diff -r ccd8e69b5392 -r 496ad160a278 mmsharing/mmshavailability/src/musavaoptionhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmsharing/mmshavailability/src/musavaoptionhandler.cpp Fri Jun 11 13:36:18 2010 +0300 @@ -0,0 +1,784 @@ +/* +* Copyright (c) 2005-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: Provide interface for the client requestin availability class. +* +*/ + + +#include "musavaoptionhandler.h" + +#include +#include +#include "musunittesting.h" +#include "musavasharedobject.h" +#include "muslogger.h" +#include "musavasip.h" +#include "musavasettingsimp.h" +#include "musavacapabilitysipagent.h" +#include "musavacapabilityexchange.h" +#include "musavacapabilityquery.h" +#include "musavacapability.h" +#include "musavacapabilityquerybase.h" +#include "musavaterminal.h" +#include "mussettingskeys.h" +#include "mussettings.h" +#include "mussesseioninformationapi.h" + + +_LIT( KMusSipPrefix, "sip:" ); +_LIT( KMusTelPrefix, "tel:" ); +_LIT( KMusPlusSign, "+" ); + +const TInt KMaxUriLength = 512; +const TInt KMusMinDigitCountInTelNumber = 7; + +const TInt KMusOptionsHandlerIndex = 1; + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CMusAvaOptionHandler* CMusAvaOptionHandler::NewL( + MMusAvaAvailabilityObserver& aObserver, + CMusAvaSettingsImp& aSettings ) + { + MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::NewL()" ) + CMusAvaOptionHandler* self = CMusAvaOptionHandler::NewLC( + aObserver, + aSettings ); + CleanupStack::Pop( self ); + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::NewL()" ) + return self; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CMusAvaOptionHandler* CMusAvaOptionHandler::NewLC( + MMusAvaAvailabilityObserver& aObserver, + CMusAvaSettingsImp& aSettings ) + { + MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::NewLC()" ) + CMusAvaOptionHandler* self = new( ELeave ) CMusAvaOptionHandler( + aObserver, + aSettings ); + CleanupStack::PushL( self ); + self->ConstructL(); + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::NewLC()" ) + return self; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CMusAvaOptionHandler::~CMusAvaOptionHandler() + { + MUS_LOG( + "mus: [MUSAVA] -> CMusAvaOptionHandler::~CMusAvaOptionHandler()" ) + if (iSharedObj ) + { + iSharedObj->DeleteSingleton(); + } + delete iCapabilityExchange; + iCapabilityExchange = NULL; + delete iSipAgent; + iSipAgent = NULL; + + MUS_LOG( + "mus: [MUSAVA] <- CMusAvaOptionHandler::~CMusAvaOptionHandler()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CMusAvaOptionHandler::CMusAvaOptionHandler( + MMusAvaAvailabilityObserver& aObserver, + CMusAvaSettingsImp& aSettings ) + :CMusAvaAvailability( aObserver ), + iSettings( aSettings ) + { + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::ConstructL() + { + MUS_LOG( "mus: [MUSAVA] -> CMusAvaOptionHandler::ConstructL()" ) + + //construct capability exchange + ConstructCapabilityExchangeL(); + + iSharedObj = CMusAvaSharedObject::GetSingletonL(); + iSipAgent = CMusAvaCapabilitySipAgent::NewL( *iCapabilityExchange, + *iSharedObj, + iObserver ); + iSharedObj->MusAvaSip().AddAdapterL( + ( MMusAvaSipConnectionAdapter& ) *iSipAgent, + KMusOptionsHandlerIndex ); + iSharedObj->MusAvaSip().AddAdapterL( + ( MMusAvaSipAdapter& ) *iSipAgent, + KMusOptionsHandlerIndex ); + + MUS_LOG( "mus: [MUSAVA] Check fast mode capability" ) + + TRAPD( err, + iFastModeCapable = + MultimediaSharingSettings::FastStartupModeL() == MusSettingsKeys::EFastModeOn && + MultimediaSharingSettings::VideoDirectionL() == MusSettingsKeys::ETwoWayVideo && + MultimediaSharingSettings::CapabilityQuerySettingL() == MusSettingsKeys::EParallel ); + if ( err == KErrNoMemory ) + { + User::Leave( err ); + } + + MUS_LOG2( "mus: [MUSAVA] Fast mode check, err:%d, capable:%d", + err, iFastModeCapable ) + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::ConstructL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TBool CMusAvaOptionHandler::CapabilityQueryAnswered( TBool aAnswered ) + { + MUS_LOG1( "mus: [MUSAVA] <-> CMusAvaOptionHandler::CapabilityQueryAnswered():%d", + aAnswered ) + + iCapabilityQueryAnswered = aAnswered ? aAnswered : iCapabilityQueryAnswered; + + HandleFastModeQueryAnswered(); + + return iCapabilityQueryAnswered; + + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::ConstructCapabilityExchangeL() + { + MUS_LOG( + "mus: [MUSAVA] -> CMusAvaOptionHandler::ConstructCapabilityExchangeL()" ) + HBufC8* terminalId = ConstructTerminalIdL(); + CleanupStack::PushL( terminalId ); + + //create capability exchange + iCapabilityExchange = + CMusAvaCapabilityExchange::NewL( *terminalId, *this ); + + //create SWIS capability + CMusAvaCapability* capability = CMusAvaCapability::NewL( + *iCapabilityExchange ); + CleanupStack::PushL( capability ); + iCapabilityExchange->AddCapabilityL( capability ); + CleanupStack::Pop( capability ); + + iSwisCapability = capability; + + CleanupStack::PopAndDestroy( terminalId ); + MUS_LOG( + "mus: [MUSAVA] <- CMusAvaOptionHandler::ConstructCapabilityExchangeL()" ) + } + + +// ----------------------------------------------------------------------------- +// @TODO: Currently terminal id is not in use i.e User-Agent header is not +// sent in request nor response. +// ----------------------------------------------------------------------------- +// +HBufC8* CMusAvaOptionHandler::ConstructTerminalIdL() + { + return KNullDesC8().AllocL(); + } + + +// ----------------------------------------------------------------------------- +// Starts the loopy execution. +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::DoExecuteL() + { + MUS_LOG( "mus: [MUSAVA] -> CMusAvaOptionHandler::DoExecuteL()" ) + + MusSettingsKeys::TOperatorVariant variantSetting = + MultimediaSharingSettings::OperatorVariantSettingL(); + + /* + Do not resent the OPTIONS request in the below scenario + i) Options Sent and waiting for Response. + ii) We already sent OPTIONS and got positive response.So we know that + other device is VS capable. + iii) We already sent OPTIONS and got negative response.So we know that + other device is VS incapable. + + Also OPTIONS should be sent only once if it matches to VS Call criteria. + */ + MUS_LOG1( "mus: [MUSAVA] - Current State %d",State() ) + + if ( State() == MMusAvaObserver::EMusAvaStatusOptionsSent || + State() == MMusAvaObserver::EMusAvaStatusAvailable || + State() == MMusAvaObserver::EMusAvaOptionNotAvailable ) + { + return; + } + + if ( variantSetting == MusSettingsKeys::EOperatorSpecific + && iSettings.CallDirection() == 2 && !iCapabilitiesRequestAnswered ) + { // terminated party + DoSetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent ); + } + else if ( MusSettingsKeys::ESequential == + MultimediaSharingSettings::CapabilityQuerySettingL() + && iSettings.CallDirection() == 2 && !iCapabilitiesRequestAnswered ) + { // terminated party + DoSetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent ); + } + else + { + if ( MusSettingsKeys::EOperatorSpecific == variantSetting || + MusSettingsKeys::EParallel == + MultimediaSharingSettings::CapabilityQuerySettingL() || + MusSettingsKeys::ESequential == + MultimediaSharingSettings::CapabilityQuerySettingL() ) + { + const MDesCArray& addresses = iSettings.SipAddresses(); + + TInt addressesCount = addresses.MdcaCount(); + MUS_LOG1( "mus: [MUSAVA] addresses.MdcaCount() %d", + addressesCount ) + if( addressesCount ) + { + const TDesC& sipAddress = addresses.MdcaPoint( 0 ); + MUS_LOG_TDESC( "mus: [MUSAVA] SIP Address: ", + sipAddress ) + TRAPD( err, iSipAgent->ExecuteCapabilityQueryL( + *iSwisCapability, sipAddress ) ); + // set status available and report to the observer + if ( err == KErrNone ) + { + HBufC8* sipAddress8 = + EscapeUtils::ConvertFromUnicodeToUtf8L( sipAddress ); + CleanupStack::PushL( sipAddress8 ); + if ( iCapabilityExchange-> + TerminalL( sipAddress8->Des() ).QueryExecuting() ) + { + DoSetState( MMusAvaObserver::EMusAvaStatusOptionsSent ); + } + else + { + DoSetState( MMusAvaObserver::EMusAvaStatusAvailable ); + } + CleanupStack::PopAndDestroy( sipAddress8 ); + } + // when profile is in when needed mode and registration still on + // going we get this error and wait untill registration is successful + // since we did not send any options set the state EMusAvaStatusNotExecuted. + else if( err == KErrSIPInvalidRegistrationState ) + { + DoSetState( MMusAvaObserver::EMusAvaStatusNotExecuted ); + } + // anything other than this should be considered default , means options sent + // and was not successful. + else + { + DoSetState( MMusAvaObserver::EMusAvaOptionNotAvailable ); + } + } + else + { + DoSetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent ); + } + } + else + { + // option sending not needed + DoSetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent ); + } + } + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::DoExecuteL()" ) + } + + +// ----------------------------------------------------------------------------- +// Stops executing availability. +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::Stop() + { + MUS_LOG( "mus: [MUSAVA] -> CMusAvaOptionHandler::Stop()" ) + // TBD + MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::Stop()" ) + } + + +// ----------------------------------------------------------------------------- +// Returns name of *this* availability. +// ----------------------------------------------------------------------------- +// +MMusAvaObserver::TAvailabilityName CMusAvaOptionHandler::Name() + { + return MMusAvaObserver::EMusAvaOptionHandler; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::PrepareForReceivedInviteL() + { + MUS_LOG( "mus: [MUSAVA] -> CMusAvaOptionHandler::PrepareForReceivedInviteL()" ) + + if ( iFastModeAvailabilityDelayed ) + { + MUS_LOG( "mus: [MUSAVA] Set delayed availability" ) + SetState( MMusAvaObserver::EMusAvaStatusAvailable ); + iFastModeAvailabilityDelayed = EFalse; + } + + MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::PrepareForReceivedInviteL()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::CapabilitiesResolved( + const CMusAvaCapabilityQueryBase& aSentQuery ) + { + MUS_LOG( + "mus: [MUSAVA] -> CMusAvaOptionHandler::CapabilitiesResolved()" ) + if ( aSentQuery.Result() == KCapabilityCapabilitesReady ) + { + // tell the upper layer that + // query was succesfull. VS is available + DoSetState( MMusAvaObserver::EMusAvaStatusAvailable ); + } + else if ( aSentQuery.Result() == KCapabilityCapabilitiesForbidden ) + { + // query returned with response "403 Forbidden". VS is NOT available + DoSetState( MMusAvaObserver::EMusAvaFailureCode ); + } + else + { + //query failed. VS is NOT available + DoSetState( MMusAvaObserver::EMusAvaOptionNotAvailable ); + } + + MUS_LOG( + "mus: [MUSAVA] <- CMusAvaOptionHandler::CapabilitiesResolved()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::CapabilitiesResolvedL( const TDesC& aUri ) + { + MUS_LOG( + "mus: [MUSAVA] -> CMusAvaOptionHandler::CapabilitiesResolvedL()" ) + if ( aUri.Length() > 0 ) + { + // Set the sip address resolved from succesfull OPTIONS response + // Old adress(es) are destroyed + CDesCArrayFlat* sipAddresses = new( ELeave ) CDesCArrayFlat( 1 ); + CleanupStack::PushL( sipAddresses ); + + sipAddresses->AppendL( aUri ); + iSettings.SetSipAddressesL( *sipAddresses ); + + MUS_LOG_TDESC( "mus: [MUSAVA] SIP Address: ", aUri ) + + sipAddresses->Reset(); + CleanupStack::PopAndDestroy( sipAddresses ); + } + + MUS_LOG( + "mus: [MUSAVA] <- CMusAvaOptionHandler::CapabilitiesResolvedL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::SetCapabilitiesResolvedForCingular() + { + MUS_LOG( + "mus: [MUSAVA] -> CMusAvaOptionHandler::\ + SetCapabilitiesResolvedForCingular()" ) + iCapabilitiesRequestAnswered = ETrue; + + TRAPD( error, DoExecuteL() ); + if ( error ) + { + MUS_LOG1( "mus: [MUSAVA] <- CMusAvaOptionHandler::\ + SetCapabilitiesResolvedForCingular() leave code = %d", error ) + } + else + { + MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::\ + SetCapabilitiesResolvedForCingular()" ) + } + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TBool CMusAvaOptionHandler::CapabilitiesResolvedForCingular() + { + MUS_LOG( + "mus: [MUSAVA] CMusAvaOptionHandler::CapabilitiesResolvedForCingular()" ) + return iCapabilitiesRequestAnswered; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::SipHeadersL( + const MDesCArray& aHeaders, + SipStrConsts::TStrings aHeaderType) + { + MUS_LOG("mus: [MUSAVA] -> CMusAvaOptionHandler::SipHeadersL()" ) + + // if header type is to then store in iSettings , so then future + // request will be send there. + if(aHeaderType == SipStrConsts::EToHeader) + { + // All addresses received should be valid, so choose just one to avoid + // situation where user has to choose one from equal addresses. + // Prefer SIP URI, but accept also TEL URI. + + TBuf sipUri; + TBuf telUri; + + for ( TInt i = 0; i < aHeaders.MdcaCount(); ++i ) + { + if ( aHeaders.MdcaPoint( i ).FindF( KMusSipPrefix ) != + KErrNotFound ) + { + sipUri.Copy( aHeaders.MdcaPoint( i ) ); + } + else if ( aHeaders.MdcaPoint(i).FindF( KMusTelPrefix ) != + KErrNotFound ) + { + telUri.Copy( aHeaders.MdcaPoint( i ) ); + } + else + { + // NOP + } + } + + CDesCArray* addresses = new( ELeave ) CDesCArrayFlat( 1 ); + CleanupStack::PushL( addresses ); + + if ( telUri.Length() > 0 ) + { + telUri.Trim(); + addresses->AppendL( telUri ); + // Check if TEL URI conforms to phone number currently hold. + // If they do not match, we replace phone number with one parsed + // out of received from P-Asserted-Identity header. Since in this + // scenario we cannot be sure about validity of contact name either, + // we empty the contact name. This is only not to show incorrect + // information, but this solution does not show possibly existing + // contact name. + + // We compare last seven digits, since that is the minimum amount + // that can make up a valid telephone number. + // Variable telUri holds also prefix, but that does not affect the + // righthand comparison. + + MUS_LOG_TDESC( "mus: [MUSUI ] iSettings.TelNumber(): ", + iSettings.TelNumber() ) + MUS_LOG_TDESC( "mus: [MUSUI ] telUri: ", telUri ) + + TPtrC16 telUriWithoutPrefix = + telUri.Right( telUri.Length() - KMusTelPrefix().Length() ); + + TPtrC16 numberPartOfTelUri = + telUriWithoutPrefix.Find( KMusPlusSign ) == 0 ? + telUriWithoutPrefix.Right( telUriWithoutPrefix.Length() - 1 ) : + telUriWithoutPrefix; + + if ( !( iSettings.TelNumber().Length() >= KMusMinDigitCountInTelNumber && + numberPartOfTelUri.Length() >= KMusMinDigitCountInTelNumber && + iSettings.TelNumber().Right( KMusMinDigitCountInTelNumber ) == + telUri.Right( KMusMinDigitCountInTelNumber ) ) ) + { + iSettings.SetTelNumberL( telUriWithoutPrefix ); + iSettings.SetContactNameL( KNullDesC() ); + iSettings.SetContactId( KErrNotFound ); + } + } + + if ( sipUri.Length() > 0 ) + { + // Replace possibly existing TEL URI with SIP URI + addresses->Reset(); + addresses->AppendL( sipUri ); + } + + iSettings.SetSipAddressesL( addresses ); // Transfers ownership + CleanupStack::Pop( addresses ); + } + else + { + // should go for future need if any. + } + MUS_LOG("mus: [MUSAVA] <- CMusAvaOptionHandler::SipHeadersL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::VideoCodecsResolvedL( const MDesCArray& aVideoCodecs ) + { + MUS_LOG("mus: [MUSAVA] -> CMusAvaOptionHandler::VideoCodecsResolvedL()" ) + + iSettings.SetVideoCodecsL( aVideoCodecs ); + + MUS_LOG("mus: [MUSAVA] <- CMusAvaOptionHandler::VideoCodecsResolvedL()" ) + } + + +// ----------------------------------------------------------------------------- +// If MO side fast mode negotiation has failed, cannot change the value anymore +// as it is very likely that automatic invitation fails as well. +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::FastModeResolved( MusSettingsKeys::TFastMode aMode ) + { + MUS_LOG1("mus: [MUSAVA] -> CMusAvaOptionHandler::FastModeResolved():%d", + aMode ) + + if ( FastModeNegotiationFailedMO() ) + { + MUS_LOG("mus: [MUSAVA] Ignore setting as failed already" ) + } + else + { + iSettings.SetFastMode( aMode ); + } + + MUS_LOG("mus: [MUSAVA] <- CMusAvaOptionHandler::FastModeResolved()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TInt CMusAvaOptionHandler::DoSetState( MMusAvaObserver::TAvailabilityStatus aNewState ) + { + MUS_LOG1( "mus: [MUSAVA] -> CMusAvaOptionHandler::DoSetState() state:%d", + aNewState ) + TInt err( KErrNone ); + + if ( iFastModeCapable ) + { + TRAP( err, aNewState = HandleFastModeL( aNewState ) ); + } + + SetState( aNewState ); + + MUS_LOG1("mus: [MUSAVA] <- CMusAvaOptionHandler::DoSetState(), err:%d", err ) + + return err; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +MMusAvaObserver::TAvailabilityStatus CMusAvaOptionHandler::HandleFastModeL( + MMusAvaObserver::TAvailabilityStatus aNewState ) + { + MUS_LOG("mus: [MUSAVA] -> CMusAvaOptionHandler::HandleFastModeL()" ) + + switch ( aNewState ) + { + case MMusAvaObserver::EMusAvaOptionNotAvailable: + { + aNewState = HandleFastModeOptionNotAvailableL( aNewState ); + break; + } + case MMusAvaObserver::EMusAvaStatusOptionsNotSent: + { + aNewState = HandleFastModeOptionsNotSentL( aNewState ); + break; + } + case MMusAvaObserver::EMusAvaStatusAvailable: + { + aNewState = HandleFastModeAvailableL( aNewState ); + break; + } + default: + { + break; + } + } + + MUS_LOG("mus: [MUSAVA] <- CMusAvaOptionHandler::HandleFastModeL()" ) + + return aNewState; + } + +// ----------------------------------------------------------------------------- +// If fast mode and call originator, application is started +// automatically at background with two-way MO use case. If fast mode is +// negotiated, availability publishing is delayed at MT side until invitation +// is received (as MO will send invite automatically). +// ----------------------------------------------------------------------------- +// +MMusAvaObserver::TAvailabilityStatus CMusAvaOptionHandler::HandleFastModeAvailableL( + MMusAvaObserver::TAvailabilityStatus aNewState ) + { + MUS_LOG("mus: [MUSAVA] -> CMusAvaOptionHandler::HandleFastModeAvailableL()" ) + + __ASSERT_ALWAYS( iSettings.Observer(), User::Leave( KErrNotReady ) ); + + if ( State() != MMusAvaObserver::EMusAvaStatusAvailable && + iSettings.FastMode() == MusSettingsKeys::EFastModeOn ) + { + if ( iSettings.CallDirection() == NMusSessionInformationApi::ECallOrginated ) + { + MUS_LOG("mus: [MUSAVA] Starting application at background" ) + iSettings.Observer()->StartApplicationL( MultimediaSharing::EMusTwoWayVideo ); + } + else + { + MUS_LOG("mus: [MUSAVA] Delay availability publishing" ) + iFastModeAvailabilityDelayed = ETrue; + aNewState = State(); + } + } + + MUS_LOG("mus: [MUSAVA] <- CMusAvaOptionHandler::HandleFastModeAvailableL()" ) + + return aNewState; + } + +// ----------------------------------------------------------------------------- +// If fast mode and call terminated side, answering to 200 ok is already enough +// to set us available in delayed manner as other end can start sending +// invitation already after getting fast mode information in answer. +// ----------------------------------------------------------------------------- +// +void CMusAvaOptionHandler::HandleFastModeQueryAnswered() + { + if ( FastModeNegotiatedByAnswerMT() ) + { + MUS_LOG( "mus: [MUSAVA] Set fastmode available already as answered" ) + + // Will result delayed availability handling + DoSetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent ); + } + } + +// ----------------------------------------------------------------------------- +// If options wasn't sent because of missing information, state can be set to +// available immediately as MT cannot start waiting for invite unless it is +// sure that other end is about to send it. +// ----------------------------------------------------------------------------- +// +MMusAvaObserver::TAvailabilityStatus +CMusAvaOptionHandler::HandleFastModeOptionsNotSentL( + MMusAvaObserver::TAvailabilityStatus aNewState ) + { + MUS_LOG("mus: [MUSAVA] -> CMusAvaOptionHandler::HandleFastModeOptionsNotSentL()" ) + + if ( FastModeNegotiatedByAnswerMT() ) + { + MUS_LOG("mus: [MUSAVA] Answered already, set available" ) + // Make available but start waiting for invitation + aNewState = HandleFastModeAvailableL( MMusAvaObserver::EMusAvaStatusAvailable ); + } + + MUS_LOG("mus: [MUSAVA] <- CMusAvaOptionHandler::HandleFastModeOptionsNotSentL()" ) + + return aNewState; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +MMusAvaObserver::TAvailabilityStatus +CMusAvaOptionHandler::HandleFastModeOptionNotAvailableL( + MMusAvaObserver::TAvailabilityStatus aNewState ) + { + MUS_LOG("mus: [MUSAVA] -> CMusAvaOptionHandler::HandleFastModeOptionNotAvailableL()" ) + + if ( iFastModeAvailabilityDelayed || + State() == MMusAvaObserver::EMusAvaStatusAvailable ) + { + MUS_LOG("mus: [MUSAVA] In delayed mode or available, ignore" ) + aNewState = State(); + } + + MUS_LOG("mus: [MUSAVA] <- CMusAvaOptionHandler::HandleFastModeOptionNotAvailableL()" ) + + return aNewState; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TBool CMusAvaOptionHandler::FastModeNegotiatedByAnswerMT() + { + return ( iFastModeCapable && + iCapabilityQueryAnswered && + iSettings.FastMode() == MusSettingsKeys::EFastModeOn && + iSettings.CallDirection() == NMusSessionInformationApi::ECallTerminated ); + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TBool CMusAvaOptionHandler::FastModeNegotiationFailedMO() + { + return ( iFastModeCapable && + iSettings.FastMode() != MusSettingsKeys::EFastModeOn && + iSettings.CallDirection() == NMusSessionInformationApi::ECallOrginated && + State() != MMusAvaObserver::EMusAvaStatusAvailable && + State() != MMusAvaObserver::EMusAvaStatusOptionsSent ); + } + +// End of file