--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/satengine/SatServer/Commands/CallControlCmd/src/CCallControlHandler.cpp Tue Feb 02 01:11:09 2010 +0200
@@ -0,0 +1,650 @@
+/*
+* Copyright (c) 2002-2008 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 CallControl command
+*
+*/
+
+
+//Include Files
+#include <utf.h>
+#include "MSatApi.h"
+#include "MSatUtils.h"
+#include "MSatUiSession.h"
+#include "MSatSUiClientHandler.h"
+#include "CCallControlHandler.h"
+#include "ccallcontrolrequesthandler.h"
+#include "msatmultimodeapi.h"
+#include "SatLog.h"
+
+// USSD DCS coding.
+const TUint8 KSatDcs7Bit( 0x40 );
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::CCallControlHandler
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+//lint -e{1403, 1769} Can not be initialized, harmless.
+CCallControlHandler::CCallControlHandler() :
+ CSatCommandHandler(),
+ iCallControlData(),
+ iCallControlPckg( iCallControlData ),
+ iCallControlSendData(),
+ iCallControlSendDataPckg( iCallControlSendData ),
+ iCallControlUiRespData(),
+ iCallControlUiRespDataPckg( iCallControlUiRespData ),
+ iCcStatus( ECcIdle )
+ {
+ LOG( SIMPLE, "CALLCONTROL: \
+ CCallControlHandler::CCallControlHandler calling - exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCallControlHandler::ConstructL()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::ConstructL calling" )
+
+ iUtils->RegisterServiceRequestL(
+ ESatSProactiveNotification,
+ ESatSProactiveNotificationResponse,
+ this );
+
+ iRequestHandler =
+ CCallControlRequestHandler::NewL( iUtils->MultiModeApi(), this );
+
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::ConstructL exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCallControlHandler* CCallControlHandler::NewL( MSatUtils* aUtils )
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::NewL calling" )
+
+ CCallControlHandler* self = new( ELeave ) CCallControlHandler;
+
+ CleanupStack::PushL( self );
+ self->BaseConstructL( aUtils );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::NewL exiting" )
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::~CCallControlHandler
+// Destructor
+// -----------------------------------------------------------------------------
+CCallControlHandler::~CCallControlHandler()
+ {
+ LOG( SIMPLE,
+ "CALLCONTROL: CCallControlHandler::~CCallControlHandler calling" )
+
+ Cancel();
+
+ LOG( SIMPLE,
+ "CALLCONTROL: CCallControlHandler::~CCallControlHandler exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::ClientResponse
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCallControlHandler::ClientResponse()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::ClientResponse calling" )
+
+ CallControlClientOperation();
+
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::ClientResponse exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::DoCancel
+// Cancels the sat request.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCallControlHandler::DoCancel()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::DoCancel calling" )
+
+ iUtils->USatAPI().NotifyCallControlCancel();
+ iRequestHandler->CancelOperation( iCcStatus );
+
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::DoCancel exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::IssueUSATRequest
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCallControlHandler::IssueUSATRequest( TRequestStatus& aStatus )
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::IssueUSATRequest calling" )
+
+ // Clear the IPC package.
+ new (&iCallControlData) RSat::TCallControlV6();
+ iNeedUiSession = EFalse;
+ iUtils->USatAPI().NotifyCallControl( aStatus, iCallControlPckg );
+
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::IssueUSATRequest exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::CommandAllowed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CCallControlHandler::CommandAllowed()
+ {
+ LOG( SIMPLE,
+ "CALLCONTROL: CCallControlHandler::CommandAllowed calling - exiting" )
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::NeedUiSession
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CCallControlHandler::NeedUiSession()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::NeedUiSession calling" )
+ // UI is not needed, if control is AllowedWithMod and AlphaId is NULL or
+ // control is Allowed and AlphaId is not provided
+
+ // Get values
+ RSat::TAlphaId alphaId;
+ RSat::TAlphaIdValidity validity;
+ RSat::TControlResult controlResult;
+
+ // Get Alpha Id and Control result by SIM.
+ iCallControlPckg().GetAlphaId( validity, alphaId );
+ iCallControlPckg().GetCcGeneralResult( controlResult );
+
+ const TBool alphaIdNull( RSat::EAlphaIdNull == alphaId.iStatus ||
+ RSat::EAlphaIdNotSet == alphaId.iStatus );
+
+ const TBool controlAllowed(
+ RSat::EAllowedNoModification == controlResult ||
+ RSat::EControlResultNotSet == controlResult );
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::NeedUiSession \
+ controlResult: %d", controlResult )
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::NeedUiSession \
+ alphaId.iStatus: %d", alphaId.iStatus )
+
+ if ( RSat::EAllowedWithModifications == controlResult &&
+ alphaIdNull )
+ {
+ LOG( NORMAL, "CALLCONTROL: CCallControlHandler::NeedUiSession \
+ EAllowedWithModifications" )
+ iNeedUiSession = EFalse;
+ }
+ else if ( controlAllowed && ( RSat::EAlphaIdProvided != alphaId.iStatus ) )
+ {
+ LOG( NORMAL, "CALLCONTROL: CCallControlHandler::NeedUiSession \
+ RSat::EAlphaIdProvided != alphaId.iStatus" )
+ iNeedUiSession = EFalse;
+ }
+ else
+ {
+ iNeedUiSession = ETrue;
+ }
+
+ // Notify other commands that we are executing.
+ iUtils->NotifyEvent( MSatUtils::ECallControlExecuting );
+
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::NeedUiSession exiting" )
+ return iNeedUiSession;
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::HandleCommand
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCallControlHandler::HandleCommand()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::HandleCommand calling" )
+
+ // Check do we need UI
+ if ( iNeedUiSession )
+ {
+ // Clear send data.
+ TSatNotificationV1 clear;
+ iCallControlSendData = clear;
+
+ // Build the IPC package.
+ RSat::TAlphaId alphaId;
+ RSat::TAlphaIdValidity validity;
+ RSat::TControlResult controlResult;
+
+ // Get Alpha Id and Control result by SIM.
+ iCallControlPckg().GetAlphaId( validity, alphaId );
+ iCallControlPckg().GetCcGeneralResult( controlResult );
+
+ // Enums to UI related parameters
+ TSatAlphaIdStatus satAlphaIdStatus;
+ TSatControlResult satControlResult;
+
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::HandleCommand\
+ alphaId.iStatus: %d", alphaId.iStatus )
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::HandleCommand\
+ controlResult: %d", controlResult )
+ // Map RSat value
+ switch ( alphaId.iStatus )
+ {
+ case RSat::EAlphaIdProvided :
+ {
+ satAlphaIdStatus = ESatAlphaIdNotNull;
+ break;
+ }
+
+ case RSat::EAlphaIdNotPresent :
+ {
+ satAlphaIdStatus = ESatAlphaIdNotProvided;
+ break;
+ }
+
+ // Use this also as a default value
+ case RSat::EAlphaIdNull :
+ case RSat::EAlphaIdNotSet :
+ default :
+ {
+ satAlphaIdStatus = ESatAlphaIdNull;
+ break;
+ }
+ }
+
+ // Map RSat value
+ switch ( controlResult )
+ {
+ case RSat::ENotAllowed :
+ {
+ satControlResult = ESatNotAllowed;
+ break;
+ }
+
+ case RSat::EAllowedWithModifications :
+ {
+ satControlResult = ESatAllowedWithModifications;
+ break;
+ }
+
+ // Use this also as a default value
+ case RSat::EAllowedNoModification :
+ case RSat::EControlResultNotSet :
+ default :
+ {
+ satControlResult = ESatAllowedNoModification;
+ break;
+ }
+ }
+
+ // Get information needed.
+ iCallControlSendData.iCommand = ESatSCallControlNotify;
+ iCallControlSendData.iText = alphaId.iAlphaId;
+ iCallControlSendData.iAlphaIdStatus = satAlphaIdStatus;
+ iCallControlSendData.iControlResult = satControlResult;
+
+ // Register notification observer
+ TRAPD( regErr, iUtils->RegisterServiceRequestL(
+ ESatSProactiveNotification,
+ ESatSProactiveNotificationResponse,
+ this )
+ ); // TRAPD
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::HandleCommand \
+ regErr: %d",regErr )
+ // No need to check error value, since we cannot send terminal
+ // response for this command
+ if ( KErrNone == regErr )
+ {
+ // Get UISession.
+ MSatUiSession* uiSession = iUtils->SatUiHandler().UiSession();
+
+ // Send command to SatClient.
+ uiSession->SendCommand( &iCallControlSendDataPckg,
+ &iCallControlUiRespDataPckg, ESatSProactiveNotification );
+ }
+ }
+ else
+ {
+ LOG( NORMAL, "CCallControlHandler::HandleCommand UI isn't needed" )
+ CallControlClientOperation();
+ }
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::HandleCommand exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::UiLaunchFailed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCallControlHandler::UiLaunchFailed()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::UiLaunchFailed calling" )
+
+ // We cannot send terminal response to SIM since it doesn't
+ // expect terminal response from MoSmControl command...
+
+ // Inform the session that we are done here
+ iUtils->NotifyEvent( MSatUtils::EDelaySimSessionEnd );
+
+ // Start to receive more commands.
+ Start();
+
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::UiLaunchFailed exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::CallControlClientOperation
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCallControlHandler::CallControlClientOperation()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::CallControlClientOperation\
+ calling" )
+ RSat::TCallParamOrigin controlOrigin;
+ iCallControlData.GetCallParamOrigin( controlOrigin );
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::\
+ CallControlClientOperation GetCallParamOrigin = %d", controlOrigin )
+ iCcStatus = ECcIdle;
+
+ RSat::TActionOriginator actionOrigin;
+ iCallControlData.GetActionOriginator( actionOrigin );
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::\
+ CallControlClientOperation GetActionOriginator: %d", actionOrigin )
+
+ if ( RSat::EClientOriginator == actionOrigin )
+ {
+ RSat::TCallControlType controlType;
+ iCallControlData.GetCallControlType( controlType );
+
+ switch ( controlType )
+ {
+ case RSat::ECcAddress:
+ {
+ LOG( NORMAL, "CALLCONTROL: CCallControlHandler::\
+ CallControlClientOperation ControlType ECcArddress" )
+ if ( KErrNone == DialNumber() )
+ {
+ iCcStatus = ECcDialWaiting;
+ }
+ break;
+ }
+ case RSat::ECcSsString:
+ {
+ LOG( NORMAL, "CALLCONTROL: CCallControlHandler::\
+ CallControlClientOperation ControlType ECcSsString" )
+ if ( KErrNone == SendSs() )
+ {
+ iCcStatus = ECcSendSsWaiting;
+ }
+ break;
+ }
+ case RSat::ECcUssdString:
+ {
+ LOG( NORMAL, "CALLCONTROL: CCallControlHandler::\
+ CallControlClientOperation ControlType ECcUssdString" )
+ if ( KErrNone == SendUssd() )
+ {
+ iCcStatus = ECcSendUssdWaiting;
+ }
+ break;
+ }
+ default:
+ {
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::\
+ CallControlClientOperation ControlType %d", controlType )
+ break;
+ }
+ }
+ }
+
+ if ( ECcIdle == iCcStatus )
+ {
+ CompleteCallControlCmd( KErrNone );
+ }
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::CallControlClientOperation\
+ exiting" )
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::DialNumber
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCallControlHandler::DialNumber()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::DialNumber calling" )
+ TInt err( KErrNone );
+ iCcStatus = ECcDialWaiting;
+ RSat::TCallSetUpParams callParams;
+ err = iCallControlData.GetCallSetUpDetails ( callParams );
+
+ if ( !err )
+ {
+ RMobileCall::TMobileCallParamsV7 dialParams;
+ dialParams.iAutoRedial = ETrue;
+ dialParams.iBearerMode = RMobileCall::EMulticallNewBearer;
+ dialParams.iCallParamOrigin = RMobileCall::EOriginatorEtelClient;
+ dialParams.iSubAddress = callParams.iSubAddress;
+ dialParams.iBearerCap1 = callParams.iCcp1;
+ dialParams.iBearerCap2 = callParams.iCcp2;
+ iCallControlData.GetBCRepeatIndicator(
+ reinterpret_cast< RSat::TBCRepeatIndicator& >
+ ( dialParams.iBCRepeatIndicator ) );
+ dialParams.iIconId.iQualifier = RMobileCall::EIconQualifierNotSet;
+ dialParams.iIconId.iIdentifier = 0;
+
+ RSat::TAlphaId alphaid;
+ RSat::TAlphaIdValidity validity;
+ iCallControlData.GetAlphaId( validity, alphaid );
+
+ if ( (RSat::EValidAlpaId == validity)
+ && ( RSat::EAlphaIdProvided == alphaid.iStatus ) )
+ {
+ LOG2( NORMAL,
+ "CALLCONTROL: CCallControlHandler::DialNumber id:%S",
+ &alphaid.iAlphaId )
+ dialParams.iAlphaId = alphaid.iAlphaId;
+ }
+
+ LOG2( NORMAL,
+ "CALLCONTROL: CCallControlHandler::DialNumber string %S",
+ &callParams.iAddress.iTelNumber )
+
+
+ RMobileCall::TMobileCallParamsV7Pckg package( dialParams );
+ iRequestHandler->DialNumber( package, callParams.iAddress.iTelNumber );
+ }
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::DialNumber exiting %d",
+ err)
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::SendSS
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCallControlHandler::SendSs()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::SendSs calling" )
+ TInt err( KErrNone );
+
+ RSat::TSsString ssString;
+ err = iCallControlData.GetSendSsDetails( ssString );
+ if ( !err )
+ {
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::SendSs type %d",
+ ssString.iTypeOfNumber )
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::SendSs plan %d",
+ ssString.iNumberPlan )
+
+ HBufC16* ss16 = HBufC16::New( ssString.iSsString.Length() );
+ if ( ss16 )
+ {
+ TPtr16 ssPtr( ss16->Des() );
+ CnvUtfConverter::ConvertToUnicodeFromUtf8( ssPtr,
+ ssString.iSsString );
+
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::SendSs string %S",
+ ss16 )
+ iRequestHandler->SendSs( *ss16 );
+ delete ss16;
+ }
+ else
+ {
+ err = KErrNoMemory;
+ }
+ }
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::SendSs exiting %d", err)
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::SendUssd
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCallControlHandler::SendUssd()
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::SendUssd calling" )
+ TInt err( KErrNone );
+ RSat::TUssdString ussdString;
+ err = iCallControlData.GetSendUssdDetails ( ussdString );
+ if ( !err )
+ {
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::SendUssd string %S",
+ &ussdString.iUssdString )
+
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::SendUssd schema %d",
+ ussdString.iDcs )
+
+ RMobileUssdMessaging::TMobileUssdAttributesV1 ussdAttr;
+
+
+ if ( KSatDcs7Bit == ussdString.iDcs )
+ {
+ ussdAttr.iFormat= RMobileUssdMessaging::EFormatPackedString;
+ }
+ else
+ {
+ ussdAttr.iFormat= RMobileUssdMessaging::EFormatUnspecified;
+ }
+
+ HBufC8* ussd8 = HBufC8::New( ussdString.iUssdString.Length() );
+ if ( ussd8 )
+ {
+ ussd8->Des().Copy( ussdString.iUssdString );
+
+ ussdAttr.iFlags = RMobileUssdMessaging::KUssdDataFormat
+ | RMobileUssdMessaging::KUssdMessageType
+ | RMobileUssdMessaging::KUssdMessageDcs;
+
+ ussdAttr.iDcs = ussdString.iDcs;
+ ussdAttr.iType = RMobileUssdMessaging::EUssdMORequest;
+ RMobileUssdMessaging::TMobileUssdAttributesV1Pckg
+ ussdPckg( ussdAttr );
+
+ iRequestHandler->SendUssd ( *ussd8, ussdPckg );
+ delete ussd8;
+ }
+ else
+ {
+ err = KErrNoMemory;
+ }
+ }
+
+ LOG2( NORMAL, "CALLCONTROL: CCallControlHandler::SendUssd exiting %d",
+ err)
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::DispatchCcRequestComplete
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCallControlHandler::DispatchCcRequestComplete( TInt aErrCode )
+ {
+ LOG( SIMPLE,
+ "CALLCONTROL: CCallControlHandler::DispatchCcRequestComplete calling" )
+
+ LOG2( NORMAL,
+ "CALLCONTROL: CCallControlHandler::DispatchCcRequestComplete aErrCode %d",
+ aErrCode )
+
+ iCcStatus = ECcIdle;
+ CompleteCallControlCmd( aErrCode );
+
+ LOG2( NORMAL,
+ "CALLCONTROL: CCallControlHandler::SendUssd exiting %d", aErrCode )
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCallControlHandler::CompleteCallControlCmd
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCallControlHandler::CompleteCallControlCmd( TInt /*aErrCode*/ )
+ {
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::CompleteCallControlCmd\
+ calling" )
+
+ // Start to receive more commands. We have to start again here because
+ // we don't send terminal response, wich does this automatically.
+ Start();
+
+ // Inform the system that we are finished executing. If there is
+ // proactive SendSm command pending, it is notified and it continues
+ // from here.
+ iUtils->NotifyEvent( MSatUtils::ECallControlDone );
+
+ // If we launched UI, close it.
+ if ( !iUtils->SatUiHandler().UiLaunchedByUser() )
+ {
+ iUtils->NotifyEvent( MSatUtils::ESimSessionEndCallBack );
+ }
+ else
+ {
+ // Inform the session that we are done here.
+ iUtils->NotifyEvent( MSatUtils::EDelaySimSessionEnd );
+ }
+
+ // We do not send TerminalResponse to SIM.
+ LOG( SIMPLE, "CALLCONTROL: CCallControlHandler::CompleteCallControlCmd\
+ exiting" )
+ }
+
+// End of File