diff -r 000000000000 -r ff3b6d0fd310 satengine/SatServer/Commands/SendUSSDCmd/src/CSendUssdHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/satengine/SatServer/Commands/SendUSSDCmd/src/CSendUssdHandler.cpp Tue Feb 02 01:11:09 2010 +0200 @@ -0,0 +1,966 @@ +/* +* Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Handles SendUssd command +* +*/ + + +#include +#include + +#include "MSatSystemState.h" +#include "MSatApi.h" +#include "MSatUtils.h" +#include "MSatUiSession.h" +#include "SatSOpcodes.h" +#include "MSatSUiClientHandler.h" +#include "CSendUssdHandler.h" +#include "TSatExtErrorUtils.h" +#include "SatLog.h" + +const TUint8 KQuarterShift( 2 ); +const TUint8 KHighNibbleShift( 4 ); +const TUint8 KDcsCharacterSet7Bit( 0x00 ); +const TUint8 KDcsCharacterSet8Bit( 0x01 ); +const TUint8 KDcsCharacterSet16Bit( 0x02 ); +const TUint8 KDcsCharacterSet7Bit2( 0x00 ); +const TUint8 KDcsCharacterSet16Bit2( 0x01 ); +const TInt KSatMaxUSSDString( 182 ); + +// USSD DCS coding. +const TUint8 KSatDcs7Bit( 0x40 ); +const TUint8 KSatDcs8Bit( 0x44 ); +const TUint8 KSatDcsUCS2( 0x48 ); +const TUint8 KSatDcsUnknown( 0xFF ); + +// ======== MEMBER FUNCTIONS ======== + +// ----------------------------------------------------------------------------- +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CSendUssdHandler* CSendUssdHandler::NewL( MSatUtils* aUtils ) + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::NewL calling" ) + + CSendUssdHandler* self = new( ELeave ) CSendUssdHandler; + + CleanupStack::PushL( self ); + self->BaseConstructL( aUtils ); + CleanupStack::Pop( self ); + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::NewL exiting" ) + return self; + } + +// ----------------------------------------------------------------------------- +// Destructor. +// ----------------------------------------------------------------------------- +// +CSendUssdHandler::~CSendUssdHandler() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::~CSendUssdHandler calling" ) + + Cancel(); + + if ( iUssdClient ) + { + delete iUssdClient; + iUssdClient = NULL; + } + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::~CSendUssdHandler exiting" ) + } + +// ----------------------------------------------------------------------------- +// From class MSatCommand. +// Response from the client +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::ClientResponse() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::ClientResponse calling" ) + + if ( iQueryRsp.iAccepted && !iNotificationSent ) + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::ClientResponse Sending notification" ) + iNotificationSent = ETrue; + + // Register service request + TRAP_IGNORE( iUtils->RegisterServiceRequestL( + ESatSProactiveNotification, + ESatSProactiveNotificationResponse, + this ) ) + + // Send notification + iUtils->SatUiHandler().UiSession()->SendCommand( + &iNotificationDataPckg, + &iNotificationRspPckg, + ESatSProactiveNotification ); + } + + // Notification sent + else if ( iNotificationRsp.iAccepted && iNotificationSent ) + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::ClientResponse Notification response" ) + } + + // User reject + else + { + iUserAccepted = EFalse; + iSendUssdRsp.iInfoType = RSat::KMeProblem; + iSendUssdRsp.iAdditionalInfo.SetLength( 1 ); + iSendUssdRsp.iAdditionalInfo[0] = RSat::KScreenBusy; + // Cannot return KPCmdNotAcceptedByUser (ETSI 11.14 v8.3.0 p65) + iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd; + + if ( iQueryRsp.iSessionTerminatedByUser ) + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::ClientResponse \ + ESessionTerminatedByUser" ) + // Notify sim session end command that next sim session end + // should close the ui session. + iUtils->NotifyEvent( MSatUtils::ESessionTerminatedByUser ); + } + + SendTerminalResponse(); + } + + // Release the wait + if ( iWait.IsStarted() ) + { + LOG( NORMAL, "SENDUSSD: CSendUssdHandler::ClientResponse stop iWait" ) + iWait.AsyncStop(); + } + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::ClientResponse exiting" ) + } + +// ----------------------------------------------------------------------------- +// From class CSatCommandHandler. +// Waits for indication of user rejection +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::Event( TInt aEvent ) + { + LOG2( SIMPLE, + "SENDUSSD: CSendUssdHandler::Event calling, aEvent:%d", aEvent ) + + switch ( aEvent ) + { + case MSatUtils::ECancelledUsingEndKey: + { + // Notify sim session end command that next sim session end + // should close the ui session. + iUtils->NotifyEvent( MSatUtils::ESessionTerminatedByUser ); + // This event is handled as above, but notification must be done. + } + //lint -fallthrough intended here + case MSatUtils::ECommandCancelled: + { + // Cancel Ussd sending + if ( iUssdClient ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::Event iUssdClient true" ) + iUssdClient->SendSatMessageCancel(); + iSendUssdRsp.iGeneralResult = + RSat::KUssdTransactionTerminatedByUser; + iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo; + iSendUssdRsp.iAdditionalInfo.Zero(); + SendTerminalResponse(); + } + break; + } + + default: + { + // Move event to base class + CSatCommandHandler::Event( aEvent ); + } + } + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::Event exiting" ) + } + +// ----------------------------------------------------------------------------- +// From class CActive. +// Cancels the sat request. +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::DoCancel() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DoCancel calling" ) + + iUtils->USatAPI().NotifySendUssdCancel(); + + if ( iUssdClient ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::DoCancel iUssdClient true" ) + delete iUssdClient; + iUssdClient = NULL; + } + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DoCancel exiting" ) + } + +// ----------------------------------------------------------------------------- +// From class CSatCommandHandler. +// Requests the command notification. +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::IssueUSATRequest( TRequestStatus& aStatus ) + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::IssueUSATRequest calling" ) + + // Clear the IPC package. + new (&iSendUssdData) RSat::TSendUssdV1(); + iNeedUiSession = ETrue; + iQueryRsp.iAccepted = EFalse; // default + iNotificationRsp.iAccepted = EFalse; + iSendUssdRsp.iGeneralResult = RSat::KPSessionTerminatedByUser; // default + + iUtils->USatAPI().NotifySendUssd( aStatus, iSendUssdPckg ); + + // Unregister from events + iUtils->UnregisterEvent( this, MSatUtils::ECommandCancelled ); + iUtils->UnregisterEvent( this, MSatUtils::ECancelledUsingEndKey ); + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::IssueUSATRequest exiting" ) + } + +// ----------------------------------------------------------------------------- +// From class CSatCommandHandler. +// Precheck before executing the command. +// ----------------------------------------------------------------------------- +// +TBool CSendUssdHandler::CommandAllowed() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::CommandAllowed calling" ) + + // Allow next terminal response to be sent + iTerminalRespSent = EFalse; + + RMobilePhone::TMobilePhoneRegistrationStatus registrationStatus( + iUtils->SystemState().GetNetworkRegistrationStatus() ); + + TBool commandAllowed( ETrue ); + + // If icon data without alpha id + if ( ( RSat::EAlphaIdProvided != iSendUssdData.iAlphaId.iStatus ) && + ( ( RSat::ESelfExplanatory == iSendUssdData.iIconId.iQualifier ) || + ( RSat::ENotSelfExplanatory == iSendUssdData.iIconId.iQualifier ) ) ) + { + commandAllowed = EFalse; + iSendUssdRsp.iGeneralResult = RSat::KCmdDataNotUnderstood; + iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo; + iSendUssdRsp.iAdditionalInfo.Zero(); + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::CommandAllowed Icon without alphaid \ + not allowed" ) + } + else if ( + ( RMobilePhone::ERegisteredOnHomeNetwork != registrationStatus ) && + ( RMobilePhone::ERegisteredRoaming != registrationStatus ) ) + { + commandAllowed = EFalse; + iSendUssdRsp.iInfoType = RSat::KMeProblem; + iSendUssdRsp.iAdditionalInfo.SetLength( 1 ); + iSendUssdRsp.iAdditionalInfo[0] = RSat::KNoService; + iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd; + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::CommandAllowed Not registered in legal \ + network" ) + } + // OK + else + { + // Check Ussd string validity + TInt dataLength( iSendUssdData.iUssdString.iUssdString.Length() ); + LOG2( SIMPLE, + "SENDUSSD: CSendUssdHandler::CommandAllowed Length of string: %d", + dataLength ) + + // Validate USSD string length. + TBool dataValid( + ( dataLength > 0 ) && ( dataLength <= KSatMaxUSSDString ) ); + + if ( dataValid ) + { + LOG( SIMPLE, "SENDUSSD: dataValid true" ) + // Validate Data Coding Scheme. + dataValid = DcsValid( iSendUssdData.iUssdString.iDcs ); + if ( !dataValid ) + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::CommandAllowed Dcs \ + not acceptable" ) + } + } + + // Second check in case DcsValid() returns EFalse + if ( !dataValid ) + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::CommandAllowed \ + dataValid false" ) + commandAllowed = EFalse; + iSendUssdRsp.iGeneralResult = RSat::KCmdDataNotUnderstood; + iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo; + iSendUssdRsp.iAdditionalInfo.Zero(); + } + } + + // Check is command allowd + if ( !commandAllowed ) + { + LOG( SIMPLE, "SENDUSSD: \ + CSendUssdHandler::CommandAllowed exiting - not allowed" ) + SendTerminalResponse(); + } + // Set icon command flag whether icon data was received and set qualifier + // to no icon id + // To be removed when icons are allowed in this command + else if ( ( RSat::ESelfExplanatory == + iSendUssdData.iIconId.iQualifier ) || + ( RSat::ENotSelfExplanatory == + iSendUssdData.iIconId.iQualifier ) ) + { + LOG( SIMPLE, "SENDUSSD: \ + CSendUssdHandler::CommandAllowed ENoIconId" ) + iIconCommand = ETrue; + iSendUssdData.iIconId.iQualifier = RSat::ENoIconId; + } + else + { + iIconCommand = EFalse; + } + + LOG2( SIMPLE, "SENDUSSD: CSendUssdHandler::CommandAllowed exiting,\ + commandAllowed: %d", commandAllowed ) + return commandAllowed; + } + +// ----------------------------------------------------------------------------- +// From class CSatCommandHandler. +// Answers for need of UI session. +// ----------------------------------------------------------------------------- +// +TBool CSendUssdHandler::NeedUiSession() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::NeedUiSession calling" ) + + iNeedUiSession = !TransparentUssdSending(); + + // Notify Cover UI if it's supported + if ( iNeedUiSession && iUtils->CoverUiSupported() ) + { + TSatCommandData medEventData; + medEventData.iPCmdNumber = RSat::ESendUssd; + medEventData.iAlphaId = iSendUssdData.iAlphaId; + if ( iUtils->SystemState().IsConfirmSatOperationsOn() ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::NeedUiSession KSatLongDuration" ) + medEventData.iDuration.iNumOfUnits = KSatLongDuration; + } + else + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::NeedUiSession KSatDefaultDuration" ) + medEventData.iDuration.iNumOfUnits = KSatDefaultDuration; + } + medEventData.iDuration.iTimeUnit = RSat::ESeconds; + medEventData.iIconID = iSendUssdData.iIconId; + TSatCommandPckg tPckg( medEventData ); + iUtils->RaiseSatEvent( tPckg ); + } + + LOG2( SIMPLE, + "SENDUSSD: CSendUssdHandler::NeedUiSession exiting,iNeedUiSession:%d", + iNeedUiSession ) + return iNeedUiSession; + } + +// ----------------------------------------------------------------------------- +// From class CSatCommandHandler. +// Called when USAT API notifies that command. +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::HandleCommand() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::HandleCommand calling" ) + + iUtils->NotifyEvent( MSatUtils::ESendUssdExecuting ); + + // This is ETrue, until user rejects + iUserAccepted = ETrue; + + if ( iNeedUiSession ) + { + + TRAP_IGNORE( + // Register to listen user cancel events: + // Cancel key event from dialog + iUtils->RegisterL( this, MSatUtils::ECommandCancelled ); + // End key from dialog + iUtils->RegisterL( this, MSatUtils::ECancelledUsingEndKey ) ) + + // Build Qyery and Notify packages + TSatAlphaIdStatus alphaIdStatus; + if ( RSat::EAlphaIdNotPresent == iSendUssdData.iAlphaId.iStatus ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleCommand EAlphaIdNotPresent" ) + alphaIdStatus = ESatAlphaIdNotProvided; + } + + else if ( RSat::EAlphaIdProvided == iSendUssdData.iAlphaId.iStatus ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleCommand EAlphaIdProvided" ) + alphaIdStatus = ESatAlphaIdNotNull; + } + + else + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleCommand others" ) + alphaIdStatus = ESatAlphaIdNull; + } + + // Has to be casted to TInt before casting to TSatIconQualifier, because + // GCC warns about the direct cast. + const struct TSatIconId iconId = { iSendUssdData.iIconId.iIdentifier, + static_cast( + static_cast( iSendUssdData.iIconId.iQualifier ) ) }; + + iQueryData.iCommand = ESatSSendUssdQuery; + iQueryData.iQueryText = iSendUssdData.iAlphaId.iAlphaId; + iQueryData.iIconId = iconId; + iQueryData.iAlphaIdStatus = alphaIdStatus; + + iNotificationSent = EFalse; + iNotificationData.iCommand = ESatSSendUssdNotify; + iNotificationData.iText = iSendUssdData.iAlphaId.iAlphaId; + iNotificationData.iIconId = iconId; + iNotificationData.iAlphaIdStatus = alphaIdStatus; + + MSatUiSession* uiSession = iUtils->SatUiHandler().UiSession(); + + // Send either query or notification + if ( iQueryOn ) + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::HandleCommand Sending Query" ) + iNotificationSent = EFalse; + + // Register service request + TRAP_IGNORE( iUtils->RegisterServiceRequestL( + ESatSProactiveQuery, + ESatSProactiveQueryResponse, + this ) ) + + // Send query + uiSession->SendCommand( + &iQueryPckg, + &iQueryRspPckg, + ESatSProactiveQuery ); + } + else + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::HandleCommand Sending notification" ) + + iNotificationSent = ETrue; + + // Register service request + TRAP_IGNORE( iUtils->RegisterServiceRequestL( + ESatSProactiveNotification, + ESatSProactiveNotificationResponse, + this ) ) + + // Send notification + uiSession->SendCommand( + &iNotificationDataPckg, + &iNotificationRspPckg, + ESatSProactiveNotification ); + } + + if ( !iWait.IsStarted() ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleCommand start iWait" ) + // Notification / query sent to UI, wait for response + iWait.Start(); + } + } + + if ( iUserAccepted ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleCommand UserAccepted" ) + // No need to wait response, send Ussd string + SendUssdString(); + } + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::HandleCommand exiting" ) + } + +// ----------------------------------------------------------------------------- +// From class CSatCommandHandler. +// Indicates the failure of launching ui client +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::UiLaunchFailed() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::UiLaunchFailed calling" ) + + iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd; + iSendUssdRsp.iInfoType = RSat::KMeProblem; + iSendUssdRsp.iAdditionalInfo.SetLength( 1 ); + iSendUssdRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem; + SendTerminalResponse(); + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::UiLaunchFailed exiting" ) + } + +// ----------------------------------------------------------------------------- +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +//lint -e{1403, 1769} Can not be initialized. +CSendUssdHandler::CSendUssdHandler() : + CSatCommandHandler(), + iSendUssdData(), + iSendUssdPckg( iSendUssdData ), + iSendUssdRsp(), + iSendUssdRspPckg( iSendUssdRsp ), + iQueryData(), + iQueryPckg( iQueryData ), + iQueryRsp(), + iQueryRspPckg( iQueryRsp ), + iNotificationData(), + iNotificationDataPckg( iNotificationData ), + iNotificationRsp(), + iNotificationRspPckg( iNotificationRsp ), + // To be removed when icons are allowed in this command + iIconCommand( EFalse ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::CSendUssdHandler calling - exiting" ) + } + + +// ----------------------------------------------------------------------------- +// Handles the Ussd string sending +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::SendUssdString() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendUssdString calling" ) + + TBool sendCompletedFirst( EFalse ); // This is always false + + TBuf sendMessage; + sendMessage.Copy( iSendUssdData.iUssdString.iUssdString ); + + TBuf receiveMessage; + + TRAPD( error, SendUssdStringL( + sendMessage, + iSendUssdData.iUssdString.iDcs, + receiveMessage, + sendCompletedFirst, + iSendUssdRsp.iUssdString.iDcs ) ); + + iSendUssdRsp.iUssdString.iUssdString.Copy( receiveMessage ); + + HandleSendUssdResult( error ); + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendUssdString exiting" ) + } + +// ----------------------------------------------------------------------------- +// Handles the Ussd string sending. +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::SendUssdStringL( + const TDesC& aSendMessage, + const TUint8 aSendDcs, + TDes& aReceiveMessage, + TBool& aSendCompletedFirst, + TUint8& aReceivedDcs ) + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendUssdStringL calling" ) + TInt error( KErrNone ); + + if ( iUssdClient ) + { + delete iUssdClient; + iUssdClient = NULL; + } + + // This needs to be EFalse, because otherwise KERN-EXEC:3 and SAT Server + // crashes. + iUssdClient = CPhCltUssdSatClient::NewL( EFalse ); + + LOG2( NORMAL, + "SENDUSSD: CSendUssdHandler::SendUssdStringL aSendDcs: %x", + aSendDcs ) + LOG2( NORMAL, + "SENDUSSD: CSendUssdHandler::SendUssdStringL Send length: %d", + aSendMessage.Length() ) + + #ifdef ENABLE_SAT_LOGGING + + const TInt count( aSendMessage.Length() ); + for ( TInt i = 0; i < count; i++ ) + { + LOG2( NORMAL, + "SENDUSSD: CSendUssdHandler::SendUssdStringL : 0x%X", + (char)aSendMessage[i] ) + } + + #endif + + error = iUssdClient->SendSatMessage( + aSendMessage, + aSendDcs, + aReceiveMessage, + aSendCompletedFirst, + aReceivedDcs ); + + LOG2( NORMAL, + "SENDUSSD: CSendUssdHandler::SendUssdStringL error: %d", error ) + LOG2( NORMAL, + "SENDUSSD: CSendUssdHandler::SendUssdStringL aReceivedDcs: %x", + aReceivedDcs ) + LOG2( NORMAL, + "SENDUSSD: CSendUssdHandler::SendUssdStringL Received length:%d", + aReceiveMessage.Length() ) + LOG2( NORMAL, + "SENDUSSD: CSendUssdHandler::SendUssdStringL Completed first:%i", + aSendCompletedFirst ) + + // Convert received Dcs + ConvertReceivedDcs( aReceivedDcs ); + + User::LeaveIfError( error ); + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendUssdStringL exiting" ) + } + +// ----------------------------------------------------------------------------- +// Handles the result of Ussd sending. +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::HandleSendUssdResult( TInt aError ) + { + LOG2( SIMPLE, "SENDUSSD: CSendUssdHandler::HandleSendUssdResult calling: \ + %i", aError ) + + if ( iQueryRsp.iSessionTerminatedByUser || + iNotificationRsp.iSessionTerminatedByUser || + ( KErrCancel == aError ) ) // End key + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleSendUssdResult TerminatedByUser" ) + iSendUssdRsp.iGeneralResult = RSat::KUssdTransactionTerminatedByUser; + iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo; + iSendUssdRsp.iAdditionalInfo.Zero(); + } + else if ( TSatExtErrorUtils::IsExtendedError( aError ) ) // extended error + { + TUint8 addInfo( 0 ); + // Check and map network failure + if ( TSatExtErrorUtils::IsNetworkError( aError ) ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleSendUssdResult NetworkError" ) + // Network error, map and modify + addInfo = TSatExtErrorUtils::MapError( aError ); + iSendUssdRsp.iGeneralResult = RSat::KNetworkUnableToProcessCmd; + iSendUssdRsp.iInfoType = RSat::KSatNetworkErrorInfo; + } + else + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleSendUssdResult MeProblem" ) + // Not a network error, don't modify + addInfo = TSatExtErrorUtils::MapError( aError, EFalse ); + iSendUssdRsp.iGeneralResult = RSat::KUssdReturnError; + iSendUssdRsp.iInfoType = RSat::KMeProblem; + } + // Add additional info to response + iSendUssdRsp.iAdditionalInfo.SetLength( 1 ); + iSendUssdRsp.iAdditionalInfo[0] = static_cast( addInfo ); + } + else if ( KErrInUse == aError ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleSendUssdResult KMeBusyOnUssd" ) + iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd; + iSendUssdRsp.iInfoType = RSat::KMeProblem; + iSendUssdRsp.iAdditionalInfo.SetLength( 1 ); + iSendUssdRsp.iAdditionalInfo[0] = RSat::KMeBusyOnUssd; + } + else if ( KErrGeneral == aError ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleSendUssdResult KMeBusyOnSs" ) + iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd; + iSendUssdRsp.iInfoType = RSat::KMeProblem; + iSendUssdRsp.iAdditionalInfo.SetLength( 1 ); + iSendUssdRsp.iAdditionalInfo[0] = RSat::KMeBusyOnSs; + } + else if ( KErrNotFound == aError ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleSendUssdResult \ + KNoSpecificMeProblem" ) + iSendUssdRsp.iGeneralResult = RSat::KUssdReturnError; + iSendUssdRsp.iInfoType = RSat::KMeProblem; + iSendUssdRsp.iAdditionalInfo.SetLength( 1 ); + iSendUssdRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem; + } + else if ( KErrNone == aError ) // Success case + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleSendUssdResult success" ) + // Convert terminal rsp if icon used + iSendUssdRsp.iGeneralResult = RSat::KSuccess; + + // If command had icon data and was done succesfully, + // report that icon was not shown. + // To be removed and correct handling (i.e. ClientResponse to + // notification is received) for general result + // KSuccessRequestedIconNotDisplayed must be added when icons + // are allowed in this command + if ( iIconCommand ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleSendUssdResult \ + IconNotDisplayed" ) + iSendUssdRsp.iGeneralResult = + RSat::KSuccessRequestedIconNotDisplayed; + } + + iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo; + iSendUssdRsp.iAdditionalInfo.Zero(); + } + else // unknown error + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::HandleSendUssdResult unknown error" ) + iSendUssdRsp.iGeneralResult = RSat::KUssdReturnError; + iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo; + iSendUssdRsp.iAdditionalInfo.Zero(); + } + + SendTerminalResponse(); + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::HandleSendUssdResult exiting" ) + } + + +// ----------------------------------------------------------------------------- +// Converts reveived Dcs to correct format. +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::ConvertReceivedDcs( TUint8& aReceivedDcs ) const + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs calling" ) + + switch ( aReceivedDcs ) + { + case KPhCltDcs7Bit: + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs Dcs7Bit" ) + aReceivedDcs = KSatDcs7Bit; + } + break; + + case KPhCltDcs8Bit: + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs Dcs8Bit" ) + aReceivedDcs = KSatDcs8Bit; + } + break; + + case KPhCltDcsUcs2: + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs DcsUCS2" ) + aReceivedDcs = KSatDcsUCS2; + } + break; + + case KPhCltDcsUnknown: + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs DcsUnknown" ) + aReceivedDcs = KSatDcsUnknown; + } + break; + + case KSatDcs7Bit: + case KSatDcs8Bit: + case KSatDcsUCS2: + case KSatDcsUnknown: + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs Already valid" ) + } + break; + + default: + { + LOG( NORMAL, + "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs Unknown" ) + aReceivedDcs = KSatDcsUnknown; + } + break; + } + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs exiting" ) + } + +// ----------------------------------------------------------------------------- +// Sends terminal response. Makes sure that terminal response +// is not send more that once / command. +// ----------------------------------------------------------------------------- +// +void CSendUssdHandler::SendTerminalResponse() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendTerminalResponse calling" ) + + if ( !iTerminalRespSent ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::SendTerminalResponse iTerminalRespSent \ + false" ) + iTerminalRespSent = ETrue; + iSendUssdRsp.SetPCmdNumber( iSendUssdData.PCmdNumber() ); + TerminalRsp( RSat::ESendUssd, iSendUssdRspPckg ); + } + + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendTerminalResponse exiting" ) + } + +// ----------------------------------------------------------------------------- +// Check validity of a given Data Coding Cheme (Dcs). +// ----------------------------------------------------------------------------- +// +TBool CSendUssdHandler::DcsValid( const TUint8 aDcs ) const + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DcsValid calling" ) + + TBool isDcsValid( EFalse ); + // 76543210 + TUint8 codingGroup = ( aDcs & 0xF0 ) >> KHighNibbleShift; // bits XXXX____ + TUint8 characterSet = ( aDcs & 0x0C ) >> KQuarterShift; // bits ____XX__ + TUint8 lowQuartet = ( aDcs & 0x0F ); // bits ____XXXX + LOG2( SIMPLE, + "SENDUSSD: CSendUssdHandler::DcsValid codingGroup: %x", codingGroup) + switch ( codingGroup ) + { + case 0x00: + case 0x02: + case 0x03: + case 0x0F: + { + isDcsValid = ETrue; + break; + } + + case 0x01: + { + if ( ( KDcsCharacterSet7Bit2 == lowQuartet ) || + ( KDcsCharacterSet16Bit2 == lowQuartet ) ) + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DcsValid valid" ) + isDcsValid = ETrue; + } + break; + } + + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x09: + { + if ( ( KDcsCharacterSet7Bit == characterSet ) || + ( KDcsCharacterSet8Bit == characterSet ) || + ( KDcsCharacterSet16Bit == characterSet ) ) + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DcsValid isDcsValid" ) + isDcsValid = ETrue; + } + break; + } + + default: + { + LOG2( SIMPLE, "SENDUSSD: Reserved Dcs found: %x", aDcs ) + } + } + + LOG2( + SIMPLE, + "SENDUSSD: CSendUssdHandler::DcsValid exiting, valid = %d", + isDcsValid ) + return isDcsValid; + } + +// ----------------------------------------------------------------------------- +// USSD sending should be transparent if alpha identifier is provided but it's +// length is 0. Also user query setting is not on. +// ----------------------------------------------------------------------------- +// +TBool CSendUssdHandler::TransparentUssdSending() + { + LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::TransparentUssdSending calling" ) + TBool result( EFalse ); + const RSat::TAlphaId alphaId( iSendUssdData.iAlphaId ); + + // Store to member variable for later use + iQueryOn = iUtils->SystemState().IsConfirmSatOperationsOn(); + + if ( ( alphaId.iStatus == RSat::EAlphaIdProvided && + alphaId.iAlphaId.Length() == 0 ) || + alphaId.iStatus == RSat::EAlphaIdNull ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::TransparentUssdSending AlphaId" ) + if ( !iQueryOn ) + { + LOG( SIMPLE, + "SENDUSSD: CSendUssdHandler::TransparentUssdSending iQueryOn \ + false" ) + result = ETrue; + } + } + + LOG2( SIMPLE, + "SENDUSSD: CSendUssdHandler::TransparentUssdSending exiting: %i", result ) + return result; + } +