--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/voipplugins/voipadapters/voipxmlprovisioning/voipxmlprocessor/src/voipxmlsiphandler.cpp Wed Sep 01 12:29:57 2010 +0100
@@ -0,0 +1,610 @@
+/*
+* Copyright (c) 2009-2010 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: SIP handler for VoIP XML processor
+*
+*/
+
+
+#include <e32cmn.h>
+#include <coecntrl.h>
+#include <sipmanagedprofile.h>
+#include <sipmanagedprofileregistry.h>
+#include <sysutil.h>
+#include <wlaninternalpskeys.h>
+#include <pathinfo.h>
+#include <authority16.h>
+#include <StringLoader.h>
+#include <escapeutils.h>
+
+#include "voipxmlutils.h"
+#include "voipxmlsiphandler.h"
+#include "voipxmlprocessorlogger.h"
+#include "voipxmlprocessordefaults.h"
+
+// ---------------------------------------------------------------------------
+// CVoipXmlSipHandler::CVoipXmlSipHandler
+// ---------------------------------------------------------------------------
+//
+CVoipXmlSipHandler::CVoipXmlSipHandler()
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CVoipXmlSipHandler::NewL
+// ---------------------------------------------------------------------------
+//
+CVoipXmlSipHandler* CVoipXmlSipHandler::NewL()
+ {
+ CVoipXmlSipHandler* self = new ( ELeave ) CVoipXmlSipHandler;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CVoipXmlSipHandler::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CVoipXmlSipHandler::ConstructL()
+ {
+ DBG_PRINT( "CVoipXmlSipHandler::ConstructL begin" );
+
+ // SIP Managed Profile Registry.
+ iRegistry = CSIPManagedProfileRegistry::NewL( *this );
+
+ // Create an empty SIP profile in which all settings will be set.
+ iProfileType.iSIPProfileClass = TSIPProfileTypeInfo::EInternet;
+ iProfileType.iSIPProfileName.Copy( KIetf() );
+ iProfile = iRegistry->CreateL( iProfileType );
+
+ iProxyUri = HBufC8::NewL( KMaxNodeValueLength );
+ iProxyTransport = EAutomatic;
+ iProxyPort = KErrNotFound;
+ iLr = EFalse;
+ iRegistrarUri = HBufC8::NewL( KMaxNodeValueLength );
+ iRegistrarTransport = EAutomatic;
+ iRegistrarPort = KErrNotFound;
+
+ const TInt ipTosShift( 2 );
+ const TUint32 tosBits( KDefaultSigQos << ipTosShift );
+ iProfile->SetParameter( KSIPSoIpTOS, tosBits );
+
+ DBG_PRINT( "CVoipXmlSipHandler::ConstructL end" );
+ }
+
+// ---------------------------------------------------------------------------
+// CVoipXmlSipHandler::~CVoipXmlSipHandler
+// ---------------------------------------------------------------------------
+//
+CVoipXmlSipHandler::~CVoipXmlSipHandler()
+ {
+ delete iProfile;
+ delete iRegistry;
+ delete iProxyUri;
+ delete iRegistrarUri;
+ }
+
+// ---------------------------------------------------------------------------
+// Sets SIP setting.
+// ---------------------------------------------------------------------------
+//
+void CVoipXmlSipHandler::SetSetting( TInt aType, TInt aParam,
+ const TDesC8& aValue )
+ {
+ // Ignore too long descriptors.
+ if ( KMaxNodeValueLength < aValue.Length() )
+ {
+ return;
+ }
+
+ switch ( aParam )
+ {
+ case EName:
+ {
+ TRAPD( err, CreateProviderNameL( aValue ) );
+ if ( KErrNone == err )
+ {
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case ESignalingQos:
+ {
+ // We need to do bitshifting on the IP TOS, because it's the
+ // upper 6 bits that are set and settings provide us the IP TOS
+ // as the lower 6 bits.
+ // The lower 2 bits are reserver for explicit congestion
+ // notification.
+ // See also more from:
+ // Symbian Developer Library
+ // => in_sock.h Global variables
+ // => KSoIpTOS
+ const TInt ipTosShift( 2 );
+ TInt value( KErrNotFound );
+ // don't need to check return value because 'TInt value' is checked
+ // coverity[check_return] coverity[unchecked_value]
+ VoipXmlUtils::Des8ToInt( aValue, value );
+ if ( 0 <= value )
+ {
+ const TUint32 tosBits( value << ipTosShift );
+ iProfile->SetParameter( KSIPSoIpTOS, tosBits );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case EType:
+ {
+ TBuf8<KMaxNodeValueLength> value;
+ value.Copy( aValue );
+ value.UpperCase();
+ if ( 0 == value.Compare( KIms() ) )
+ {
+ iProfileType.iSIPProfileClass = TSIPProfileTypeInfo::EIms;
+ value.LowerCase();
+ iProfileType.iSIPProfileName.Copy( value );
+ iProfile->SetType( iProfileType );
+ iSettingsSet = ETrue;
+ }
+ else if ( 0 == value.Compare( KIetf() ) )
+ {
+ iProfileType.iSIPProfileClass =
+ TSIPProfileTypeInfo::EInternet;
+ iProfileType.iSIPProfileName.Copy( value );
+ iProfile->SetType( iProfileType );
+ iSettingsSet = ETrue;
+ }
+ else
+ {
+ iProfileType.iSIPProfileClass = TSIPProfileTypeInfo::EOther;
+ iProfileType.iSIPProfileName.Copy( aValue );
+ iProfile->SetType( iProfileType );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case EPublicUserId:
+ {
+ TBuf8<KMaxNodeValueLength> value;
+ value.Copy( aValue );
+ TRAPD( err, ModifyPuidL( value ) );
+ if ( KErrNone == err )
+ {
+ iProfile->SetParameter( KSIPUserAor, value );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case ESignalCompression:
+ {
+ TInt value;
+ if ( KErrNone == VoipXmlUtils::Des8ToInt( aValue, value ) )
+ {
+ iProfile->SetParameter( KSIPSigComp, (TBool)value );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case ESecurityNegotiation:
+ {
+ TInt value;
+ if ( KErrNone == VoipXmlUtils::Des8ToInt( aValue, value ) )
+ {
+ iProfile->SetParameter(
+ KSIPSecurityNegotiation, (TBool)value );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case EProfileLock:
+ {
+ TInt value;
+ if ( KErrNone == VoipXmlUtils::Des8ToInt( aValue, value ) )
+ {
+ iProfile->SetParameter( KSIPProfileLocked, (TBool)value );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case EAutoRegistration:
+ {
+ TInt value;
+ if ( KErrNone == VoipXmlUtils::Des8ToInt( aValue, value ) )
+ {
+ iProfile->SetParameter( KSIPAutoRegistration, (TBool)value );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case EUri:
+ {
+ TBuf8<KMaxNodeValueLength> tempBuf( KNullDesC8 );
+ if ( 0 != aValue.Find( KSip() ) &&
+ 0 != aValue.Find( KSips() ) )
+ {
+ tempBuf.Copy( KSip() );
+ }
+ tempBuf.Append( aValue );
+ //lint -e{960} No need for else statement here
+ if ( EProxy == aType )
+ {
+ iProxyUri->Des().Copy( tempBuf );
+ iSettingsSet = ETrue;
+ }
+ else if ( ERegistrar == aType )
+ {
+ iRegistrarUri->Des().Copy( tempBuf );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case ETransport:
+ {
+ //lint -e{960} No need for else statement here
+ if ( EProxy == aType )
+ {
+ iProxyTransport = ValidateTransport( aValue );
+ iSettingsSet = ETrue;
+ }
+ else if ( ERegistrar == aType )
+ {
+ iRegistrarTransport = ValidateTransport( aValue );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case EPort:
+ {
+ TInt value;
+ TInt err = VoipXmlUtils::Des8ToInt( aValue, value );
+ //lint -e{960} No need for else statement here
+ if ( EProxy == aType && KErrNone == err )
+ {
+ iProxyPort = value;
+ iSettingsSet = ETrue;
+ }
+ else if ( ERegistrar == aType && KErrNone == err )
+ {
+ iRegistrarPort = value;
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case ELooseRouting:
+ {
+ TInt value;
+ if ( EProxy == aType &&
+ KErrNone == VoipXmlUtils::Des8ToInt( aValue, value ) )
+ {
+ iLr = (TBool)value;
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ case EUsername:
+ {
+ //lint -e{960} No need for else statement here
+ if ( EProxy == aType )
+ {
+ if ( TSIPProfileTypeInfo::EInternet ==
+ iProfileType.iSIPProfileClass )
+ {
+ iProfile->SetParameter( KSIPOutboundProxy,
+ KSIPDigestUserName, aValue );
+ iSettingsSet = ETrue;
+ }
+ else
+ {
+ iProfile->SetParameter( KSIPPrivateIdentity, aValue );
+ iSettingsSet = ETrue;
+ }
+ }
+ else if ( ERegistrar == aType )
+ {
+ if ( TSIPProfileTypeInfo::EInternet ==
+ iProfileType.iSIPProfileClass )
+ {
+ iProfile->SetParameter( KSIPRegistrar, KSIPDigestUserName,
+ aValue );
+ iSettingsSet = ETrue;
+ }
+ else
+ {
+ iProfile->SetParameter( KSIPPrivateIdentity, aValue );
+ iSettingsSet = ETrue;
+ }
+ }
+ break;
+ }
+ case EPassword:
+ {
+ //lint -e{960} No need for else statement here
+ if ( EProxy == aType )
+ {
+ iProfile->SetParameter( KSIPOutboundProxy, KSIPDigestPassword,
+ aValue );
+ iSettingsSet = ETrue;
+ }
+ else if ( ERegistrar == aType )
+ {
+ iProfile->SetParameter( KSIPRegistrar, KSIPDigestPassword,
+ aValue );
+ iSettingsSet = ETrue;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Stores settings to SIP managed profile registry.
+// ---------------------------------------------------------------------------
+//
+TInt CVoipXmlSipHandler::StoreSettings()
+ {
+ if ( !iSettingsSet )
+ {
+ // No settings to be stored => method not supported.
+ return KErrNotSupported;
+ }
+
+ TBuf8<KMaxNodeValueLength> tempBuf( KNullDesC8 );
+
+ // ==============================
+ // Set components to proxy URI.
+ // ==============================
+ //
+ if ( KErrNotFound != iProxyPort )
+ {
+ tempBuf.Copy( KColon() );
+ tempBuf.AppendNum( iProxyPort );
+ }
+ //lint -e{960} No need for else statement here
+ if ( EUdp == iProxyTransport )
+ {
+ tempBuf.Append( KTransport() );
+ tempBuf.Append( KUdp() );
+ }
+ else if ( ETcp == iProxyTransport )
+ {
+ tempBuf.Append( KTransport() );
+ tempBuf.Append( KTcp() );
+ }
+ else if ( ETls == iProxyTransport )
+ {
+ tempBuf.Append( KTransport() );
+ tempBuf.Append( KTls() );
+ }
+ if ( iLr )
+ {
+ tempBuf.Append( KLr() );
+ }
+
+ if ( iProxyUri->Des().MaxLength() >=
+ ( iProxyUri->Des().Length() + tempBuf.Length() ) )
+ {
+ iProxyUri->Des().Append( tempBuf );
+ }
+ iProfile->SetParameter( KSIPOutboundProxy, KSIPServerAddress,
+ iProxyUri->Des() );
+
+ // ==============================
+ // Set components to registrar URI.
+ // ==============================
+ //
+ tempBuf.Zero();
+ if ( KErrNotFound != iRegistrarPort )
+ {
+ tempBuf.Copy( KColon() );
+ tempBuf.AppendNum( iRegistrarPort );
+ }
+ //lint -e{960} No need for else statement here
+ if ( EUdp == iRegistrarTransport )
+ {
+ tempBuf.Append( KTransport() );
+ tempBuf.Append( KUdp() );
+ }
+ else if ( ETcp == iRegistrarTransport )
+ {
+ tempBuf.Append( KTransport() );
+ tempBuf.Append( KTcp() );
+ }
+ else if ( ETls == iProxyTransport )
+ {
+ tempBuf.Append( KTransport() );
+ tempBuf.Append( KTls() );
+ }
+ if ( iRegistrarUri->Des().MaxLength() >=
+ ( iRegistrarUri->Des().Length() + tempBuf.Length() ) )
+ {
+ iRegistrarUri->Des().Append( tempBuf );
+ }
+ iProfile->SetParameter( KSIPRegistrar, KSIPServerAddress,
+ iRegistrarUri->Des() );
+
+ TRAPD( err, iRegistry->SaveL( *iProfile ) );
+ if ( KErrNone != err )
+ {
+ // No need for specifying what went wrong because paramhandler
+ // is only intrested in KErrNotSupported, KErrCompletion and KErrNone.
+ err = KErrCompletion;
+ }
+ // Store SIP settings ID for later use.
+ iProfile->GetParameter( KSIPProfileId, iProfileId );
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns the profile ID if the profile saved in StoreSettings.
+// ---------------------------------------------------------------------------
+//
+TUint32 CVoipXmlSipHandler::SettingsId()
+ {
+ return iProfileId;
+ }
+
+// ---------------------------------------------------------------------------
+// Saves linkage information.
+// ---------------------------------------------------------------------------
+//
+void CVoipXmlSipHandler::LinkSettings( TInt aType, TUint32 aSettingsId )
+ {
+ if ( EDestination == aType && aSettingsId )
+ {
+ iProfile->SetParameter( KSIPSnapId, aSettingsId );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Finalizes settings saving.
+// ---------------------------------------------------------------------------
+//
+TInt CVoipXmlSipHandler::FinalizeSettings()
+ {
+ TRAPD( err, iRegistry->SaveL( *iProfile ) );
+ if ( KErrNone != err )
+ {
+ // ParamHandler is only intrested in KErrNone and KErrCompletion.
+ err = KErrCompletion;
+ }
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MSIPProfileRegistryObserver.
+// ---------------------------------------------------------------------------
+//
+void CVoipXmlSipHandler::ProfileRegistryEventOccurred(
+ TUint32 /*aSIPProfileId*/, TEvent /*aEvent*/ )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// From class MSIPProfileRegistryObserver.
+// ---------------------------------------------------------------------------
+//
+void CVoipXmlSipHandler::ProfileRegistryErrorOccurred(
+ TUint32 /*aSIPProfileId*/, TInt /*aError*/ )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CVoipXmlSipHandler::CreateProviderNameL
+// Checks if duplicate named SIP profiles. Renames if same.
+// ---------------------------------------------------------------------------
+//
+void CVoipXmlSipHandler::CreateProviderNameL( const TDesC8& aName )
+ {
+ DBG_PRINT( "CVoipXmlSipHandler::CreateProviderNameL begin" );
+
+ const TInt maxModifyLength =
+ KMaxNodeNameLength - KMaxProfileNameAppendLength;
+
+ RPointerArray<CSIPProfile> profiles;
+ CleanupResetAndDestroyL( profiles ); // CS:1
+
+ // Get all profiles based on profile types.
+ iRegistry->ProfilesL( profiles );
+ const TInt profileCount = profiles.Count();
+
+ // Go through loaded profiles and check for name duplicates.
+ HBufC8* name = HBufC8::NewLC( KMaxNodeNameLength ); // CS:2
+ name->Des().Copy( aName.Left( maxModifyLength ) );
+ TUint i( 1 ); // Add number to the name if name already in use.
+ const TInt count( profiles.Count() );
+ for ( TInt counter = 0; counter < count; counter++ )
+ {
+ CSIPManagedProfile* profile =
+ static_cast<CSIPManagedProfile*>( profiles[counter] );
+ const TDesC8* existingName;
+ profile->GetParameter( KSIPProviderName, existingName );
+ if ( 0 == existingName->Compare( *name ) )
+ {
+ name->Des().Copy( aName.Left( maxModifyLength ) );
+ name->Des().Append( KOpenParenthesis8() );
+ name->Des().AppendNum( i );
+ name->Des().Append( KClosedParenthesis8() );
+ counter = 0;
+ i++;
+ if ( KMaxProfileNames < i )
+ {
+ User::Leave( KErrBadName );
+ }
+ }
+ }
+ iProfile->SetParameter( KSIPProviderName, name->Des() );
+
+ // name, &profiles
+ CleanupStack::PopAndDestroy( 2, &profiles ); // CS:0
+ DBG_PRINT( "CVoipXmlSipHandler::CreateProviderNameL end" );
+ }
+
+// ---------------------------------------------------------------------------
+// Modifies public user ID, i.e. escapes and adds sip: prefix if necessary.
+// ---------------------------------------------------------------------------
+//
+void CVoipXmlSipHandler::ModifyPuidL( TDes8& aValue )
+ {
+ if ( KErrNotFound == aValue.Find( KEscaped() ) )
+ {
+ HBufC8* tempPuid = EscapeUtils::EscapeEncodeL( aValue,
+ EscapeUtils::EEscapeNormal );
+ aValue.Copy( tempPuid->Des() );
+ delete tempPuid;
+ tempPuid = NULL;
+ }
+ if ( 0 != aValue.Find( KSip() ) && 0 != aValue.Find( KSips() ) )
+ {
+ if ( aValue.MaxLength() >= ( aValue.Length() + KSip().Length() ) )
+ {
+ aValue.Insert( 0, KSip() );
+ }
+ else
+ {
+ User::Leave( KErrTooBig );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Validates transport type.
+// ---------------------------------------------------------------------------
+//
+CVoipXmlSipHandler::TTransportType CVoipXmlSipHandler::ValidateTransport(
+ const TDesC8& aValue )
+ {
+ TBuf8<KMaxNodeValueLength> value;
+ value.Copy( aValue );
+ value.UpperCase();
+ if ( 0 == value.Compare( KUdp() ) )
+ {
+ return EUdp;
+ }
+ else if ( 0 == value.Compare( KTcp() ) )
+ {
+ return ETcp;
+ }
+ else if ( 0 == value.Compare( KTls() ) )
+ {
+ return ETls;
+ }
+ else
+ {
+ return EAutomatic;
+ }
+ }
+
+// End of file.