--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vtengines/videoteleng/Src/Base/cvtengmdtrcommandsender.cpp Mon Nov 23 14:47:47 2009 +0200
@@ -0,0 +1,460 @@
+/*
+* Copyright (c) 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: Mediator command sender implementation
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "cvtengmdtrcommandsender.h"
+#include "CVtEngEventManager.h"
+#include "VtEngUtils.h"
+#include "CVtEngSettings.h"
+#include "CVtEngOperation.h"
+#include "vtengcommands.h"
+#include "CVtEngStateManager.h"
+#include "VtEngPanic.h"
+#include <mediatorcommandinitiator.h>
+#include <mediatordomainuids.h>
+#include <mediatorcommandstotelephonyapi.h>
+#include <mediatoraudiocommandstotelephonyapi.h>
+#include <videoteltophonecommandsapi.h>
+#include <cvtlogger.h>
+
+
+/**
+* Three state classes for handling audio mute/unmute commands towards mediator when mute state
+* is changed locally faster than mediator gives response.
+
+
+ IDLE <-------------------------|
+ | |
+ NotifyOutgoingAudioState( x ) / mediator.Send( x ) |
+ | |
+ v |
+ |--------------------------------------> SENDING -- CommandResponseL ---|
+ | |
+ | NotifyOutgoingAudioState( y ) / saveCommand( y )
+ | |
+ | v
+ |- CommandResponseL( x ) / Send( y ) ---- BUFFERED
+
+
+
+
+*/
+NONSHARABLE_CLASS( TVtMdtrStateIdle ) : public CBase
+{
+ public:
+ TVtMdtrStateIdle( CVtEngMdtrCommandSender& aSender, CMediatorCommandInitiator& aMediator );
+ virtual void SendL( TUid aDomain, TUid aCategory, TInt aCommand );
+ virtual void CommandResponseL( TUid aDomain, TUid aCategory, TInt aCommand, TInt aStatus );
+
+ TInt DoSend( TUid aDomain, TUid aCategory, TInt aCommand );
+
+ CVtEngMdtrCommandSender& iSender;
+ CMediatorCommandInitiator& iMediator;
+};
+
+NONSHARABLE_CLASS( TVtMdtrStateSending ) : public TVtMdtrStateIdle
+{
+ public:
+ TVtMdtrStateSending( CVtEngMdtrCommandSender& aSender, CMediatorCommandInitiator& aMediator );
+ void SendL( TUid aDomain, TUid aCategory, TInt aCommand );
+ void CommandResponseL( TUid aDomain, TUid aCategory, TInt aCommand, TInt aStatus );
+};
+
+NONSHARABLE_CLASS( TVtMdtrStateBuffered ) : public TVtMdtrStateIdle
+{
+ public:
+ TVtMdtrStateBuffered( CVtEngMdtrCommandSender& aSender, CMediatorCommandInitiator& aMediator );
+ void SendL( TUid aDomain, TUid aCategory, TInt aCommand );
+ void CommandResponseL( TUid aDomain, TUid aCategory, TInt aCommand, TInt aStatus );
+
+ TUid iDomain;
+ TUid iCategory;
+ TInt iCommand;
+};
+
+
+// CONSTANTS
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CVtEngMdtrCommandSender* CVtEngMdtrCommandSender::NewL( CVtEngUtility& aUtils )
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.NewL" )
+ CVtEngMdtrCommandSender* self = new ( ELeave )
+ CVtEngMdtrCommandSender( aUtils );
+ CleanupStack::PushL( self );
+ self->ConstructL( );
+ CleanupStack::Pop();
+
+ __VTPRINTEXIT( "CVtEngMdtrCommandSender.NewL" )
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::~CVtEngMdtrCommandSender
+// destructor
+// -----------------------------------------------------------------------------
+//
+CVtEngMdtrCommandSender::~CVtEngMdtrCommandSender()
+ {
+ iUtils.EventManager().RemoveObserver( this );
+ delete iMediatorInitiator;
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::EndCall
+// Sends end call command via Mediator
+// -----------------------------------------------------------------------------
+//
+void CVtEngMdtrCommandSender::EndCall( )
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.EndCall" )
+ const TVersion KTelephonyCmdVersion(
+ KTelephonyCommandsVersionMajor,
+ KTelephonyCommandsVersionMinor,
+ KTelephonyCommandsVersionBuild );
+ const TInt res =
+ iMediatorInitiator->IssueCommand(
+ KMediatorTelephonyDomain,
+ KCatCommandsToTelephony,
+ EPhoneCmdEndActiveCall,
+ KTelephonyCmdVersion,
+ KNullDesC8() );
+
+ __VTPRINTEXITR( "CVtEngMdtrCommandSender.EndCall res=%d", res )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::VoiceFallback
+// Sends voice fallback command to telephony via Mediator
+// -----------------------------------------------------------------------------
+//
+void CVtEngMdtrCommandSender::VoiceFallback()
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.VoiceFallback" )
+ const TVersion KVtToPhoneCmdVersion(
+ KVideoTelToPhoneCmdVersionMajor,
+ KVideoTelToPhoneCmdVersionMinor,
+ KVideoTelToPhoneCmdVersionBuild );
+#ifdef _DEBUG
+ TInt err =
+#endif
+ iMediatorInitiator->IssueCommand(
+ KMediatorTelephonyDomain,
+ KCatVideoTelToPhoneCommands,
+ EVtCmdFallback,
+ KVtToPhoneCmdVersion,
+ KNullDesC8() );
+ // response is not awaited
+ __VTPRINTEXITR( "CVtEngMdtrCommandSender.VoiceFallback %d>", err )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::SwitchToVoiceL
+// Sends switch to voice command to telephony via Mediator
+// -----------------------------------------------------------------------------
+//
+void CVtEngMdtrCommandSender::SwitchToVoiceL( CVtEngOperation& aOperation )
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.SwitchToVoiceL" )
+ iOperation = &aOperation;
+ // add this as observer. Mediator command is sent when idle state
+ // is reached (i.e. Protocol has released dataport and it can be recovered
+ // by telephony)
+ iUtils.EventManager().AddObserverL( this );
+ // let current state handle actual request
+ iUtils.StateManager()->HandleOperationL( aOperation );
+ __VTPRINTEXIT( "CVtEngMdtrCommandSender.SwitchToVoiceL" )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::NotifyOutgoingAudioState
+// Sends microphone state to telephony via Mediator
+// -----------------------------------------------------------------------------
+//
+void CVtEngMdtrCommandSender::NotifyOutgoingAudioState(
+ const TBool aMicEnabled )
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.NotifyOutgoingAudioState" )
+
+ const TInt command = ( aMicEnabled )
+ ? EAudioCmdUnmute : EAudioCmdMute;
+#ifdef _DEBUG
+ TRAPD( res, iSenderState->SendL(
+ KMediatorTelephonyDomain,
+ KCatAudioCommandsToTelephony,
+ command ) );
+#else
+ TRAP_IGNORE(iSenderState->SendL(
+ KMediatorTelephonyDomain,
+ KCatAudioCommandsToTelephony,
+ command ) );
+#endif
+
+ __VTPRINTEXITR( "CVtEngMdtrCommandSender.NotifyOutgoingAudioState %d", res )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::SetSenderState
+// sets new mediator sender state for audio command
+// -----------------------------------------------------------------------------
+//
+void CVtEngMdtrCommandSender::SetSenderState( TVtMdtrStateIdle& aNewState )
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.SetSenderState" )
+ __VTPRINT2( DEBUG_GEN, " delete old state %x", (TInt) iSenderState )
+ __ASSERT_DEBUG( iSenderState != &aNewState,
+ Panic( EVtEngPanicWrongMediatorSenderState ) );
+ delete iSenderState;
+ iSenderState = &aNewState;
+ __VTPRINTEXITR( "CVtEngMdtrCommandSender.SetSenderState %x", (TInt) iSenderState )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::CommandResponseL
+// Mediator framework callback
+// -----------------------------------------------------------------------------
+//
+void CVtEngMdtrCommandSender::CommandResponseL( TUid aDomain,
+ TUid aCategory,
+ TInt aCommandId,
+ TInt aStatus,
+ const TDesC8& /*aData*/ )
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.CommandResponseL" )
+ switch ( aCommandId )
+ {
+ case EAudioCmdUnmute:
+ case EAudioCmdMute:
+ iSenderState->CommandResponseL( aDomain, aCategory, aCommandId, aStatus );
+ break;
+ default:
+ // ignored for other commands (so far)
+ break;
+ }
+ __VTPRINT2( DEBUG_GEN, " mediator command id=%d", aCommandId )
+ __VTPRINTEXITR( "CVtEngMdtrCommandSender.CommandResponseL res=%d", aStatus )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::HandleVtEventL
+// Handles state change event associated with "switch to voice" and "TerminateSession" command
+// -----------------------------------------------------------------------------
+//
+void CVtEngMdtrCommandSender::HandleVtEventL( TInt aEvent )
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.HandleVtEventL" )
+#ifdef _DEBUG
+ TInt err = KErrNone;
+#endif
+ if ( aEvent == KVtEngSessionStateChanged &&
+ iOperation && iOperation->Command() == KVtEngSwitchToVoice )
+ {
+ const TVersion KVtToPhoneCmdVersion(
+ KVideoTelToPhoneCmdVersionMajor,
+ KVideoTelToPhoneCmdVersionMinor,
+ KVideoTelToPhoneCmdVersionBuild );
+
+ iUtils.EventManager().RemoveObserver( this );
+ // send command (ignore possible error - no way to recover from it)
+#ifdef _DEBUG
+ err =
+#endif
+ iMediatorInitiator->IssueCommand(
+ //KMediatorVideoTelephonyDomain,
+ KMediatorTelephonyDomain,
+ KCatVideoTelToPhoneCommands,
+ EVtCmdSwitchToVoice,
+ KVtToPhoneCmdVersion,
+ KNullDesC8() );
+ iOperation->HandleOpComplete( KErrNone );
+ iOperation = NULL;
+ }
+ __VTPRINTEXITR( "CVtEngMdtrCommandSender.HandleVtEventL %d", err )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::
+// c++ constructor
+// -----------------------------------------------------------------------------
+//
+CVtEngMdtrCommandSender::CVtEngMdtrCommandSender( CVtEngUtility& aUtils ) :
+ iUtils( aUtils )
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.CVtEngMdtrCommandSender" )
+ __VTPRINTEXIT( "CVtEngMdtrCommandSender.CVtEngMdtrCommandSender" )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtEngMdtrCommandListener::ConstructL
+//
+// -----------------------------------------------------------------------------
+//
+void CVtEngMdtrCommandSender::ConstructL()
+ {
+ __VTPRINTENTER( "CVtEngMdtrCommandSender.ConstructL" )
+ iMediatorInitiator = CMediatorCommandInitiator::NewL( this );
+
+ // set initial mediator command sender state
+ iSenderState = new ( ELeave ) TVtMdtrStateIdle( *this, *iMediatorInitiator );
+ __VTPRINTEXIT( "CVtEngMdtrCommandSender.ConstructL" )
+ }
+
+TVtMdtrStateIdle::TVtMdtrStateIdle( CVtEngMdtrCommandSender& aSender, CMediatorCommandInitiator& aMediator )
+: iSender( aSender), iMediator( aMediator )
+ {
+ __VTPRINTENTER( "TVtMdtrStateIdle.ctr" )
+ __VTPRINTEXITR( "TVtMdtrStateIdle.ctr %x", (TInt) this )
+ }
+
+void TVtMdtrStateIdle::SendL( TUid aDomain, TUid aCategory, TInt aCommand )
+ {
+ __VTPRINTENTER( "TVtMdtrStateIdle.SendL" )
+ TVtMdtrStateIdle* nextState = NULL;
+ const TInt res = DoSend( aDomain, aCategory, aCommand );
+ if ( res == KErrInUse )
+ {
+ nextState = new ( ELeave ) TVtMdtrStateBuffered( iSender, iMediator );
+ CleanupStack::PushL( nextState );
+ nextState->SendL( aDomain, aCategory, aCommand );
+ CleanupStack::Pop( nextState );
+ }
+ else
+ {
+ nextState = new ( ELeave ) TVtMdtrStateSending( iSender, iMediator );
+ }
+ iSender.SetSenderState( *nextState );
+ __VTPRINTEXIT( "TVtMdtrStateIdle.SendL" )
+ }
+
+TInt TVtMdtrStateIdle::DoSend( TUid aDomain, TUid aCategory, TInt aCommand )
+ {
+ __VTPRINTENTER( "TVtMdtrStateIdle.DoSend" )
+ const TVersion KVtToPhoneCmdVersion(
+ KVideoTelToPhoneCmdVersionMajor,
+ KVideoTelToPhoneCmdVersionMinor,
+ KVideoTelToPhoneCmdVersionBuild );
+
+ TInt res = iMediator.IssueCommand(
+ aDomain,
+ aCategory,
+ aCommand,
+ KVtToPhoneCmdVersion,
+ KNullDesC8() );
+ __VTPRINTEXITR( "TVtMdtrStateIdle.DoSend res=%d", res )
+ return res;
+ }
+
+void TVtMdtrStateIdle::CommandResponseL( TUid /*aDomain*/, TUid /*aCategory*/, TInt /*aCommand*/, TInt /*aStatus*/ )
+ {
+ __VTPRINTENTER( "TVtMdtrStateIdle.CommandResponseL" )
+ // base class method should never be possible to call
+ __VTPRINTEXIT( "TVtMdtrStateIdle.CommandResponseL" )
+ }
+
+TVtMdtrStateSending::TVtMdtrStateSending( CVtEngMdtrCommandSender& aSender, CMediatorCommandInitiator& aMediator )
+: TVtMdtrStateIdle( aSender, aMediator )
+ {
+ __VTPRINTENTER( "TVtMdtrStateSending.ctr" )
+ __VTPRINTEXITR( "TVtMdtrStateSending.ctr %x", (TInt) this )
+ }
+
+void TVtMdtrStateSending::SendL( TUid aDomain, TUid aCategory, TInt aCommand )
+ {
+ __VTPRINTENTER( "TVtMdtrStateSending.SendL" )
+ TVtMdtrStateIdle* buffered = new ( ELeave )TVtMdtrStateBuffered( iSender, iMediator );
+ CleanupStack::PushL( buffered );
+ buffered->SendL( aDomain, aCategory, aCommand );
+ CleanupStack::Pop( buffered );
+ iSender.SetSenderState( *buffered );
+ __VTPRINTEXIT( "TVtMdtrStateSending.SendL" )
+ }
+
+void TVtMdtrStateSending::CommandResponseL( TUid aDomain, TUid aCategory, TInt aCommand, TInt aStatus )
+ {
+ __VTPRINTENTER( "TVtMdtrStateSending.CommandResponseL" )
+ __VTPRINT2( DEBUG_GEN, " command=%d", aCommand )
+ __VTPRINT2( DEBUG_GEN, " response=%d", aStatus )
+ TVtMdtrStateIdle* idle = new ( ELeave ) TVtMdtrStateIdle( iSender, iMediator );
+ iSender.SetSenderState( *idle );
+ __VTPRINTEXIT( "TVtMdtrStateSending.CommandResponseL" )
+ }
+
+TVtMdtrStateBuffered::TVtMdtrStateBuffered( CVtEngMdtrCommandSender& aSender, CMediatorCommandInitiator& aMediator )
+: TVtMdtrStateIdle( aSender, aMediator )
+ {
+ __VTPRINTENTER( "TVtMdtrStateBuffered.ctr" )
+ __VTPRINTEXITR( "TVtMdtrStateBuffered.ctr %x", (TInt) this )
+ }
+
+void TVtMdtrStateBuffered::SendL( TUid aDomain, TUid aCategory, TInt aCommand )
+ {
+ __VTPRINTENTER( "TVtMdtrStateBuffered.SendL" )
+
+ iDomain = aDomain;
+ iCategory = aCategory;
+ iCommand = aCommand;
+ // iCommand is sent in CommandResponseL
+ __VTPRINTEXIT( "TVtMdtrStateBuffered.SendL" )
+ }
+
+void TVtMdtrStateBuffered::CommandResponseL( TUid aDomain, TUid aCategory, TInt aCommand, TInt aStatus )
+ {
+ __VTPRINTENTER( "TVtMdtrStateBuffered.CommandResponseL" )
+ const TVersion KVtToPhoneCmdVersion(
+ KVideoTelToPhoneCmdVersionMajor,
+ KVideoTelToPhoneCmdVersionMinor,
+ KVideoTelToPhoneCmdVersionBuild );
+ TBool nextStateIdle = ETrue;
+ TInt res = KErrNone;
+ if ( aCommand != iCommand )
+ {
+ res = iMediator.IssueCommand(
+ KMediatorTelephonyDomain,
+ KCatAudioCommandsToTelephony,
+ iCommand,
+ KVtToPhoneCmdVersion,
+ KNullDesC8() );
+ if ( res == KErrNone )
+ {
+ nextStateIdle = EFalse;
+ }
+ }
+ TVtMdtrStateIdle* nextState = NULL;
+ if ( nextStateIdle )
+ {
+ __VTPRINT2( DEBUG_GEN, " failed to send buffered command with error=%d", res )
+ nextState = new ( ELeave ) TVtMdtrStateIdle( iSender, iMediator );
+ }
+ else
+ {
+ nextState = new ( ELeave ) TVtMdtrStateSending( iSender, iMediator );
+ CleanupStack::PushL( nextState );
+ nextState->SendL( iDomain, iCategory, iCommand );
+ CleanupStack::Pop( nextState );
+ }
+ iSender.SetSenderState( *nextState );
+ __VTPRINTEXIT( "TVtMdtrStateBuffered.CommandResponseL" )
+ }
+
+// End of File