--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/satengine/SatServer/Commands/SendSSCmd/src/CSendSsHandler.cpp Tue Feb 02 01:11:09 2010 +0200
@@ -0,0 +1,1002 @@
+/*
+* Copyright (c) 2002-2009 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 SendSS command
+*
+*/
+
+
+#include <CPhoneGsmParserBase.h>
+#include <CPhoneGsmParserResult.h>
+#include <PhoneGsmParser.h>
+#include <CPhoneGsmOptionContainerBase.h>
+
+#include "MSatSystemState.h"
+#include "MSatApi.h"
+#include "MSatUtils.h"
+#include "MSatUiSession.h"
+#include "SatSOpcodes.h"
+#include "MSatSUiClientHandler.h"
+#include "CSendSsHandler.h"
+#include "SatLog.h"
+#include "csatsendssrequestcompletehandler.h"
+#include "csatsendssadditionalinfohandler.h"
+#include "csatsendsshandler.h"
+
+// CustomAPI returns KCustomApiSsGsmActive=0x01
+const TInt KSsGsmActiveSuccess = 0x01;
+// CustomAPI returns KCustomApiSsGsmRegistered=0x02
+const TInt KSsGsmRegistered = 0x02;
+// CustomAPI returns KCustomApiSsGsmProvisioned=0x04
+const TInt KSsGsmProvisioned = 0x04;
+// CustomAPI returns KCustomApiSsGsmQuiescent=0x08
+const TInt KSsGsmQuiescent = 0x08;
+// CustomAPI returns SsServiceFailedResp=0xFFFF
+const TInt KSsServiceFailed = 0xFFFF;
+// Error code for NetworkFailure = 0xFFFE
+const TInt KSsNetworkError = 0xFFFE;
+//interval wait for ussd send
+const TInt KCallbackInterval = 1000000;
+// Interval wait for additional info
+const TInt KSSRequestCallbackInterval = 5000000;
+// Ss OperationCode value.
+const TInt KSsOperationShowFDNLIst = 0x05;
+const TInt KSsOperationPasswordRegistration = 0x06;
+// Ss error
+const TInt KSsSimAtkCcRejected = 0x0D;
+const TInt KTwo = 2;
+
+// ======== MEMBER FUNCTIONS ========
+
+// -----------------------------------------------------------------------------
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CSendSSHandler* CSendSSHandler::NewL( MSatUtils* aUtils )
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::NewL calling" )
+
+ CSendSSHandler* self = new( ELeave ) CSendSSHandler;
+
+ CleanupStack::PushL( self );
+ self->BaseConstructL( aUtils );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::NewL exiting" )
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CSendSSHandler::~CSendSSHandler()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::~CSendSSHandler calling" )
+
+ Cancel();
+ // Destroy all objects.
+ delete iAdditionalInfoHandler;
+ delete iRequestCompleteHandler;
+ delete iPhoneGsmHandlerBase;
+ delete iParser;
+ delete iResult;
+ delete iPhoneGsmOptionContainerBase;
+ if ( iTimer )
+ {
+ iTimer->Cancel();
+ delete iTimer;
+ iTimer = NULL;
+ }
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::~CSendSSHandler exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// Processes the SS Request Complete.
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::DispatchSsRequestComplete( TInt aErrCode )
+ {
+ LOG2( SIMPLE, "SENDSS: CSendSSHandler::DispatchSsRequestComplete \
+ called aErrCode: %i", aErrCode )
+
+ if ( ( KSsGsmActiveSuccess == aErrCode ) ||
+ ( KSsGsmRegistered == aErrCode ) ||
+ ( KSsGsmProvisioned == aErrCode ) ||
+ ( KSsGsmQuiescent == aErrCode ) )
+ {
+ iSsResult = KErrNone;
+ }
+ else
+ {
+ iSsResult = aErrCode;
+ }
+
+ // Store result for later use
+ iSsResult = aErrCode;
+ iRequestCompleteArrived = ETrue;
+
+ //is additional info received
+ if ( iAdditionalInfoArrived )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::DispatchSsRequestComplete \
+ iAdditionalInfoArrived true" )
+ HandleSendSsResult();
+ }
+ else //if not 5 second timer to get additional info
+ {
+ if ( !iTimer )
+ {
+ LOG( SIMPLE,
+ "CSendSSHandler::DispatchSsRequestComplete iTimer false" )
+ TRAPD( err, iTimer = CPeriodic::NewL( CActive::EPriorityStandard ); );
+
+ LOG2( NORMAL, "SENDSS: CSendSSHandler::DispatchSsRequestComplete \
+ CPeriodic::NewL err: %d ", err )
+ if ( KErrNone == err )
+ {
+ iTimer->Start( KSSRequestCallbackInterval,
+ KCallbackInterval, TCallBack( SSRequestCallback, this ) );
+ }
+ }
+ }
+
+ LOG( SIMPLE, "CSendSSHandler::DispatchSsRequestComplete exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// Processes the SS aditional info.
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::DispatchSsAdditionalInfo(
+ const TDesC& aAdditionalInfo )
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::DispatchSsAdditionalInfo called" )
+
+ iAdditionalInfoArrived = ETrue;
+ iAdditionalInfo.Copy( aAdditionalInfo );
+ LOG2( SIMPLE, "SENDSS: CSendSSHandler::DispatchSsAdditionalInfo length of\
+ aAdditionalInfo: %i", aAdditionalInfo.Length())
+
+ if ( aAdditionalInfo.Length() > 0 )
+ {
+ // This is special case due tsy will not send request complete.
+ if ( ( ( KSsOperationPasswordRegistration == aAdditionalInfo[0] ) ||
+ ( KSsOperationShowFDNLIst == aAdditionalInfo[0] ) ) &&
+ ( !iRequestCompleteArrived ) )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::DispatchSsAdditionalInfo special case" )
+ iSsResult = KErrNone;
+ iRequestCompleteArrived = ETrue;
+ }
+ }
+
+ //is requestcompletenotification reveived
+ if ( iRequestCompleteArrived )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::DispatchSsAdditionalInfo \
+ iRequestCompleteArrived true" )
+ HandleSendSsResult();
+ }
+ else //if not 5 second timer to get requestcompletenote
+ {
+ if ( !iTimer )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::DispatchSsAdditionalInfo iTimer false" )
+ TRAPD( err, iTimer = CPeriodic::NewL( CActive::EPriorityStandard ); );
+
+ LOG2( NORMAL, "SENDSS: CSendSSHandler::DispatchSsAdditionalInfo \
+ CPeriodic::NewL err: %d ", err )
+ if ( KErrNone == err )
+ {
+ iTimer->Start( KSSRequestCallbackInterval,
+ KCallbackInterval, TCallBack( SSRequestCallback, this ) );
+ }
+ }
+ }
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::DispatchSsAdditionalInfo exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// From class MSatCommand.
+// Response from the client.
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::ClientResponse()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::ClientResponse calling" )
+
+ if ( iQueryRsp.iAccepted && !iNotificationSent )
+ {
+ LOG( NORMAL,
+ "SENDSS: CSendSSHandler::ClientResponse Sending notification" )
+ iNotificationSent = ETrue;
+
+ // Register service request
+ TRAP_IGNORE( iUtils->RegisterServiceRequestL(
+ ESatSProactiveNotification,
+ ESatSProactiveNotificationResponse,
+ this ) )
+
+ // Send notification
+ iUtils->SatUiHandler().UiSession()->SendCommand(
+ &iNotificationDataPckg,
+ &iNotificationRspPckg,
+ ESatSProactiveNotification );
+ }
+ else if ( iNotificationRsp.iAccepted && iNotificationSent )
+ {
+ LOG( NORMAL,
+ "SENDSS: CSendSSHandler::ClientResponse Notification response" )
+ }
+ else // User reject
+ {
+ iUserAccepted = EFalse;
+ // Cannot return KPCmdNotAcceptedByUser (ETSI 11.14 v8.3.0 p65)
+ iSendSsRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
+ iSendSsRsp.iInfoType = RSat::KMeProblem;
+ iSendSsRsp.iAdditionalInfo.SetLength( 1 );
+ iSendSsRsp.iAdditionalInfo[0] = RSat::KScreenBusy;
+
+ if ( iQueryRsp.iSessionTerminatedByUser )
+ {
+ LOG( NORMAL, "SENDSS: CSendSSHandler::ClientResponse \
+ ESessionTerminatedByUser" )
+ // Notify sim session end command that next sim session end
+ // should close the ui session.
+ iUtils->NotifyEvent( MSatUtils::ESessionTerminatedByUser );
+ }
+
+ SendTerminalResponse();
+ }
+
+ // Release Wait
+ if ( iSendWait.IsStarted() )
+ {
+ LOG( NORMAL, "SENDSS: CSendSSHandler::ClientResponse stop iSendWait" )
+ iSendWait.AsyncStop();
+ }
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::ClientResponse exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// From class CSatCommandHandler.
+// Waits for indication of user rejection
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::Event( TInt aEvent )
+ {
+ LOG2( SIMPLE, "SENDSS: CSendSSHandler::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:
+ {
+ // Check is there a confirmation on screen
+ if ( !iQueryOn || iNotificationSent )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::Event iNotificationSent true" )
+ // Cancel notification requests
+ iRequestCompleteHandler->Cancel();
+ iAdditionalInfoHandler->Cancel();
+
+ iSendSsRsp.iGeneralResult = RSat::KUssdTransactionTerminatedByUser;
+ iSendSsRsp.iInfoType = RSat::KNoAdditionalInfo;
+ iSendSsRsp.iAdditionalInfo.Zero();
+ SendTerminalResponse();
+ }
+ break;
+ }
+
+ default:
+ {
+ // Move event to base class
+ CSatCommandHandler::Event( aEvent );
+ }
+ }
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::Event exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// From class CActive.
+// Cancels the sat request.
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::DoCancel()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::DoCancel calling" )
+
+ iUtils->USatAPI().NotifySendSsCancel();
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::DoCancel exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// From class CSatCommandHandler.
+// Requests the command notification.
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::IssueUSATRequest( TRequestStatus& aStatus )
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::IssueUSATRequest calling" )
+
+ // Clear the IPC package.
+ new (&iSendSsData) RSat::TSendSsV1();
+ iQueryOn = EFalse;
+ iQueryRsp.iAccepted = EFalse; // default
+ iNotificationRsp.iAccepted = EFalse;
+ iSendSsRsp.iGeneralResult = RSat::KPSessionTerminatedByUser; // default
+ iSendSsRsp.iInfoType = RSat::KNoAdditionalInfo;
+ iSendSsRsp.iAdditionalInfo.Zero();
+
+ iUtils->USatAPI().NotifySendSs( aStatus, iSendSsPckg );
+
+ // Unregister from events
+ iUtils->UnregisterEvent( this, MSatUtils::ECommandCancelled );
+ iUtils->UnregisterEvent( this, MSatUtils::ECancelledUsingEndKey );
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::IssueUSATRequest exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// From class CSatCommandHandler.
+// Precheck before executing the command.
+// -----------------------------------------------------------------------------
+//
+TBool CSendSSHandler::CommandAllowed()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::CommandAllowed calling" )
+
+ // Allow this command to send terminal response
+ iTerminalRespSent = EFalse;
+ RMobilePhone::TMobilePhoneRegistrationStatus registrationStatus(
+ iUtils->SystemState().GetNetworkRegistrationStatus() );
+
+ TBool commandAllowed( ETrue );
+
+ // icon without alpha id
+ if ( ( RSat::EAlphaIdProvided != iSendSsData.iAlphaId.iStatus ) &&
+ ( RSat::ESelfExplanatory == iSendSsData.iIconId.iQualifier ||
+ RSat::ENotSelfExplanatory == iSendSsData.iIconId.iQualifier ) )
+ {
+ iSendSsRsp.iGeneralResult = RSat::KCmdDataNotUnderstood;
+ iSendSsRsp.iInfoType = RSat::KNoAdditionalInfo;
+ iSendSsRsp.iAdditionalInfo.Zero();
+ commandAllowed = EFalse;
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::CommandAllowed icon without alpha id" )
+ }
+ else if ( ( RMobilePhone::ERegisteredOnHomeNetwork != registrationStatus ) &&
+ ( RMobilePhone::ERegisteredRoaming != registrationStatus ) )
+ {
+ iSendSsRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
+ iSendSsRsp.iInfoType = RSat::KMeProblem;
+ iSendSsRsp.iAdditionalInfo.SetLength( 1 );
+ iSendSsRsp.iAdditionalInfo[0] = RSat::KNoService;
+ commandAllowed = EFalse;
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::CommandAllowed no service" )
+ }
+ // 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 ==
+ iSendSsData.iIconId.iQualifier ) ||
+ ( RSat::ENotSelfExplanatory ==
+ iSendSsData.iIconId.iQualifier ) )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::CommandAllowed ENoIconId" )
+ iIconCommand = ETrue;
+ iSendSsData.iIconId.iQualifier = RSat::ENoIconId;
+ }
+ else
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::CommandAllowed others" )
+ iIconCommand = EFalse;
+ }
+
+ if ( !commandAllowed )
+ {
+ SendTerminalResponse();
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::CommandAllowed not allowed" )
+ }
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::CommandAllowed exiting" )
+ return commandAllowed;
+ }
+
+// -----------------------------------------------------------------------------
+// From class CSatCommandHandler.
+// Answers for need of UI session.
+// -----------------------------------------------------------------------------
+//
+TBool CSendSSHandler::NeedUiSession()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::NeedUiSession calling" )
+
+ iNeedUiSession = !TransparentSsSending();
+
+ // Notify Cover UI if it's supported
+ if ( iNeedUiSession && iUtils->CoverUiSupported() )
+ {
+ TSatCommandData medEventData;
+ medEventData.iPCmdNumber = RSat::ESendSs;
+ medEventData.iAlphaId = iSendSsData.iAlphaId;
+ if ( iUtils->SystemState().IsConfirmSatOperationsOn() )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::NeedUiSession KSatLongDuration" )
+ medEventData.iDuration.iNumOfUnits = KSatLongDuration;
+ }
+ else
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::NeedUiSession KSatDefaultDuration" )
+ medEventData.iDuration.iNumOfUnits = KSatDefaultDuration;
+ }
+ medEventData.iDuration.iTimeUnit = RSat::ESeconds;
+ medEventData.iIconID = iSendSsData.iIconId;
+ TSatCommandPckg tPckg( medEventData );
+ iUtils->RaiseSatEvent( tPckg );
+ }
+
+ LOG2( SIMPLE, "SENDSS: CSendSSHandler::NeedUiSession exiting,\
+ iNeedUiSession: %d", iNeedUiSession )
+ return iNeedUiSession;
+ }
+
+// -----------------------------------------------------------------------------
+// From class CSatCommandHandler.
+// Called when USAT API notifies that command.
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::HandleCommand()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::HandleCommand calling" )
+
+ iUtils->NotifyEvent( MSatUtils::ESendSsExecuting );
+
+ // This is true, by default
+ iUserAccepted = ETrue;
+
+ if ( iNeedUiSession )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleCommand iNeedUiSession true" )
+ 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
+ // Has to be casted to TInt before casting to TSatIconQualifier, because
+ // GCC warns about the direct cast.
+ const struct TSatIconId iconId = { iSendSsData.iIconId.iIdentifier,
+ static_cast<TSatIconQualifier>(
+ static_cast<TInt>( iSendSsData.iIconId.iQualifier ) ) };
+
+ if ( RSat::EAlphaIdNotPresent == iSendSsData.iAlphaId.iStatus )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleCommand EAlphaIdNotPresent" )
+ iQueryData.iAlphaIdStatus = ESatAlphaIdNotProvided;
+ iNotificationData.iAlphaIdStatus = ESatAlphaIdNotProvided;
+ }
+ else if ( RSat::EAlphaIdProvided == iSendSsData.iAlphaId.iStatus )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleCommand EAlphaIdProvided" )
+ iQueryData.iAlphaIdStatus = ESatAlphaIdNotNull;
+ iNotificationData.iAlphaIdStatus = ESatAlphaIdNotNull;
+ }
+ else
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleCommand ESatAlphaIdNull" )
+ iQueryData.iAlphaIdStatus = ESatAlphaIdNull;
+ iNotificationData.iAlphaIdStatus = ESatAlphaIdNull;
+ }
+
+ iQueryData.iCommand = ESatSSendSsQuery;
+ iQueryData.iQueryText = iSendSsData.iAlphaId.iAlphaId;
+ iQueryData.iIconId = iconId;
+
+ iNotificationSent = EFalse;
+ iNotificationData.iCommand = ESatSSendSsNotify;
+ iNotificationData.iText = iSendSsData.iAlphaId.iAlphaId;
+ iNotificationData.iIconId = iconId;
+
+ MSatUiSession* uiSession = iUtils->SatUiHandler().UiSession();
+
+ // Send either query or notification
+ if ( iQueryOn )
+ {
+ LOG( NORMAL,
+ "SENDSS: CSendSSHandler::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,
+ "SENDSS: CSendSSHandler::HandleCommand Sending notification" )
+ iNotificationSent = ETrue;
+
+ // Register service request
+ TRAP_IGNORE( iUtils->RegisterServiceRequestL(
+ ESatSProactiveNotification,
+ ESatSProactiveNotificationResponse,
+ this ) )
+
+ // Send notification
+ uiSession->SendCommand(
+ &iNotificationDataPckg,
+ &iNotificationRspPckg,
+ ESatSProactiveNotification );
+ }
+
+ if ( !iSendWait.IsStarted() )
+ {
+ LOG( NORMAL,
+ "SENDSS: CSendSSHandler::HandleCommand start iSendWait" )
+ // Start waiting response from the user
+ iSendWait.Start();
+ }
+ }
+
+ if ( iUserAccepted )
+ {
+ LOG( NORMAL,
+ "SENDSS: CSendSSHandler::HandleCommand iUserAccepted true" )
+ // Ready to send Ss string
+ TRAPD( err, SendSsStringL() )
+ if ( KErrNone != err )
+ {
+ LOG2( NORMAL, " Ss sending failed: %i", err )
+ iSendSsRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
+ iSendSsRsp.iInfoType = RSat::KMeProblem;
+ iSendSsRsp.iAdditionalInfo.SetLength( 1 );
+ iSendSsRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem;
+ SendTerminalResponse();
+ }
+ }
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::HandleCommand exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// From class CSatCommandHandler.
+// Indicates the failure of launching ui client
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::UiLaunchFailed()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::UiLaunchFailed calling" )
+
+ iSendSsRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
+ iSendSsRsp.iInfoType = RSat::KMeProblem;
+ iSendSsRsp.iAdditionalInfo.SetLength( 1 );
+ iSendSsRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem;
+ SendTerminalResponse();
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::UiLaunchFailed exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+//lint -e{1403, 1769} Can not be initialized.
+CSendSSHandler::CSendSSHandler() :
+ CSatCommandHandler(),
+ iSendSsData(),
+ iSendSsPckg( iSendSsData ),
+ iSendSsRsp(),
+ iSendSsRspPckg( iSendSsRsp ),
+ 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, "SENDSS: CSendSSHandler::CSendSSHandler calling - exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::ConstructL()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::ConstructL calling" )
+
+ // Create additional info and request complete handlers
+ iAdditionalInfoHandler = CSatSendSsAdditionalInfoHandler::NewL(
+ *iUtils->CustomApi(), this );
+ iRequestCompleteHandler = CSatSendSsRequestCompleteHandler::NewL(
+ *iUtils->CustomApi(), this );
+ iPhoneGsmHandlerBase = new ( ELeave ) CSatSendSsHandler();
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::ConstructL exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// Handles the Ss string sending.
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::SendSsStringL()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::SendSsString calling" )
+
+ // Set default values
+ iSsResult = KErrArgument;
+ iRequestCompleteArrived = EFalse;
+ iAdditionalInfoArrived = EFalse;
+
+ //Parsing and interpreting
+ TBuf<RSat::KStringMaxSize> sendMessage;
+ sendMessage.Copy( iSendSsData.iSsString.iSsString );
+
+ // CPhoneGsmOptionContainerBase cannot be deleted before SendSsString
+ // complete, so the object is designed as a member in order that it can be
+ // deleted asychronously.
+ iParser = PhoneGsmParser::CreateParserL();
+ iResult = PhoneGsmParser::CreateResultL();
+ iPhoneGsmOptionContainerBase = PhoneGsmParser::CreateOptionContainerL();
+
+ //Update options
+ iPhoneGsmOptionContainerBase->SetOptionStatus( KPhoneOptionSend, ETrue );
+
+ //Parsing and interpreting
+
+ //Parse string
+ if ( iParser->ParseL( sendMessage, *iResult, *iPhoneGsmOptionContainerBase ) )
+ {
+ if ( PhoneGsmParser::DetermineContentType( *iResult ) ==
+ PhoneGsmParser::EContentSupplementaryService )
+ {
+
+ if ( !iRequestCompleteHandler->IsActive() )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::SendSsString start \
+ iRequestCompleteHandler" )
+ iRequestCompleteHandler->Start();
+ }
+
+ if ( !iAdditionalInfoHandler->IsActive() )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::SendSsString start \
+ iAdditionalInfoHandler" )
+ iAdditionalInfoHandler->Start();
+ }
+
+ // Make a Default Additional Info here, in case additional
+ // info field won't be received
+ // the field is a dummy
+ iAdditionalInfo.SetLength( 1 );
+ iAdditionalInfo[0] = 0x00;
+
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::SendSsString Processing Ss" )
+
+ // CPhoneGsmHandlerBase lives in all lifetime of
+ // CSendSSHandler. So, it designed as a member.
+ iPhoneGsmHandlerBase->ProcessL( *iResult );
+ }
+ else
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::SendSsString KCmdDataNotUnderstood" )
+ iSendSsRsp.iGeneralResult = RSat::KCmdDataNotUnderstood;
+ iSendSsRsp.iInfoType = RSat::KNoAdditionalInfo;
+ iSendSsRsp.iAdditionalInfo.Zero();
+
+ // Send terminal response
+ SendTerminalResponse();
+ }
+ }
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::SendSsString exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// Handles the result of Ss sending.
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::HandleSendSsResult()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::HandleSendSsResult calling" )
+ LOG2( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleSendSsResult iSsResult: %i", iSsResult )
+ // Remove progress bar from the screen
+ if ( KSsServiceFailed == iSsResult || KSsNetworkError == iSsResult )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleSendSsResult Clearing Progress bar.." )
+ iUtils->NotifyUiEvent( ESatSsEndEvent, ESatEventFailure, iSsResult );
+ // Send Error notification, but only if Alpha ID was provided
+ if ( ESatAlphaIdNotNull == iNotificationData.iAlphaIdStatus )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleSendSsResult Sending Ss note: \
+ Not Done" )
+ iUtils->NotifyUiEvent( ESatSsErrorEvent, ESatEventFailure,
+ iSsResult );
+ }
+ }
+ else if ( iNotificationSent )
+ {
+ // Remove the UI dialog
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleSendSsResult iNotificationSent true" )
+ iUtils->NotifyUiEvent( ESatSsEndEvent, ESatEventCompleteOk, iSsResult );
+ }
+
+ switch ( iSsResult )
+ {
+ case KErrGeneral: // Command not processed
+ {
+ iSendSsRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
+ iSendSsRsp.iInfoType = RSat::KMeProblem;
+ iSendSsRsp.iAdditionalInfo.SetLength( 1 );
+ iSendSsRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem;
+ break;
+ }
+
+ case KErrArgument:
+ {
+ iSendSsRsp.iGeneralResult = RSat::KCmdDataNotUnderstood;
+ iSendSsRsp.iInfoType = RSat::KNoAdditionalInfo;
+ iSendSsRsp.iAdditionalInfo.Zero();
+ break;
+ }
+
+ case KSsServiceFailed:
+ {
+ //This is a special case, TSY sends error value in additional info
+ //when SS is rejected by Call control
+ if ( KTwo <= iAdditionalInfo.Length() &&
+ KSsSimAtkCcRejected == iAdditionalInfo[1] )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleSendSsResult \
+ KInteractionWithCCPermanentError" )
+ iSendSsRsp.iGeneralResult =
+ RSat::KInteractionWithCCPermanentError;
+ iSendSsRsp.iAdditionalInfo.SetLength( 1 );
+ iSendSsRsp.iAdditionalInfo[0] = RSat::KActionNotAllowed;
+ }
+ else
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleSendSsResult KSsReturnError" )
+ iSendSsRsp.iGeneralResult = RSat::KSsReturnError;
+ iSendSsRsp.iAdditionalInfo.Copy( iAdditionalInfo );
+ }
+ iSendSsRsp.iInfoType = RSat::KMeProblem;
+ break;
+ }
+
+ case KSsNetworkError:
+ {
+ iSendSsRsp.iGeneralResult = RSat::KNetworkUnableToProcessCmd;
+ iSendSsRsp.iInfoType = RSat::KSatNetworkErrorInfo;
+ iSendSsRsp.iAdditionalInfo.SetLength( 1 );
+ if ( iAdditionalInfo.Length() > 1 )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleSendSsResult \
+ iAdditionalInfo.Length() > 1" )
+ iSendSsRsp.iAdditionalInfo[0] = \
+ ( iAdditionalInfo[1] == RSat::KNoSpecificMeProblem ) \
+ ? iAdditionalInfo[1] : ( iAdditionalInfo[1] | 0x80 );
+ }
+ else
+ {
+ iSendSsRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem;
+ }
+ break;
+ }
+
+ default:
+ {
+ // Convert terminal rsp if icon used
+ iSendSsRsp.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,
+ "SENDSS: CSendSSHandler::HandleSendSsResult iIconCommand \
+ true" )
+ iSendSsRsp.iGeneralResult =
+ RSat::KSuccessRequestedIconNotDisplayed;
+ }
+
+ if ( iAdditionalInfo.Length() )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::HandleSendSsResult \
+ iAdditionalInfo.Length >0" )
+ iSendSsRsp.iInfoType = RSat::KSendSsInfo;
+ iSendSsRsp.iAdditionalInfo.Copy( iAdditionalInfo );
+ }
+ else
+ {
+ iSendSsRsp.iInfoType = RSat::KNoAdditionalInfo;
+ iSendSsRsp.iAdditionalInfo.Zero();
+ }
+
+ break;
+ }
+ }
+
+ delete iResult;
+ iResult = NULL;
+
+ delete iParser;
+ iParser = NULL;
+
+ delete iPhoneGsmOptionContainerBase;
+ iPhoneGsmOptionContainerBase = NULL;
+
+ iRequestCompleteHandler->Cancel();
+ iAdditionalInfoHandler->Cancel();
+
+ // Send terminal response
+ SendTerminalResponse();
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::HandleSendSsResult exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// SS sending should be transparent if alpha identifier is provided but it's
+// length is 0. Also user query setting is not on.
+// -----------------------------------------------------------------------------
+//
+TBool CSendSSHandler::TransparentSsSending()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::TransparentSsSending calling" )
+
+ TBool result( EFalse );
+ const RSat::TAlphaId alphaId( iSendSsData.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,
+ "SENDSS: CSendSSHandler::TransparentSsSending EAlphaIdNull" )
+ if ( !iQueryOn )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::TransparentSsSending iQueryOn false" )
+ result = ETrue;
+ }
+ }
+
+ LOG2( SIMPLE, "SENDSS: CSendSSHandler::TransparentSsSending exiting: %i",
+ result )
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// Sends terminal response, if not yet sent
+// -----------------------------------------------------------------------------
+//
+void CSendSSHandler::SendTerminalResponse()
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::SendTerminalResponse calling" )
+
+ if ( !iTerminalRespSent )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::SendTerminalResponse iTerminalRespSent false" )
+ iTerminalRespSent = ETrue;
+ iSendSsRsp.SetPCmdNumber( iSendSsData.PCmdNumber() );
+ TerminalRsp( RSat::ESendSs, iSendSsRspPckg );
+ }
+
+ // Delete timer in case it is still active
+ if ( iTimer )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::SendTerminalResponse iTimer true" )
+ iTimer->Cancel();
+ delete iTimer;
+ iTimer = NULL;
+ }
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::SendTerminalResponse exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// Callback for SendSS additionalinfo waiting timer.
+// -----------------------------------------------------------------------------
+//
+TInt CSendSSHandler::SSRequestCallback( TAny* aPtr )
+ {
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::SSRequestCallback calling" )
+
+ CSendSSHandler* handler =
+ static_cast<CSendSSHandler*>( aPtr );
+
+ if ( handler )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::SSRequestCallback handler true" )
+ handler->HandleSendSsResult();
+
+ if ( handler->iTimer )
+ {
+ LOG( SIMPLE,
+ "SENDSS: CSendSSHandler::SSRequestCallback cancel iTimer" )
+ handler->iTimer->Cancel();
+ delete handler->iTimer;
+ handler->iTimer = NULL;
+ }
+ }
+
+ LOG( SIMPLE, "SENDSS: CSendSSHandler::SSRequestCallback exiting" )
+ return ( KErrNone );
+ }
+