--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmsharing/mmshavailability/src/musavaoptionhandler.cpp Thu Dec 17 08:44:37 2009 +0200
@@ -0,0 +1,539 @@
+/*
+* 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 <escapeutils.h>
+#include <siperr.h>
+#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"
+
+
+_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] <- CMusAvaOptionHandler::ConstructL()" )
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TBool CMusAvaOptionHandler::CapabilityQueryAnswered( TBool aAnswered )
+ {
+ iCapabilityQueryAnswered = aAnswered ? aAnswered : iCapabilityQueryAnswered;
+
+ 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
+ SetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent );
+ }
+ else if ( MusSettingsKeys::ESequential ==
+ MultimediaSharingSettings::CapabilityQuerySettingL()
+ && iSettings.CallDirection() == 2 && !iCapabilitiesRequestAnswered )
+ { // terminated party
+ SetState( 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() )
+ {
+ SetState( MMusAvaObserver::EMusAvaStatusOptionsSent );
+ }
+ else
+ {
+ SetState( 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 )
+ {
+ SetState( MMusAvaObserver::EMusAvaStatusNotExecuted );
+ }
+ // anything other than this should be considered default , means options sent
+ // and was not successful.
+ else
+ {
+ SetState( MMusAvaObserver::EMusAvaOptionNotAvailable );
+ }
+ }
+ else
+ {
+ SetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent );
+ }
+ }
+ else
+ {
+ // option sending not needed
+ SetState( 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::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
+ SetState( MMusAvaObserver::EMusAvaStatusAvailable );
+ }
+ else if ( aSentQuery.Result() == KCapabilityCapabilitiesForbidden )
+ {
+ // query returned with response "403 Forbidden". VS is NOT available
+ SetState( MMusAvaObserver::EMusAvaFailureCode );
+ }
+ else
+ {
+ //query failed. VS is NOT available
+ SetState( 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<KMaxUriLength> sipUri;
+ TBuf<KMaxUriLength> 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()" )
+ }
+