--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/tsrc/testdriver/siptester/src/CTcSIPIMSAuthenticator.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,397 @@
+/*
+* Copyright (c) 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: See class definition below.
+*
+*/
+
+#include "CTcSIPIMSAuthenticator.h"
+#include "SipConstants.h"
+#include "ErrorHandling.h"
+
+#include <commsdat.h>
+#include <CommsDatTypesV1_1.h>
+#include <MetaDatabase.h>
+#include <cdblen.h>
+#include <tconvbase64.h>
+
+
+#ifdef RD_SIP_TESTER
+const TInt KAuthenticationTimeout = 30000000; // 30 seconds
+#endif
+
+CTcSIPIMSAuthenticationParams* CTcSIPIMSAuthenticationParams::NewL()
+ {
+ CTcSIPIMSAuthenticationParams* self =
+ new ( ELeave ) CTcSIPIMSAuthenticationParams();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CTcSIPIMSAuthenticationParams::~CTcSIPIMSAuthenticationParams()
+ {
+ delete iRes;
+ delete iIk;
+ delete iCk;
+ delete iAuts;
+ }
+
+void CTcSIPIMSAuthenticationParams::SetResL( const TDesC8& aRes )
+ {
+ delete iRes;
+ iRes = 0;
+
+ const TInt KBase64EncodedResLength = 20;
+ iRes = EncodeL( aRes, KBase64EncodedResLength );
+ }
+
+void CTcSIPIMSAuthenticationParams::SetIkL( const TDesC8& aIk )
+ {
+ delete iIk;
+ iIk = 0;
+
+ const TInt KBase64EncodedIkLength = 20;
+ iIk = EncodeL( aIk, KBase64EncodedIkLength );
+ }
+
+void CTcSIPIMSAuthenticationParams::SetCkL( const TDesC8& aCk )
+ {
+ delete iCk;
+ iCk = 0;
+
+ const TInt KBase64EncodedCkLength = 20;
+ iCk = EncodeL( aCk, KBase64EncodedCkLength );
+ }
+
+void CTcSIPIMSAuthenticationParams::SetAutsL( const TDesC8& aAuts )
+ {
+ delete iAuts;
+ iAuts = 0;
+
+ const TInt KBase64EncodedAutsLength = 20;
+ iAuts = EncodeL( aAuts, KBase64EncodedAutsLength );
+ }
+
+const TDesC8& CTcSIPIMSAuthenticationParams::Res()
+ {
+ return *iRes;
+ }
+
+const TDesC8& CTcSIPIMSAuthenticationParams::Ik()
+ {
+ return *iIk;
+ }
+
+const TDesC8& CTcSIPIMSAuthenticationParams::Ck()
+ {
+ return *iCk;
+ }
+
+const TDesC8& CTcSIPIMSAuthenticationParams::Auts()
+ {
+ return *iAuts;
+ }
+
+void CTcSIPIMSAuthenticationParams::ConstructL()
+ {
+ iRes = KNullDesC8().AllocL();
+ iIk = KNullDesC8().AllocL();
+ iCk = KNullDesC8().AllocL();
+ iAuts = KNullDesC8().AllocL();
+ }
+
+HBufC8* CTcSIPIMSAuthenticationParams::EncodeL(
+ const TDesC8& aInput,
+ TInt aEncodedMaxLen )
+ {
+ if ( aInput.Length() > 0 )
+ {
+ HBufC8* encoded = HBufC8::NewLC( aEncodedMaxLen );
+ TPtr8 encodedPtr( encoded->Des() );
+ TBase64 encoder;
+ User::LeaveIfError( encoder.Encode( aInput, encodedPtr ) );
+ CleanupStack::Pop( encoded );
+ return encoded;
+ }
+ return KNullDesC8().AllocL();
+ }
+
+
+CTcSIPIMSAuthenticator* CTcSIPIMSAuthenticator::NewL()
+ {
+ CTcSIPIMSAuthenticator* self =
+ new ( ELeave ) CTcSIPIMSAuthenticator();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CTcSIPIMSAuthenticator::~CTcSIPIMSAuthenticator()
+ {
+ Cancel();
+ delete iTimer;
+ delete iAuthenticationResult;
+ #ifdef RD_SIP_TESTER
+ {
+ iPhone.Close();
+ }
+ #endif // RD_SIP_TESTER
+ iEtelServer.Close();
+ }
+
+
+void CTcSIPIMSAuthenticator::RunL()
+ {
+ #ifdef RD_SIP_TESTER
+ {
+ TInt error( iStatus.Int() );
+ switch ( error )
+ {
+ case KErrNone:
+ {
+ iAuthenticationResult->SetIkL( iData.iIK );
+ iAuthenticationResult->SetCkL( iData.iCK );
+ iAuthenticationResult->SetResL( iData.iRES );
+ break;
+ }
+ case -3214:
+ {
+ // Using harcoded value for KErrMMEtelSqnVerificationFailed
+ // to enable building SIP Tester on public SDKs
+ // which do not have file etelmmerr.h.
+ iAuthenticationResult->SetResL( iData.iRES );
+ iAuthenticationResult->SetAutsL( iData.iAUTS );
+ break;
+ }
+ default:
+ {
+ // KErrMMEtelAuthenticateFailed and KErrMMEtelMacVerificationFailed
+ // are handled over here
+ iError = error;
+ break;
+ }
+ }
+ }
+ #endif // RD_SIP_TESTER
+
+ if ( iActiveWait.IsStarted() )
+ {
+ iTimer->Remove( iReceiveTimeout );
+ iActiveWait.AsyncStop();
+ }
+ }
+
+void CTcSIPIMSAuthenticator::DoCancel()
+ {
+ #ifdef RD_SIP_TESTER
+ {
+ iPhone.CancelAsyncRequest( EMobilePhoneIMSAuthenticate );
+ }
+ #endif // RD_SIP_TESTER
+ }
+
+CTcSIPIMSAuthenticationParams& CTcSIPIMSAuthenticator::AuthenticateL(
+ const TDesC8& aNonce )
+ {
+ #ifdef RD_SIP_TESTER
+ {
+ __ASSERT_ALWAYS( !IsActive(), User::Leave( KErrInUse ) );
+
+ CTcSIPIMSAuthenticationParams* tmp =
+ CTcSIPIMSAuthenticationParams::NewL();
+ delete iAuthenticationResult;
+ iAuthenticationResult = tmp;
+
+ SetAuthenticationDataL( aNonce );
+
+ RMobilePhone::TImsAuthenticateDataV5Pckg message =
+ RMobilePhone::TImsAuthenticateDataV5Pckg( iData );
+
+ iPhone.ImsAuthenticate( iStatus, message );
+ SetActive();
+
+ iTimer->Queue( KAuthenticationTimeout, iReceiveTimeout );
+ iActiveWait.Start();
+
+ if ( !iAuthenticationResult )
+ {
+ User::Leave( KErrTimedOut );
+ }
+
+ if ( iError != KErrNone )
+ {
+ TInt err( iError );
+ iError = KErrNone;
+ User::Leave( err );
+ }
+ }
+ #else
+ aNonce.Length(); // Avoid compiler warning
+ User::Leave( KErrNotSupported );
+ #endif // RD_SIP_TESTER
+
+ return *iAuthenticationResult;
+ }
+
+CTcSIPIMSAuthenticator::CTcSIPIMSAuthenticator() :
+ CActive( EPriorityStandard )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+void CTcSIPIMSAuthenticator::ConstructL()
+ {
+ iTimer = CDeltaTimer::NewL( CActive::EPriorityStandard );
+ TCallBack cb( ReceiveTimeout, this );
+ iReceiveTimeout.Set( cb );
+
+ TBuf<KCommsDbSvrMaxFieldLength> tsyModuleName;
+ GetTsyModuleNameL( tsyModuleName );
+ PreparePhoneL( tsyModuleName );
+ }
+
+TInt CTcSIPIMSAuthenticator::ReceiveTimeout( TAny* aSelf )
+ {
+ CTcSIPIMSAuthenticator& self =
+ *reinterpret_cast< CTcSIPIMSAuthenticator* >( aSelf );
+ if( self.iActiveWait.IsStarted() )
+ {
+ self.iActiveWait.AsyncStop();
+ }
+
+ return KErrNone;
+ }
+
+void CTcSIPIMSAuthenticator::GetTsyModuleNameL( TDes& aTsyModuleName ) const
+ {
+ __ASSERT_ALWAYS( aTsyModuleName.MaxSize() >= KCommsDbSvrMaxFieldLength,
+ User::Leave( KErrArgument ) );
+
+ using namespace CommsDat;
+
+ CMDBSession* db = CMDBSession::NewLC( KCDLatestVersion );
+
+ CMDBField<TUint32>* globalSettingField =
+ new ( ELeave ) CMDBField<TUint32>( KCDTIdModemPhoneServicesSMS );
+ CleanupStack::PushL( globalSettingField );
+
+ globalSettingField->SetRecordId( 1 );
+ globalSettingField->LoadL( *db );
+ TUint32 modemId = *globalSettingField;
+
+ CMDBField<TDesC>* tsyField =
+ new ( ELeave ) CMDBField<TDesC>( KCDTIdTsyName );
+ CleanupStack::PushL( tsyField );
+
+ tsyField->SetRecordId( modemId );
+ tsyField->LoadL( *db );
+ aTsyModuleName = *tsyField;
+
+ CleanupStack::PopAndDestroy( 3, db ); // db, tsyField & globalSettingField
+ }
+
+void CTcSIPIMSAuthenticator::PreparePhoneL( const TDes& aTsyModuleName )
+ {
+ #ifdef RD_SIP_TESTER
+ {
+ User::LeaveIfError( iEtelServer.Connect() );
+ User::LeaveIfError( iEtelServer.LoadPhoneModule( aTsyModuleName ) );
+
+ //Get total number of phones supported by all currently loaded TSY modules
+ TInt phoneCount( 0 );
+ User::LeaveIfError( iEtelServer.EnumeratePhones( phoneCount ) );
+
+ RTelServer::TPhoneInfo phoneInfo;
+ TName searchTsyName;
+ TInt phoneIndex( KErrNotFound );
+
+ while ( phoneIndex == KErrNotFound && phoneCount-- > 0 )
+ {
+ //Check whether this phone belongs to the loaded TSY
+ if ( ( iEtelServer.GetTsyName( phoneCount, searchTsyName ) == KErrNone )
+ &&
+ ( searchTsyName.CompareF( aTsyModuleName ) == 0 ) )
+ {
+ phoneIndex = phoneCount;
+ }
+ }
+ if ( phoneIndex == KErrNotFound )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ User::LeaveIfError( iEtelServer.GetPhoneInfo( phoneIndex, phoneInfo ) );
+ User::LeaveIfError( iPhone.Open( iEtelServer, phoneInfo.iName ) );
+
+ RPhone::TStatus phoneStatus;
+ User::LeaveIfError( iPhone.GetStatus( phoneStatus ) );
+
+ //Check whether phone has already been initialised
+ if ( phoneStatus.iMode == RPhone::EModeUnknown )
+ {
+ TInt err = iPhone.Initialise();
+
+ if ( err != KErrNone )
+ {
+ iPhone.Close();
+ User::Leave( err );
+ }
+ }
+ }
+ #else
+ {
+ aTsyModuleName.Length(); // Avoid compiler warning
+ }
+ #endif // RD_SIP_TESTER
+ }
+
+void CTcSIPIMSAuthenticator::SetAuthenticationDataL( const TDesC8& aNonce )
+ {
+ #ifdef RD_SIP_TESTER
+ {
+ iData.iRAND.Zero();
+ iData.iAUTN.Zero();
+ iData.iRES.Zero();
+ iData.iIK.Zero();
+ iData.iCK.Zero();
+ iData.iAUTS.Zero();
+
+ HBufC8* decoded = HBufC8::NewLC( aNonce.Length() );
+ TPtr8 decodedPtr( decoded->Des() );
+
+ TBase64 encoder;
+ User::LeaveIfError( encoder.Decode( aNonce, decodedPtr ) );
+
+ __ASSERT_ALWAYS( decodedPtr.Length() >=
+ ( RMobilePhone::KRandLength + RMobilePhone::KAutnLength ),
+ User::Leave( KErrCorrupt ) );
+
+ TPtrC8 rand = decodedPtr.Left( RMobilePhone::KRandLength );
+ TPtrC8 autn = decodedPtr.Mid( RMobilePhone::KRandLength,
+ RMobilePhone::KAutnLength );
+
+ iData.iRAND.Copy( rand );
+ iData.iAUTN.Copy( autn );
+
+ CleanupStack::PopAndDestroy( decoded );
+ }
+ #else
+ {
+ aNonce.Length(); // Avoid compiler warning
+ }
+ #endif // RD_SIP_TESTER
+ }
+