# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1268401451 -7200 # Node ID 1e1cc61f56c35777c3106472ef841c07a9b13df8 # Parent dd3853b8dc3f5088fa5438af181a20439fa4f32f Revision: 201007 Kit: 201008 diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/rtp/group/rtptest.xml --- a/realtimenetprots/rtp/group/rtptest.xml Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/rtp/group/rtptest.xml Fri Mar 12 15:44:11 2010 +0200 @@ -1,9 +1,9 @@ diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/Data/backup_registration.xml --- a/realtimenetprots/sipfw/Data/backup_registration.xml Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/Data/backup_registration.xml Fri Mar 12 15:44:11 2010 +0200 @@ -1,10 +1,10 @@ diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/ApnManager/inc/sipapnconfigurationhandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/ProfileAgent/ApnManager/inc/sipapnconfigurationhandler.h Fri Mar 12 15:44:11 2010 +0200 @@ -0,0 +1,198 @@ +// Copyright (c) 2007-2009 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: +// Name : sipapnconfigurationhandler.h +// Part of : SIP Profile Server +// implementation +// Version : 1.0 +// + +#ifndef __CSIPAPNCONFIGURATIONHANDLER_H__ +#define __CSIPAPNCONFIGURATIONHANDLER_H__ + +// INCLUDES +#include +#include +#include +#include "sipapnmanager.h" + +// CONSTANTS +const TInt KSecondaryApnMaxRetryCount = 100; + +// FORWARD DECLARATIONS +class CCommsDatabase; +namespace CommsDat + { + class CCDRecordBase; + } + +// CLASS DEFINITION sipapnconfigurationhandler.h +/** + * + */ +class CSIPApnConfigurationHandler : public CActive + { + public: // Constructors and destructor + + enum TSipApnMonitoringState + { + EMonitoringIdle, + EMonitoringConnection, + EMonitoringDatabase + }; + + /** + * Static constructor. + * + * @return An initialized instance of this class. + */ + static CSIPApnConfigurationHandler* NewL( MSIPApnChangeObserver& aObserver, + TUint32 aIapId); + + /** + * Static constructor. + * + * @return An initialized instance of this class. + */ + static CSIPApnConfigurationHandler* NewLC( MSIPApnChangeObserver& aObserver, + TUint32 aIapId); + + /// Destructor + ~CSIPApnConfigurationHandler(); + + public: + + /** + * Change APN of specified IAP. If async change is allowed, change + * may be done later if it was not possible at the moment. Once apn + * is changed, observer is notified about change. + */ + void SetApnL( const TDesC8& aApn, + TBool aUseSecureAuthentication, + TBool aAllowAsync ); + + TBool IsPrimaryApnUsed(); + + TBool HasPendingTasks() const; + + TUint32 HandlerIapId() const; + + TBool IsFailed() const; + + void SetFailed(TBool aIsFailed, TBool aIsFatalFailure ); + + void UpdateApnL( TBool aIsPrimaryApn, const TDesC8& aApn ); + + protected: // From CActive + + void DoCancel(); + void RunL(); + TInt RunError( TInt aError ); + + private: + + TBool IsInUseL( TConnectionInfo& aConnectionInfo ); + + void StartMonitoringConnectionL( TConnectionInfo& aConnectionInfo ); + + void WatchConnectionStatusChange(); + + void WatchDatabaseStatusChangeL( TUint32 aIapId ); + + TBool ApnChangeNeededL( const TDesC8& aApn ); + + TBool ChangeApnIfNotInUseL( TBool aAllowAsync = ETrue ); + + TBool IssueApnChangeL( TUint32 aIapId, + const TDesC8& aApn, + TBool aUseSecureAuthentication, + TBool aAllowAsync = ETrue ); + + void ChangeApnL( const TDesC8& aApn, + TBool aUseSecureAuthentication ); + + TBool ClearProtectedRecord( CommsDat::CCDRecordBase& aRecord ); + + void SetMonitoringState( TSipApnMonitoringState aMonitoringState ); + + TSipApnMonitoringState MonitoringState() const; + + void ConnectionMonitoringCompletedL( TInt aError ); + + void DatabaseMonitoringCompletedL( TInt aError ); + + void SendApnChangedNotificationL( const TDesC8& aApn, TInt aError = KErrNone ); + + TDesC8& PrimaryApn(); + + TDesC8& SecondaryApn(); + + /** + * Reads the APN of specified IAP. + * @param aIapId IAP id + * @return APN or NULL if not found. Ownership is transferred. + */ + HBufC8* ReadCurrentApnL(); + + + private: // Constructors + + /// Constructor + CSIPApnConfigurationHandler( MSIPApnChangeObserver& aObserver, + TUint32 aIapId); + + /// 2nd phase constructor + void ConstructL(); + + private: // Data + + MSIPApnChangeObserver& iObserver; + + TSipApnMonitoringState iMonitoringState; + + RSocketServ iSocketSrv; + + RConnection iConnection; + + TPckgBuf iConnectionInfo; + + TNifProgressBuf iProgress; + + HBufC8* iApnProposal; + + TUint32 iIapId; + + CCommsDatabase* iCommsDatabase; + + TInt iMonitoringRetryCount; + + HBufC8* iCurrentApn; + + TBool iApnUseSecureAuthProposal; + + TBool iIsFailed; + + TBool iIsFatalFailure; + + HBufC8* iPrimaryApn; + HBufC8* iSecondaryApn; + +#ifdef CPPUNIT_TEST + friend class CSIPApnManagerTest; + friend class CSIPApnManager; +#endif + + }; + +#endif // __CSIPAPNCONFIGURATIONHANDLER_H__ + diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/ApnManager/inc/sipapnmanager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/ProfileAgent/ApnManager/inc/sipapnmanager.h Fri Mar 12 15:44:11 2010 +0200 @@ -0,0 +1,101 @@ +// Copyright (c) 2007-2009 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: +// Name : sipapnmanager.h +// Part of : SIP Profile Server +// implementation +// Version : 1.0 +// + + +#ifndef CSIPAPNMANAGER_H +#define CSIPAPNMANAGER_H + +// INCLUDES +#include + +// FORWARD DECLARATIONS +class CSIPApnConfigurationHandler; + +// OBSERVER +class MSIPApnChangeObserver + { +public: + /** + * Called when apn change completed successfully or failed so fatally + * that there's no change expected any further on that IAPId. + */ + virtual void ApnChanged( const TDesC8& aApn, TUint32 aIapId, TInt aError ) = 0; + }; + +// CLASS DEFINITION +/** + * + */ +class CSIPApnManager : public CBase + { + public: // Constructors and destructor + + static CSIPApnManager* NewL( MSIPApnChangeObserver& aObserver ); + + ~CSIPApnManager(); + + public: // New methods + + // Update the cached primary or secondary APN + void UpdateApnL( TUint32 aIapId, TBool aIsPrimaryApn, const TDesC8& aApn ); + + TBool IsFailed( TUint32 aIapId ); + void SetFailed( TUint32 aIapId ,TBool aIsFailed, TBool aIsFatalFailure ); + + TBool IsPrimaryApnInUse( TUint32 aIapId ); + + void WriteApnL( TUint32 aIapId, TBool aIsPrimaryApn, const TDesC8* aApn ); + + TBool HasPendingTasks() const; + + /* + * Checks whether the IAPId is ModemBearer + */ + TBool IsIapGPRSL( TUint32 aIapId ); + + private: // Constructors + + CSIPApnManager( MSIPApnChangeObserver& aObserver ); + + void ConstructL(); + + private: + + CSIPApnConfigurationHandler* FindIapIdHandler( TUint32 aIapId ); + + void SetApnL( const TDesC8& aApn, + TBool aUseSecureAuthentication, + TBool aAllowAsync, + TUint32 aIapId); + + void CreateHandlerL( TUint32 aIapId ); + + private: // Data + + MSIPApnChangeObserver& iObserver; + RPointerArray iHandlers; + TBool iInitialApnChangeFailed; + +#ifdef CPPUNIT_TEST + friend class CSIPApnManagerTest; +#endif + + }; + +#endif // CSIPAPNMANAGER_H diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/ApnManager/src/sipapnconfigurationhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/ProfileAgent/ApnManager/src/sipapnconfigurationhandler.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -0,0 +1,903 @@ +// Copyright (c) 2007-2009 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: +// Name : sipapnconfigurationhandler.cpp +// Part of : SIP Profile Server +// implementation +// Version : 1.0 +// +#include +#include +#include +#include "sipapnconfigurationhandler.h" +#include "SipProfileLog.h" + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::NewL +// ----------------------------------------------------------------------------- +// +CSIPApnConfigurationHandler* CSIPApnConfigurationHandler::NewL( + MSIPApnChangeObserver& aObserver, TUint32 aIapId) + { + CSIPApnConfigurationHandler* self = + CSIPApnConfigurationHandler::NewLC( aObserver, aIapId ); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::NewLC +// ----------------------------------------------------------------------------- +// +CSIPApnConfigurationHandler* CSIPApnConfigurationHandler::NewLC( + MSIPApnChangeObserver& aObserver, TUint32 aIapId) + { + CSIPApnConfigurationHandler* self = + new ( ELeave ) CSIPApnConfigurationHandler( aObserver, aIapId ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::~CSIPApnConfigurationHandler +// ----------------------------------------------------------------------------- +// +CSIPApnConfigurationHandler::~CSIPApnConfigurationHandler() + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::~CSIPApnConfigurationHandler()" ) + + Cancel(); + iConnection.Close(); + iSocketSrv.Close(); + + delete iApnProposal; + delete iCurrentApn; + + delete iPrimaryApn; + delete iSecondaryApn; + + delete iCommsDatabase; + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::~CSIPApnConfigurationHandler() exit" ) + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::SetApnL +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::SetApnL( + const TDesC8& aApn, + TBool aUseSecureAuthentication, + TBool aAllowAsync ) + { + PROFILE_DEBUG6( + "CSIPApnConfigurationHandler::SetApnL() apn", aApn ) + + // Cancel if waiting for connection closure, will be re-issued if needed + Cancel(); + + // Store current apn setting + HBufC8* apn = aApn.AllocL(); + delete iApnProposal; + iApnProposal = apn; + iApnUseSecureAuthProposal = aUseSecureAuthentication; + + if ( !ApnChangeNeededL( *iApnProposal ) ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::SetApnL() apn already correct" ) + + SendApnChangedNotificationL( *iApnProposal ); + return; + } + + iMonitoringRetryCount = 0; + + ChangeApnIfNotInUseL( aAllowAsync ); + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::SetApnL() exit" ) + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::IsPrimaryApnUsed +// ----------------------------------------------------------------------------- +// +TBool CSIPApnConfigurationHandler::IsPrimaryApnUsed() + { + return ( iCurrentApn && iCurrentApn->Compare( PrimaryApn() ) == 0 ); + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::ReadCurrentApnL +// ----------------------------------------------------------------------------- +// +HBufC8* CSIPApnConfigurationHandler::ReadCurrentApnL() + { + HBufC8* apn(NULL); + + using namespace CommsDat; + + CMDBSession* db = CMDBSession::NewL( CMDBSession::LatestVersion() ); + CleanupStack::PushL( db ); + // Set any attributes if any + db->SetAttributeMask( ECDHidden ); + + // Create an iap record + CCDIAPRecord* iapRecord = + static_cast( + CCDRecordBase::RecordFactoryL( KCDTIdIAPRecord ) ); + CleanupStack::PushL( iapRecord ); + + iapRecord->SetRecordId( iIapId ); + + iapRecord->LoadL( *db ); + + // serviceType identifies the servicing table to use + CMDBField* serviceType = + ( CMDBField* )iapRecord->GetFieldByIdL( KCDTIdIAPServiceType ); + + __ASSERT_ALWAYS( serviceType && !serviceType->IsNull(), + User::Leave( KErrNotFound ) ); + // Only this service type has APN in the service record + if ( TPtrC( KCDTypeNameOutgoingWCDMA ).Compare( *serviceType ) == 0 ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ReadCurrentApnL(), wcdma service" ) + + // iapRecord->iService field is a link to the servicing table. It tells + // which record to use from the table. + iapRecord->iService.LoadL( *db ); + + if ( !iapRecord->iService.iLinkedRecord ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ReadCurrentApnL(), creating linked" ) + + // Ownership of created record is transferred + iapRecord->iService.iLinkedRecord = + static_cast( + CCDRecordBase::RecordFactoryL( KCDTIdOutgoingGprsRecord ) ); + iapRecord->iService.iLinkedRecord->SetRecordId( iapRecord->iService ); + + iapRecord->iService.iLinkedRecord->LoadL( *db ); + } + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ReadCurrentApnL(), linked service loaded" ) + + CCDOutgoingGprsRecord* serviceRecord = + static_cast( iapRecord->iService.iLinkedRecord ); + + TDesC& currApn = serviceRecord->iGPRSAPN.GetL(); + PROFILE_DEBUG6( + "CSIPApnConfigurationHandler::ReadCurrentApnL(), current apn", + currApn ); + + apn = HBufC8::NewL( currApn.Length() ); + apn->Des().Copy( currApn ); + + delete iCurrentApn; + iCurrentApn = NULL; + iCurrentApn = apn->AllocL(); + } + + db->ClearAttributeMask( ECDHidden ); + + CleanupStack::PopAndDestroy( iapRecord ); + CleanupStack::PopAndDestroy( db ); + + return apn; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::HasPendingTasks +// ----------------------------------------------------------------------------- +// +TBool CSIPApnConfigurationHandler::HasPendingTasks() const + { + return MonitoringState() != EMonitoringIdle; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::DoCancel +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::DoCancel() + { + TSipApnMonitoringState currentState = MonitoringState(); + + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::DoCancel() state", currentState ); + + if ( currentState == EMonitoringConnection ) + { + iConnection.CancelProgressNotification(); + } + else if ( currentState == EMonitoringDatabase ) + { + if ( iCommsDatabase ) + { + iCommsDatabase->CancelRequestNotification(); + } + } + else + { + // NOP + } + + SetMonitoringState( EMonitoringIdle ); + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::DoCancel() exit" ) + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::RunL +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::RunL() + { + TInt error = iStatus.Int(); + + TSipApnMonitoringState currentState = MonitoringState(); + + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::RunL() err", error ); + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::RunL() state", currentState ); + + SetMonitoringState( EMonitoringIdle ); // Clear current state + + if ( currentState == EMonitoringConnection ) + { + ConnectionMonitoringCompletedL( error ); + } + else if ( currentState == EMonitoringDatabase ) + { + DatabaseMonitoringCompletedL( error ); + } + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::RunL() exit" ) + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::RunError +// ----------------------------------------------------------------------------- +// +TInt CSIPApnConfigurationHandler::RunError( TInt aError ) + { + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::RunError() err", aError ); + + if ( aError != KErrNoMemory && aError != KErrNone ) + { + iObserver.ApnChanged( *iApnProposal, iIapId, aError ); + aError = KErrNone; + } + + return aError; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::CSIPApnConfigurationHandler +// ----------------------------------------------------------------------------- +// +CSIPApnConfigurationHandler::CSIPApnConfigurationHandler( + MSIPApnChangeObserver& aObserver, TUint32 aIapId ) : + CActive( CActive::EPriorityStandard ), + iObserver( aObserver ), + iMonitoringState( EMonitoringIdle ) + { + CActiveScheduler::Add( this ); + iIapId = aIapId; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::ConstructL +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::ConstructL() + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ConstructL()" ) + + User::LeaveIfError( iSocketSrv.Connect() ); + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ConstructL() exit" ) + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::IsInUseL +// ----------------------------------------------------------------------------- +// +TBool CSIPApnConfigurationHandler::IsInUseL( TConnectionInfo& aConnectionInfo ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::IsInUseL()" ) + + TBool inUse( EFalse ); + RConnection rcon; + User::LeaveIfError( rcon.Open( iSocketSrv ) ); + CleanupClosePushL( rcon ); + + TUint activeCount( 0 ); + User::LeaveIfError( rcon.EnumerateConnections( activeCount ) ); + + if ( activeCount > 0 ) + { + // Indexing is unordinary + for( TUint i = 1; i <= activeCount && !inUse; i++ ) + { + TPckgBuf connectionInfo; + User::LeaveIfError( rcon.GetConnectionInfo( i, connectionInfo ) ); + + if ( connectionInfo().iIapId == iIapId ) + { + inUse = ETrue; + aConnectionInfo = connectionInfo(); + } + } + } + + CleanupStack::PopAndDestroy( &rcon ); + + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::IsInUseL() inuse", inUse ) + + return inUse; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::StartMonitoringConnectionL +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::StartMonitoringConnectionL( + TConnectionInfo& aConnectionInfo ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::StartMonitoringConnectionL()" ) + + __ASSERT_ALWAYS( !IsActive(), User::Leave( KErrInUse ) ); + + if ( iConnection.SubSessionHandle() ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler:: close existing connection" ) + + iConnection.Close(); + } + + iConnectionInfo = aConnectionInfo; + + User::LeaveIfError( iConnection.Open( iSocketSrv ) ); + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler:: attaching" ) + + User::LeaveIfError( + iConnection.Attach( iConnectionInfo, RConnection::EAttachTypeMonitor ) ); + + WatchConnectionStatusChange(); + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::StartMonitoringConnectionL() exit" ) + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::WatchConnectionStatusChange +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::WatchConnectionStatusChange() + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::WatchConnectionStatusChange()" ) + + Cancel(); + + iConnection.ProgressNotification( iProgress, iStatus, KConnectionClosed ); + SetActive(); + + SetMonitoringState( EMonitoringConnection ); + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::WatchConnectionStatusChange(), exit" ) + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::WatchDatabaseStatusChangeL +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::WatchDatabaseStatusChangeL( TUint32 aIapId ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::WatchDatabaseStatusChangeL()" ) + + Cancel(); + + if ( !iCommsDatabase ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler:: create commsdb" ) + iCommsDatabase = CCommsDatabase::NewL(); + } + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler:: request notification" ) + + // Start monitoring for db events, there will be lots of them pouring in + // as there's no filtering feature. We are interested only in + // unlocked events. + User::LeaveIfError( iCommsDatabase->RequestNotification( iStatus ) ); + + SetActive(); + + iIapId = aIapId; + + SetMonitoringState( EMonitoringDatabase ); + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::WatchDatabaseStatusChangeL(), exit" ) + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::ApnChangeNeededL +// ----------------------------------------------------------------------------- +// +TBool CSIPApnConfigurationHandler::ApnChangeNeededL( const TDesC8& aApn ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ApnChangeNeededL()" ) + + TBool apnChangeNeeded( EFalse ); + HBufC8* currentApn = ReadCurrentApnL(); + + if ( currentApn && currentApn->Compare( aApn ) != 0 ) + { + // Apn is not the same as wanted + apnChangeNeeded = ETrue; + } + + delete currentApn; + + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::ApnChangeNeededL(), apnChangeNeeded", + apnChangeNeeded ) + return apnChangeNeeded; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::ChangeApnIfNotInUseL +// ----------------------------------------------------------------------------- +// +TBool CSIPApnConfigurationHandler::ChangeApnIfNotInUseL( TBool aAllowAsync ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ChangeApnIfNotInUseL()" ) + + TBool apnChanged( EFalse ); + + TConnectionInfo connectionInfo; + if ( IsInUseL( connectionInfo ) ) + { + // If iap is in use, apn cannot be changed until everyone has stopped + // using it + __ASSERT_ALWAYS( aAllowAsync, User::Leave( KErrInUse ) ); + + StartMonitoringConnectionL( connectionInfo ); + } + else + { + apnChanged = IssueApnChangeL( + iIapId, *iApnProposal, iApnUseSecureAuthProposal, aAllowAsync ); + } + + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::ChangeApnIfNotInUseL(), apnChanged", + apnChanged ) + return apnChanged; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::IssueApnChangeL +// ----------------------------------------------------------------------------- +// +TBool CSIPApnConfigurationHandler::IssueApnChangeL( + TUint32 aIapId, + const TDesC8& aApn, + TBool aUseSecureAuthentication, + TBool aAllowAsync ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::IssueApnChangeL()" ) + + TBool apnChanged( EFalse ); + if(aIapId == iIapId) + { + TRAPD( err, ChangeApnL( aApn, aUseSecureAuthentication ) ); + if ( err == KErrLocked || err == KErrAccessDenied ) + { + // Database transaction lock may cause errors if some other client is + // accessing the same record at the same time. In such case, start + // monitoring for database events and retry apn changing at each + // unlock/rollback event. + + __ASSERT_ALWAYS( aAllowAsync, User::Leave( KErrInUse ) ); + + WatchDatabaseStatusChangeL( iIapId ); + } + else + { + User::LeaveIfError( err ); + apnChanged = ETrue; + } + } + + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::IssueApnChangeL(), apnChanged", + apnChanged ) + return apnChanged; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::ChangeApnL +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::ChangeApnL( + const TDesC8& aApn, + TBool aUseSecureAuthentication ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ChangeApnL()" ) + + using namespace CommsDat; + + CMDBSession* db = CMDBSession::NewL( CMDBSession::LatestVersion() ); + CleanupStack::PushL( db ); + // Set attributes so that also protected iaps can be accessed + db->SetAttributeMask( ECDHidden | ECDProtectedWrite ); + + // Create an iap record + CCDIAPRecord* iapRecord = + static_cast( + CCDRecordBase::RecordFactoryL( KCDTIdIAPRecord ) ); + CleanupStack::PushL( iapRecord ); + + iapRecord->SetRecordId( iIapId ); + + TBool clearedProtectedIap = ClearProtectedRecord( *iapRecord ); + + iapRecord->LoadL( *db ); + + iapRecord->iService.LoadL( *db ); + + if ( !iapRecord->iService.iLinkedRecord ) + { + // Ownership of created record is transferred + iapRecord->iService.iLinkedRecord = + static_cast( + CCDRecordBase::RecordFactoryL( KCDTIdOutgoingGprsRecord ) ); + + iapRecord->iService.iLinkedRecord->SetRecordId( iapRecord->iService ); + iapRecord->iService.iLinkedRecord->LoadL( *db ); + } + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ChangeApnL linked service loaded" ) + + CCDOutgoingGprsRecord* serviceRecord = + static_cast( iapRecord->iService.iLinkedRecord ); + + TBool clearedProtectedService = ClearProtectedRecord( *serviceRecord ); + + PROFILE_DEBUG6( + "CSIPApnConfigurationHandler::ChangeApnL() curr apn", + serviceRecord->iGPRSAPN.GetL() ); + + HBufC* apn = HBufC::NewLC( aApn.Length() ); + apn->Des().Copy( aApn ); + serviceRecord->iGPRSAPN.SetL( *apn ); + CleanupStack::PopAndDestroy( apn ); + + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::ChangeApnL() curr security", + serviceRecord->iGPRSDisablePlainTextAuth ); + + // Set CHAP/PAP (CHAP is enabled if plain text auth is disabled) + serviceRecord->iGPRSDisablePlainTextAuth = aUseSecureAuthentication; + + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::ChangeApnL() new security", + aUseSecureAuthentication ) + + serviceRecord->ModifyL( *db ); + + if ( clearedProtectedIap ) + { + // Set protection back + iapRecord->SetAttributes( ECDProtectedWrite ); + iapRecord->ModifyL( *db ); + } + + if ( clearedProtectedService ) + { + // Set protection back + serviceRecord->SetAttributes( ECDProtectedWrite ); + serviceRecord->ModifyL( *db ); + } + + db->ClearAttributeMask( ECDHidden | ECDProtectedWrite ); + + CleanupStack::PopAndDestroy( iapRecord ); + CleanupStack::PopAndDestroy( db ); + + SendApnChangedNotificationL( aApn ); + + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::ChangeApnL(), exit" ) + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::ClearProtectedRecord +// ----------------------------------------------------------------------------- +// +TBool CSIPApnConfigurationHandler::ClearProtectedRecord( + CommsDat::CCDRecordBase& aRecord ) + { + TBool cleared( EFalse ); + if ( aRecord.IsSetAttribute( CommsDat::ECDProtectedWrite ) ) + { + aRecord.ClearAttributes( CommsDat::ECDProtectedWrite ); + cleared = ETrue; + } + return cleared; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::SetMonitoringState +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::SetMonitoringState( + TSipApnMonitoringState aMonitoringState ) + { + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::SetMonitoringState, state", + aMonitoringState ); + iMonitoringState = aMonitoringState; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::MonitoringState +// ----------------------------------------------------------------------------- +// +CSIPApnConfigurationHandler::TSipApnMonitoringState + CSIPApnConfigurationHandler::MonitoringState() const + { + return iMonitoringState; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::ConnectionMonitoringCompletedL +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::ConnectionMonitoringCompletedL( TInt aError ) + { + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler:: progress.err", + iProgress().iError ); + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler:: progress.stage", + iProgress().iStage ); + + if ( !aError ) + { + if ( iProgress().iStage == KConnectionClosed || + iProgress().iStage == KLinkLayerClosed || + iProgress().iStage == KConnectionFailure ) + { + // Changing is now possible + IssueApnChangeL( + iConnectionInfo().iIapId, *iApnProposal, iApnUseSecureAuthProposal ); + } + else if ( !iProgress().iError ) + { + // Changing not yet possible. Request further notifications + // from RConnection only if possible + WatchConnectionStatusChange(); + } + } + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::DatabaseMonitoringCompletedL +// Only interested about unlock and rollback events. When such occur, it might +// be possible that other client has released transaction lock and we can +// finally modify apn. Note: cancelling notifications may complete with +// KErrCancel, in that case we don't want to reissue notifications. +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::DatabaseMonitoringCompletedL( TInt aError ) + { + TBool apnChanged( EFalse ); + if ( aError == KErrCancel ) + { + return; + } + + if ( aError == RDbNotifier::EUnlock || + aError == RDbNotifier::ERollback || + aError == RDbNotifier::EClose ) + { + // Changing may be now possible, if not, db notifications or connection + // monitoring is re-enabled inside following method + apnChanged = ChangeApnIfNotInUseL(); + } + else + { + WatchDatabaseStatusChangeL( iIapId ); + } + + // Have some safety limit for monitoring as it's not guaranteed that + // db lock is ever released -> avoid unnecessary battery consumption + if ( !apnChanged ) + { + iMonitoringRetryCount++; + PROFILE_DEBUG3( + "DatabaseMonitoringCompletedL:: retrycount", + iMonitoringRetryCount ); + + if ( iMonitoringRetryCount > KSecondaryApnMaxRetryCount ) + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler:: max retries reached!" ) + Cancel(); + + User::Leave( KErrAbort ); + } + } + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::SendApnChangedNotificationL +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::SendApnChangedNotificationL( + const TDesC8& aNewApn, + TInt aError ) + { + if ( !IsPrimaryApnUsed() ) + { + HBufC8* currentApn = aNewApn.AllocL(); + delete iCurrentApn; + iCurrentApn = NULL; + iCurrentApn = currentApn; + + iObserver.ApnChanged( *iCurrentApn, iIapId, aError ); + } + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::IsFailed +// ----------------------------------------------------------------------------- +// +TBool CSIPApnConfigurationHandler::IsFailed() const + { + return iIsFailed; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::IsFailed +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::SetFailed( TBool aIsFailed, TBool aIsFatalFailure ) + { + PROFILE_DEBUG4( + "CSIPApnConfigurationHandler::SetFailed() (failed, fatal)", + aIsFailed, aIsFatalFailure ) + PROFILE_DEBUG4( + "CSIPApnConfigurationHandler::SetFailed() (curr failed, curr fatal)", + iIsFailed, iIsFatalFailure ) + + if ( iIsFailed != aIsFailed ) + { + TInt err( KErrNone ); + if ( aIsFailed ) + { + TRAP( err, SetApnL( + SecondaryApn(), ETrue, ETrue) ); + } + else if ( !iIsFatalFailure ) + { + TRAP( err, SetApnL( + PrimaryApn(), EFalse, ETrue) ); + } + else + { + PROFILE_DEBUG1( + "CSIPApnConfigurationHandler::SetFailed(), ignored" ) + + // State change is ignored as state change to "not-failed" was + // attempted while fatal error had occured earlier + aIsFailed = iIsFailed; + aIsFatalFailure = iIsFatalFailure; + } + + if ( err ) + { + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::SetFailed(), Setting apn failed, err", err ) + } + } + + iIsFailed = aIsFailed; + iIsFatalFailure = aIsFatalFailure; + } + +// ---------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::PrimaryApn +// ---------------------------------------------------------------------------- +// +TDesC8& CSIPApnConfigurationHandler::PrimaryApn() + { + return *iPrimaryApn; + } + +// ---------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::SecondaryApn +// ---------------------------------------------------------------------------- +// +TDesC8& CSIPApnConfigurationHandler::SecondaryApn() + { + return *iSecondaryApn; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::HandlerIapId +// ----------------------------------------------------------------------------- +// +TUint32 CSIPApnConfigurationHandler::HandlerIapId() const + { + return iIapId; + } + +// ----------------------------------------------------------------------------- +// CSIPApnConfigurationHandler::UpdateApnL +// ----------------------------------------------------------------------------- +// +void CSIPApnConfigurationHandler::UpdateApnL( TBool aIsPrimaryApn, const TDesC8& aApn ) + { +PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::UpdateApnL isPrimary", aIsPrimaryApn ) + PROFILE_DEBUG6( + "CSIPApnConfigurationHandler::UpdateApnL apn", aApn ) + + HBufC8* newApn = aApn.AllocL(); + if ( aIsPrimaryApn ) + { + delete iPrimaryApn; + iPrimaryApn = newApn; + } + else + { + delete iSecondaryApn; + iSecondaryApn = newApn; + } + } + +// End of file diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/ApnManager/src/sipapnmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/ProfileAgent/ApnManager/src/sipapnmanager.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -0,0 +1,244 @@ +// Copyright (c) 2007-2009 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: +// Name : sipapnmanager.cpp +// Part of : SIP Profile Server +// implementation +// Version : 1.0 +// + +#include +#include +#include +#include +#include "sipapnmanager.h" +#include "SipProfileLog.h" +#include "sipapnconfigurationhandler.h" + +// ============================ MEMBER FUNCTIONS ============================== + +// ---------------------------------------------------------------------------- +// CSIPApnManager::NewL +// ---------------------------------------------------------------------------- +// +CSIPApnManager* CSIPApnManager::NewL( + MSIPApnChangeObserver& aObserver ) + { + CSIPApnManager* self = new (ELeave) CSIPApnManager( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::~CSIPApnManager +// ---------------------------------------------------------------------------- +// +CSIPApnManager::~CSIPApnManager() + { + iHandlers.ResetAndDestroy(); + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::UpdateApnL +// ---------------------------------------------------------------------------- +// +void CSIPApnManager::UpdateApnL( TUint32 aIapId, TBool aIsPrimaryApn, const TDesC8& aApn ) + { + CSIPApnConfigurationHandler* handler = FindIapIdHandler( aIapId ); + if (!handler) + { + CreateHandlerL(aIapId); + handler = FindIapIdHandler(aIapId); + } + + PROFILE_DEBUG1("CSIPApnManager::UpdateApnL(), handler exists") + handler->UpdateApnL( aIsPrimaryApn, aApn); + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::IsFailed +// ---------------------------------------------------------------------------- +// +TBool CSIPApnManager::IsFailed( TUint32 aIapId ) + { + CSIPApnConfigurationHandler* handler = FindIapIdHandler( aIapId ); + return (handler && handler->IsFailed()); + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::SetFailed +// Setting back to "not-failed" state is allowed only if fatal failure has not +// occured. +// ---------------------------------------------------------------------------- +// +void CSIPApnManager::SetFailed( TUint32 aIapId ,TBool aIsFailed, TBool aIsFatalFailure ) + { + CSIPApnConfigurationHandler* handler = FindIapIdHandler( aIapId ); + if(handler) + { + handler->SetFailed( aIsFailed, aIsFatalFailure ); + } + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::IsPrimaryApnInUse +// ---------------------------------------------------------------------------- +// +TBool CSIPApnManager::IsPrimaryApnInUse( TUint32 aIapId ) + { + CSIPApnConfigurationHandler* handler = FindIapIdHandler( aIapId ); + return ( handler && handler->IsPrimaryApnUsed() ); + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::WriteApnL +// ---------------------------------------------------------------------------- +// +void CSIPApnManager::WriteApnL( TUint32 aIapId, TBool aIsPrimaryApn, const TDesC8* aApn ) + { + PROFILE_DEBUG3( "CSIPApnManager::WriteApnL isPrimary", aIsPrimaryApn ) + TBool useSecureAuth = aIsPrimaryApn ? EFalse : ETrue; + + CSIPApnConfigurationHandler* handler = FindIapIdHandler( aIapId ); + if (!handler) + { + CreateHandlerL(aIapId); + handler = FindIapIdHandler(aIapId); + } + + handler->SetApnL( *aApn, useSecureAuth, ETrue); + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::HasPendingTasks +// ---------------------------------------------------------------------------- +// +TBool CSIPApnManager::HasPendingTasks() const + { + TInt count = iHandlers.Count(); + PROFILE_DEBUG3( + "CSIPApnManager::HasPendingTasks handler count", count ) + + for ( TInt i = 0; i < count; ++i ) + { + if ( iHandlers[ i ]->HasPendingTasks() ) + { + PROFILE_DEBUG1( + "CSIPApnManager::HasPendingTasks return ETrue" ) + return ETrue; + } + } + PROFILE_DEBUG1( + "CSIPApnManager::HasPendingTasks return EFalse" ) + return EFalse; + } +// ---------------------------------------------------------------------------- +// CSIPApnManager::CSIPApnManager +// ---------------------------------------------------------------------------- +// +CSIPApnManager::CSIPApnManager( MSIPApnChangeObserver& aObserver ) : + iObserver( aObserver ) + { + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::ConstructL +// Read APNs from settings file but don't write to CommsDat yet. If IMS profile +// has APNs, use them instead. APN is written to CommsDat when the operation +// (register, deregister, update..) that caused IMS agent to be loaded, starts +// (CSIPIMSProfileAgent::SelectInitialApnL). +// ---------------------------------------------------------------------------- +// +void CSIPApnManager::ConstructL() + { + PROFILE_DEBUG1("CSIPApnManager::ConstructL()" ) + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::FindIapIdHandler +// ---------------------------------------------------------------------------- +// +CSIPApnConfigurationHandler* CSIPApnManager::FindIapIdHandler( TUint32 aIapId ) + { + CSIPApnConfigurationHandler* handler = NULL; + TBool found(EFalse); + + for(TInt i =0; iHandlerIapId()== aIapId) + { + PROFILE_DEBUG3("CSIPApnManager::FindIapIdHandler, found handler for aIapId", aIapId ) + found = ETrue; + handler = iHandlers[ i ]; + } + } + + return handler; + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::CreateHandlerL +// ---------------------------------------------------------------------------- +// +void CSIPApnManager::CreateHandlerL( TUint32 aIapId ) + { + PROFILE_DEBUG1( + "CSIPApnManager::CreateHandlerL , enter" ) + PROFILE_DEBUG3( + "CSIPApnManager::CreateHandlerL for IapId", aIapId ) + + CSIPApnConfigurationHandler* Handler = + CSIPApnConfigurationHandler::NewL( iObserver, aIapId); + CleanupStack::PushL( Handler ); + iHandlers.AppendL( Handler ); + CleanupStack::Pop( Handler ); + PROFILE_DEBUG1( + "CSIPApnManager::CreateHandlerL, exit" ) + } + +// ---------------------------------------------------------------------------- +// CSIPApnManager::IsIapGPRSL +// ---------------------------------------------------------------------------- +// +TBool CSIPApnManager::IsIapGPRSL( TUint32 aIapId ) + { + TBool isIapGPRS(EFalse); + using namespace CommsDat; + CMDBSession* db = CMDBSession::NewL( CMDBSession::LatestVersion() ); + CleanupStack::PushL( db ); + // Set any attributes if any + db->SetAttributeMask( ECDHidden ); + // Create an iap record + CCDIAPRecord* iapRecord = + static_cast( + CCDRecordBase::RecordFactoryL( KCDTIdIAPRecord ) ); + CleanupStack::PushL( iapRecord ); + iapRecord->SetRecordId( aIapId ); + iapRecord->LoadL( *db ); + TPtrC bearerType(iapRecord->iBearerType); + if(bearerType.CompareF(TPtrC(KCDTypeNameModemBearer)) == 0) + { + isIapGPRS = ETrue; + } + + db->ClearAttributeMask( ECDHidden ); + + CleanupStack::PopAndDestroy( iapRecord ); + CleanupStack::PopAndDestroy( db ); + PROFILE_DEBUG3( + "CSIPApnConfigurationHandler::IsIapGPRSL(),isIapGPRS", isIapGPRS ) + return isIapGPRS; + } +// End of File diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Client/Api/sipprofile.h --- a/realtimenetprots/sipfw/ProfileAgent/Client/Api/sipprofile.h Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Client/Api/sipprofile.h Fri Mar 12 15:44:11 2010 +0200 @@ -185,6 +185,17 @@ */ const TUint32 KSIPServerAddress = 152; +/** +* PrimaryAPN is of type TDesC8 +*/ +const TUint32 KPrimaryAPN = 20; + +/** +* SecondaryAPN is of type TDesC8 +*/ +const TUint32 KSecondaryAPN = 21; + + // CLASS DECLARATION /** * @publishedAll diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Client/Src/sipmanagedprofile.cpp --- a/realtimenetprots/sipfw/ProfileAgent/Client/Src/sipmanagedprofile.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Client/Src/sipmanagedprofile.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -224,6 +224,8 @@ case KSIPDigestPassword: case KSIPHeaders: case KSIPContactHeaderUser: + case KPrimaryAPN: + case KSecondaryAPN: User::Leave(KErrNotFound); case KSIPSnapId: __ASSERT_ALWAYS((aVal>0),User::Leave(KErrArgument)); @@ -272,6 +274,8 @@ case KSIPContactHeaderUser: case KSIPSoIpTOS: case KSIPSnapId: + case KPrimaryAPN: + case KSecondaryAPN: User::Leave(KErrNotFound); default: iSIPProfile->SetExtensionParameterL(aParam, aVal); @@ -313,6 +317,8 @@ case KSIPContactHeaderUser: case KSIPSoIpTOS: case KSIPSnapId: + case KPrimaryAPN: + case KSecondaryAPN: User::Leave(KErrNotFound); default: TBuf8 buf; @@ -358,6 +364,8 @@ case KSIPContactHeaderUser: case KSIPSoIpTOS: case KSIPSnapId: + case KPrimaryAPN: + case KSecondaryAPN: User::Leave(KErrNotFound); default: iSIPProfile->SetExtensionParameterL(aParam, aVal); diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Client/Src/sipprofile.cpp --- a/realtimenetprots/sipfw/ProfileAgent/Client/Src/sipprofile.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Client/Src/sipprofile.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -313,6 +313,8 @@ case KSIPOutboundProxy: case KSIPPrivateIdentity: case KSIPSoIpTOS: + case KPrimaryAPN: + case KSecondaryAPN: { return KErrNotFound; } diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Group/sipietfagent.mmp --- a/realtimenetprots/sipfw/ProfileAgent/Group/sipietfagent.mmp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Group/sipietfagent.mmp Fri Mar 12 15:44:11 2010 +0200 @@ -60,6 +60,6 @@ VENDORID 0x70000001 -CAPABILITY ProtServ NetworkServices ReadDeviceData +CAPABILITY ProtServ NetworkServices ReadDeviceData WriteDeviceData SMPSAFE diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Group/sipimsagent.mmp --- a/realtimenetprots/sipfw/ProfileAgent/Group/sipimsagent.mmp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Group/sipimsagent.mmp Fri Mar 12 15:44:11 2010 +0200 @@ -86,6 +86,6 @@ VENDORID 0x70000001 -CAPABILITY ProtServ NetworkServices ReadDeviceData +CAPABILITY ProtServ NetworkServices ReadDeviceData WriteDeviceData SMPSAFE diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Group/sipprofilefsm.mmp --- a/realtimenetprots/sipfw/ProfileAgent/Group/sipprofilefsm.mmp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Group/sipprofilefsm.mmp Fri Mar 12 15:44:11 2010 +0200 @@ -58,6 +58,6 @@ VENDORID 0x70000001 -CAPABILITY ProtServ NetworkServices ReadDeviceData +CAPABILITY ProtServ NetworkServices ReadDeviceData WriteDeviceData SMPSAFE diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Group/sipprofileserver.mmp --- a/realtimenetprots/sipfw/ProfileAgent/Group/sipprofileserver.mmp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Group/sipprofileserver.mmp Fri Mar 12 15:44:11 2010 +0200 @@ -46,6 +46,10 @@ SOURCE sipalrmigrationcontroller.cpp SOURCE sipalrmigrationobserverinfo.cpp +SOURCEPATH ../ApnManager/src +SOURCE sipapnmanager.cpp +SOURCE sipapnconfigurationhandler.cpp + SOURCEPATH ../Store/Src SOURCE SIPProfileStorageBase.cpp SOURCE SIPProfileStorageIndex.cpp @@ -69,6 +73,7 @@ USERINCLUDE ../PluginMgr/Inc USERINCLUDE ../Store/Inc USERINCLUDE ../AlrMonitor/inc +USERINCLUDE ../ApnManager/inc MW_LAYER_SYSTEMINCLUDE @@ -87,10 +92,12 @@ LIBRARY centralrepository.lib LIBRARY cmmanager.lib LIBRARY commsdat.lib +LIBRARY featmgr.lib +LIBRARY commdb.lib VENDORID 0x70000001 -CAPABILITY ProtServ NetworkServices ReadDeviceData +CAPABILITY ProtServ NetworkServices ReadDeviceData WriteDeviceData // MACRO PLAT_SEC_TEST diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Group/sipproxyrsv.mmp --- a/realtimenetprots/sipfw/ProfileAgent/Group/sipproxyrsv.mmp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Group/sipproxyrsv.mmp Fri Mar 12 15:44:11 2010 +0200 @@ -43,6 +43,6 @@ VENDORID 0x70000001 -CAPABILITY ProtServ NetworkServices ReadDeviceData +CAPABILITY ProtServ NetworkServices ReadDeviceData WriteDeviceData SMPSAFE diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileCacheItem.h --- a/realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileCacheItem.h Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileCacheItem.h Fri Mar 12 15:44:11 2010 +0200 @@ -301,7 +301,43 @@ * EFalse otherwise */ TBool IsRfsInprogress() const; + + /** + * VPN session is about to start. + */ + void VpnInUse(TBool aStatus); + /** + * Tells if VPN is in use. + * @return ETrue if VPN is in use. + * EFalse otherwise + */ + TBool IsVpnInUse() const; + + /** + * Sets the initial APN for the profile + */ + void SetApnSelected(TBool aStatus); + + /** + * Tells if initial Apn is selected or not + * @return ETrue if Initial APN settings are done + * EFalse otherwise + */ + TBool IsInitialApnSelected() const; + + /** + * Tells if Apn can be switched for a given IAP + * @return ETrue if Profile all the switchable parameters + * EFalse otherwise + */ + TBool IsApnSwitchEnabled() const; + + /** + * Sets the switch value for the profile + */ + void SetApnSwitchStatus(TBool aStatus); + /** * Checks if profile can be permanently removed * @return ETrue if not used and can be removed @@ -613,6 +649,9 @@ // ETrue if Rfs has been initiated TBool iIsRfsInprogress; + + // ETrue if VPN is in use + TBool iIsVpnInUse; // Tells if at least one client disallowed migration to a new IAP TBool iMigrationDisallowed; @@ -620,6 +659,12 @@ // ETrue if a new IAP came available, but it was disallowed by the // profile, because new IAP couldn't be handled. TBool iMustRefreshIAPs; + + // ETrue when if the initial APN is selcted. + TBool iInitialApnSelected; + + // ETrue when APN can be switched for the profile. + TBool iApnSwitchEnabled; // Not owned. NULL if SNAP is not configured. CSipAlrMigrationController* iMigrationController; diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileServerCore.h --- a/realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileServerCore.h Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileServerCore.h Fri Mar 12 15:44:11 2010 +0200 @@ -35,6 +35,7 @@ #include "sipprofileagentobserver.h" #include "sipprofileerrorhandler.h" #include +#include "sipapnmanager.h" #include // FORWARD DECLARATIONS @@ -67,8 +68,29 @@ class CSIPProfileServerCore : public CBase, public MSIPProfileAgentObserver, public MSipProfileErrorHandler, - public MSipSystemStateObserver + public MSipSystemStateObserver, + public MSIPApnChangeObserver { + + public: + /* + * struct to store ApnSwitchEnabled profiles in the event + * when IAPSettings are not same as required. + */ + struct TStoreSwitchEnabledProfile + { + public: + enum TOperation + { + Update =1, + Enable, + Register + }; + CSIPConcreteProfile* iProfile; + const MSIPExtendedConcreteProfileObserver* iObserver; + TOperation operation; + }; + public: // Constructors and destructor /** @@ -116,6 +138,10 @@ CSipSystemStateMonitor::TSystemVariable aVariable, TInt aObjectId, TInt aValue ); + + public: // MSIPApnChangeObserver + + void ApnChanged( const TDesC8& aApn, TUint32 aIapId, TInt aError ); public: // New functions @@ -441,18 +467,41 @@ TUint32 GenerateProfileIdL(); /** - * Sends forcibly disable profile added event to all clients - * @param aProfileId: Id of the profile being disabled forcibly - */ + * Sends forcibly disable profile added event to all clients + * @param aProfileId: Id of the profile being disabled forcibly + */ void SendProfileForciblyDisabledEvent(const CSIPProfileCacheItem& aItem) const; - /** - * Gets cached profile, leave if not found - * ownership is not transfered - * @param aProfileId id of profile. - * @return profile cache item - */ - CSIPProfileCacheItem* ProfileCacheItemL(TUint32 aProfileId) const; + /** + * Gets cached profile, leave if not found + * ownership is not transfered + * @param aProfileId id of profile. + * @return profile cache item + */ + CSIPProfileCacheItem* ProfileCacheItemL(TUint32 aProfileId) const; + + /** + *Starts timer of type CDeltaTimer, + *which callback is ConnectionCloseTimerExpired function + */ + void StartConnectionCloseTimer(); + + /** + * A callback for CDeltaTimer + */ + static TInt ConnectionCloseTimerExpired(TAny* aPtr); + + /** + * Notify system state monitor about event processing completion + */ + void ConfirmSystemstateMonitor( + CSipSystemStateMonitor::TSystemVariable aVariable); + + /* + * Checks whether the Update can be performed when the profile + * has IAP as modem bearer. + */ + TBool IsUpdateAllowed( CSIPConcreteProfile *aProfile ); private: @@ -468,9 +517,9 @@ void ConstructL(); /** - * Sends status event to observers of the profile + * Sends status event to observers of the profile * @param aItem holds profile and observers - */ + */ void SendStatusEventL(CSIPProfileCacheItem& aItem, CSIPConcreteProfile::TStatus aStatus) const; @@ -613,32 +662,32 @@ */ void ReserveStorageL(TBool aRestoreOngoing); - /** - * Cleans up array in case of failure - * ownership of aArray is transferred + /** + * Cleans up array in case of failure + * ownership of aArray is transferred * @param aArray array to be cleaned up - */ + */ static void ResetAndDestroy(TAny* aArray); - /** - * Cleans up array in case of failure - * ownership of aArray is transferred + /** + * Cleans up array in case of failure + * ownership of aArray is transferred * @param aArray array to be cleaned up - */ + */ static void ResetAndDestroyInfo(TAny* aArray); - /** - * Reverts back cache in case of failure + /** + * Reverts back cache in case of failure * @param aItem cache cleanup item - */ + */ static void CrashRevert(TAny* aItem); /** - * Handles the errors occured during the profile restore + * Handles the errors occured during the profile restore * @param aErr * @param fileStore specifies the kind of the file on which * the storage error has occured - */ + */ void HandleProfileStorageErrorL(TInt aErr, TBool fileStore=EFalse); /** @@ -648,10 +697,10 @@ void RemoveProfileItem(TUint32 aProfileId); /** - * Removes unused migration controllers, except if it uses the specified - * SNAP id. + * Removes unused migration controllers, except if it uses the specified + * SNAP id. * @param aSnapId SNAP id - */ + */ void RemoveUnusedMigrationControllers(TUint32 aSnapId); void LoadSystemStateMonitorL(); @@ -662,25 +711,60 @@ */ CSIPConcreteProfile* FindDefaultProfile() const; - TBool ShouldChangeIap(CSIPConcreteProfile& aProfile, TInt aError) const; + TBool ShouldChangeIap(CSIPConcreteProfile& aProfile, TInt aError) const; - /** - * @return ETrue if any registered profile is using aIap - */ - TBool AnyRegisteredProfileUsesIap(TUint aIap) const; + /** + * @return ETrue if any registered profile is using aIap + */ + TBool AnyRegisteredProfileUsesIap(TUint aIap) const; - /** - * Add profiles in Profile Cache - * @param aProfiles Array of the profiles to be added - * @param aNotifyProfileCreation specifies whether the notification to be sent to the profile clients - */ - void AddProfilesInCacheL(RPointerArray& aProfiles,TBool aNotifyProfileCreation); + /** + * Add profiles in Profile Cache + * @param aProfiles Array of the profiles to be added + * @param aNotifyProfileCreation specifies whether the notification + * to be sent to the profile clients + */ + void AddProfilesInCacheL(RPointerArray& aProfiles, + TBool aNotifyProfileCreation); /** * Gets the IAP Count in the Snap - * @return number of aIaps in the Snap - */ - TInt IAPCountL(TUint32 aSnapId) const; + * @return number of aIaps in the Snap + */ + TInt IAPCountL(TUint32 aSnapId) const; + + /* + * Checks whether the current seetings are same as + * required seetings for Registeration. + * @ returns ETrue when the seetings are correct + * EFalse otherwise + */ + + TBool IsRegistrationAllowedWithCurrentApnSettings( TUint32 aIapId ); + + /** + ** Selecting Initial Apn for the profile + **/ + void SelectInitialApnL( const CSIPConcreteProfile& aProfile ); + + /** + * Checks whether the profile's IAP is switch enabled + * @ returns ETrue when the profile is APN switch enabled + * EFalse otherwise + */ + TBool CheckApnSwitchEnabledL( const CSIPConcreteProfile& aProfile ); + + /** + * Checks the IAP settings + * @ returns ETrue when all the settings are correct + * EFalse otherwise + */ + TBool CheckIapSettings(TUint32 aProfileId); + + void UsePrimaryApn(TUint32 aIapId); + + void UseBackupApn( TUint32 aIapId, TBool aFatalFailure = ETrue ); + private: // Data @@ -725,8 +809,17 @@ // Owned CSipSystemStateMonitor* iSystemStateMonitor; + //ApnManager + CSIPApnManager* iApnManager; // iBackupApnSettings; + RArray iWaitForApnSettings; TBool iOfflineEventReceived; + + TBool iFeatMgrInitialized; + + CDeltaTimer* iDeltaTimer; + TCallBack iDeltaTimerCallBack; + TDeltaTimerEntry iDeltaTimerEntry; private: // For testing purposes #ifdef CPPUNIT_TEST diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileState.h --- a/realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileState.h Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileState.h Fri Mar 12 15:44:11 2010 +0200 @@ -333,6 +333,14 @@ CSIPProfileState& aUnregInProg, CSIPProfileState& aUnregistered) const; + /** + * Deregister profiles while registration is is progress + * @param aItem profile cache item + * @param aItem aUnregistered "Unregister" state + */ + void DeregisterWhileRegInProgressL(CSIPProfileCacheItem& aItem, + CSIPProfileState& aUnregistered); + protected: // Data CSIPPluginDirector& iPluginDirector; diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileStateRegInProg.h --- a/realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileStateRegInProg.h Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Inc/SipProfileStateRegInProg.h Fri Mar 12 15:44:11 2010 +0200 @@ -89,6 +89,10 @@ void IapAvailableL(CSIPProfileCacheItem& aItem, TUint32 aSnapId, TUint32 aNewIapId); + + // Newly added to handle unregistration request in + // RegInProg state. + void ShutdownInitiated( CSIPProfileCacheItem& aItem ); public: // New functions diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileCSSession.cpp --- a/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileCSSession.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileCSSession.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -249,13 +249,21 @@ { HBufC8* profileBuf = iHelper.ReadLC(ESipProfileItcArgProfile,aMessage); CSIPConcreteProfile* profile = InternalizeProfileLC(*profileBuf); - TBool canProceed = iCore.UpdateProfileToStoreL(profile, *this); - CleanupStack::Pop(profile); - CleanupStack::PopAndDestroy(profileBuf); - if (canProceed) - { - iCore.UpdateRegistrationL(profile->Id(), *this); - } + TBool updateAllowed = iCore.IsUpdateAllowed(profile); + if(updateAllowed) + { + TBool canProceed = iCore.UpdateProfileToStoreL(profile, *this); + CleanupStack::Pop(profile); + CleanupStack::PopAndDestroy(profileBuf); + if (canProceed) + { + iCore.UpdateRegistrationL(profile->Id(), *this); + } + } + else + { + User::Leave(KErrNotSupported); + } } // ----------------------------------------------------------------------------- diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileCacheItem.cpp --- a/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileCacheItem.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileCacheItem.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -84,6 +84,9 @@ #endif { iIsRfsInprogress = EFalse; + iIsVpnInUse = EFalse; + iInitialApnSelected = EFalse; + iApnSwitchEnabled = EFalse; iDeltaTimerEntry.Set(iDeltaTimerCallBack); } @@ -560,6 +563,61 @@ return iIsRfsInprogress; } +// ----------------------------------------------------------------------------- +// CSIPProfileCacheItem::VpnInUse +// ----------------------------------------------------------------------------- +// +void CSIPProfileCacheItem::VpnInUse(TBool aStatus) + { + iIsVpnInUse = aStatus; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCacheItem::IsVpnInUse +// ----------------------------------------------------------------------------- +// +TBool CSIPProfileCacheItem::IsVpnInUse() const + { + return iIsVpnInUse; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCacheItem::SetApnSelected +// ----------------------------------------------------------------------------- +// +void CSIPProfileCacheItem::SetApnSelected(TBool aStatus) + { + iInitialApnSelected = aStatus; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCacheItem::IsInitialApnSelected +// ----------------------------------------------------------------------------- +// +TBool CSIPProfileCacheItem::IsInitialApnSelected() const + { + return iInitialApnSelected; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCacheItem::SetApnSwitchStatus +// ----------------------------------------------------------------------------- +// +void CSIPProfileCacheItem::SetApnSwitchStatus(TBool aStatus) + { + iApnSwitchEnabled = aStatus; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCacheItem::IsApnSwitchEnabled +// ----------------------------------------------------------------------------- +// +TBool CSIPProfileCacheItem::IsApnSwitchEnabled() const + { + return iApnSwitchEnabled; + } + +// ----------------------------------------------------------------------------- // CSIPProfileCacheItem::CanBePermanentlyRemoved // ----------------------------------------------------------------------------- // diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileServerCore.cpp --- a/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileServerCore.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileServerCore.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -48,12 +48,16 @@ #include #include #include - -#include -#include +#include // for Feature Manager +#include +#include #include using namespace CommsDat; + +const TInt KMicroSecInSec = 1000000; +const TInt KIdleTimer = 2; + // ============================ MEMBER FUNCTIONS =============================== // ----------------------------------------------------------------------------- @@ -86,7 +90,8 @@ // ----------------------------------------------------------------------------- // CSIPProfileServerCore::CSIPProfileServerCore() : - iBackupInProgress(EFalse) + iBackupInProgress(EFalse), + iDeltaTimerCallBack(ConnectionCloseTimerExpired, this) #ifdef CPPUNIT_TEST // Set the array granularity to 1, so they allocate memory for every append , iProfileCache(1), @@ -94,6 +99,8 @@ iMigrationControllers(1) #endif { + iFeatMgrInitialized = EFalse; + iDeltaTimerEntry.Set(iDeltaTimerCallBack); } // ----------------------------------------------------------------------------- @@ -103,6 +110,11 @@ void CSIPProfileServerCore::ConstructL() { User::LeaveIfError(iFs.Connect()); + + FeatureManager::InitializeLibL(); + iFeatMgrInitialized = ETrue; + + iDeltaTimer = CDeltaTimer::NewL(CActive::EPriorityStandard); iFindEntry = CSIPProfileCacheItem::NewL(*this, iUnregistered); @@ -148,6 +160,8 @@ *iUnregistered); iUnregisteringOldIAP->SetNeighbourStates(*iRegistered, *iUnregInProg); + iApnManager = CSIPApnManager::NewL( *this ); + LoadSystemStateMonitorL(); iAlrHandler = CSipAlrHandler::NewL(*this,iSystemStateMonitor); @@ -201,9 +215,16 @@ delete iWaitForPermission; delete iMigratingToNewIAP; delete iUnregisteringOldIAP; - + delete iApnManager; delete iNotify; - + iWaitForApnSettings.Reset(); + if(iFeatMgrInitialized) + { + FeatureManager::UnInitializeLib(); + } + + delete iDeltaTimer; + iFs.Close(); PROFILE_DEBUG1("ProfileServer stopped") @@ -270,40 +291,39 @@ } } - if (item && item->IsRfsInprogress()) + TBool eventCompleted = EFalse; + if(item && (item->IsRfsInprogress() || iOfflineEventReceived || + (FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn )&& + item->IsVpnInUse()))) { CSIPConcreteProfile::TStatus status; TInt count = iProfileCache.Count(); - for (TInt i = 0; i < iProfileCache.Count(); i++) + for ( TInt i = 0; i < iProfileCache.Count(); i++ ) { - iPluginDirector->State(status, iProfileCache[i]->UsedProfile()); - if (status == CSIPConcreteProfile::EUnregistered) + iPluginDirector->State( status, iProfileCache[i]->UsedProfile() ); + if ( status == CSIPConcreteProfile::EUnregistered ) + { count--; + } + else if (status == CSIPConcreteProfile::ERegistered ) + { + iProfileCache[i]->ShutdownInitiated(); + } } - if (!count) - { - iSystemStateMonitor->EventProcessingCompleted( - CSipSystemStateMonitor::ERfsState, 0, *this); - } + if ( !count ) + eventCompleted = ETrue; } - } - - if (iOfflineEventReceived) - { - CSIPConcreteProfile::TStatus status; - TInt count = iProfileCache.Count(); - for (TInt i = 0; i < iProfileCache.Count(); i++) + if(eventCompleted) { - iPluginDirector->State(status, iProfileCache[i]->UsedProfile()); - if (status == CSIPConcreteProfile::EUnregistered) - count--; - } - if (!count) - { - iSystemStateMonitor->EventProcessingCompleted(CSipSystemStateMonitor::ESystemState, 0, *this); - } - } - + if (item->IsRfsInprogress()) + StartConnectionCloseTimer(); + else if(iOfflineEventReceived) + ConfirmSystemstateMonitor(CSipSystemStateMonitor::ESystemState); + else if((FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn )&& + item->IsVpnInUse())) + ConfirmSystemstateMonitor(CSipSystemStateMonitor::EVpnState); + } + } CheckServerStatus(); } @@ -434,11 +454,20 @@ (aValue == CSipSystemStateMonitor::ESystemShuttingDown || aValue == CSipSystemStateMonitor::ESystemOffline )) - { + { + TBool waitForDeregistration = EFalse; for (TInt i = 0; i < iProfileCache.Count(); i++) { iProfileCache[i]->ShutdownInitiated(); - } + CSIPConcreteProfile::TStatus status; + iPluginDirector->State(status, iProfileCache[i]->UsedProfile()); + if(status != CSIPConcreteProfile::EUnregistered) + waitForDeregistration = ETrue; + } + if(!waitForDeregistration) + { + ConfirmSystemstateMonitor(CSipSystemStateMonitor::ESystemState); + } } //If the System State is Online, register all the profiles in always on mode else if(aVariable == CSipSystemStateMonitor::ESystemState && @@ -449,7 +478,7 @@ { iProfileCache[i]->ResetShutdownvariable(); CSIPProfileCacheItem* item = iProfileCache[i]; - if (item->Profile().IsAutoRegistrationEnabled()) + if (iProfileCache[i]->IsReferred()) { TRAPD(err, item->StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue)); if (err != KErrNone) @@ -464,9 +493,18 @@ if(aValue == CSipSystemStateMonitor::ERfsStarted) { PROFILE_DEBUG1("RFS Started, de-registering the profiles") - for (TInt i = 0; i < iProfileCache.Count(); i++) + TBool waitForDeregistration = EFalse; + for (TInt i = 0; i < iProfileCache.Count(); i++) { iProfileCache[i]->RfsInprogress(ETrue); + CSIPConcreteProfile::TStatus status; + iPluginDirector->State(status, iProfileCache[i]->UsedProfile()); + if (status != CSIPConcreteProfile::EUnregistered) + waitForDeregistration = ETrue; + } + if(!waitForDeregistration) + { + ConfirmSystemstateMonitor(CSipSystemStateMonitor::ERfsState); } } else if(aValue == CSipSystemStateMonitor::ERfsFailed) @@ -496,7 +534,50 @@ } } } - } + // Perform de/re-registration for VPN. + else if( FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && ( aVariable == CSipSystemStateMonitor::EVpnState ) ) + { + // If VPN session is about to start, SIP should be deregistered. + if( aValue == CSipSystemStateMonitor::EVpnInitiating ) + { + PROFILE_DEBUG1("VPN Initiated , de-registering the profiles") + TBool waitForDeregistration = EFalse; + for (TInt i = 0; i < iProfileCache.Count(); i++) + { + iProfileCache[i]->VpnInUse( ETrue ); + iProfileCache[i]->ShutdownInitiated(); + CSIPConcreteProfile::TStatus status; + iPluginDirector->State(status, iProfileCache[i]->UsedProfile()); + if (status != CSIPConcreteProfile::EUnregistered) + waitForDeregistration = ETrue; + } + if (!waitForDeregistration) + { + ConfirmSystemstateMonitor(CSipSystemStateMonitor::EVpnState); + } + } + // If VPN session ended, SIP should be re-registered. + else if( aValue == CSipSystemStateMonitor::EVpnTerminated ) + { + PROFILE_DEBUG1("VPN Terminated , re-registering the profiles") + for (TInt i = 0; i < iProfileCache.Count(); i++) + { + iProfileCache[i]->VpnInUse(EFalse); + if ( iProfileCache[i]->IsReferred() ) + { + TRAPD(err, iProfileCache[i]->StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue)); + if (err != KErrNone) + { + HandleAsyncError( *iProfileCache[i], + CSIPConcreteProfile::ERegistrationInProgress, + err); + } + } + } + } + } + } // ----------------------------------------------------------------------------- // CSIPProfileServerCore::SessionRegisterL @@ -824,6 +905,11 @@ return EFalse; } } + if (iApnManager->HasPendingTasks()) + { + PROFILE_DEBUG1("ApnManager has pending tasks, do not stop server yet") + return EFalse; + } return ETrue; } @@ -904,14 +990,73 @@ const MSIPExtendedConcreteProfileObserver& aObserver) { CSIPProfileCacheItem* item = ProfileCacheItemL(aProfileId); + TInt err(KErrNone); CSIPConcreteProfile::TStatus status(CSIPConcreteProfile::ERegistrationInProgress); + if (item->Profile().Status() == CSIPConcreteProfile::ERegistered) { status = CSIPConcreteProfile::EUnregistrationInProgress; } + if(FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn)) + { + if(item->LatestProfile().IapId()!= item->UsedProfile().IapId()) + { + item->SetApnSelected(EFalse); + } + + item->SetApnSwitchStatus(EFalse); + if(CheckApnSwitchEnabledL(item->LatestProfile())) + { + const TDesC8* primaryApn( NULL ); + const TDesC8* secondaryApn( NULL ); + const TDesC8* latestprimaryApn( NULL ); + const TDesC8* latestsecondaryApn( NULL ); + + TInt err1 = item->LatestProfile().ExtensionParameter(KPrimaryAPN,latestprimaryApn); + TInt err2 = item->UsedProfile().ExtensionParameter(KPrimaryAPN,primaryApn); + + TInt err3 = item->LatestProfile().ExtensionParameter(KSecondaryAPN,latestsecondaryApn); + TInt err4 = item->UsedProfile().ExtensionParameter(KSecondaryAPN,secondaryApn); + if((err1 == KErrNone && err2 == KErrNone && latestprimaryApn->Compare(*primaryApn)!= 0)|| + (err3 == KErrNone && err4 == KErrNone && + latestsecondaryApn->Compare(*secondaryApn)!= 0)) + { + item->SetApnSelected(EFalse); + } + } + } - TRAPD(err, item->UpdateRegistrationL(aObserver)); + + if(FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn) + && item->IsApnSwitchEnabled()) + { + PROFILE_DEBUG1("CSIPProfileServerCore::UpdateRegistrationL, SwichEnabled") + if(CheckIapSettings( item->LatestProfile().Id())) + { + PROFILE_DEBUG1("CSIPProfileServerCore::UpdateRegistrationL, Settings are correct") + if(IsRegistrationAllowedWithCurrentApnSettings(item->LatestProfile().IapId())) + { + PROFILE_DEBUG1("CSIPProfileServerCore::UpdateRegistrationL, Registration is allowed") + TRAP(err, item->UpdateRegistrationL(aObserver)); + } + else + { + PROFILE_DEBUG1("CSIPProfileServerCore::UpdateRegistrationL, Appending into Array") + TStoreSwitchEnabledProfile updateProfile; + updateProfile.iObserver = &aObserver; + updateProfile.iProfile = &item->LatestProfile(); + updateProfile.operation = TStoreSwitchEnabledProfile::Update; + iWaitForApnSettings.AppendL(updateProfile); + } + } + else + User::LeaveIfError(KErrNotSupported); + } + else + { + TRAP(err, item->UpdateRegistrationL(aObserver)); + } if (err != KErrNone) { HandleAsyncError(*item, status, err); @@ -927,7 +1072,42 @@ const MSIPExtendedConcreteProfileObserver& aObserver) { CSIPProfileCacheItem* item = ProfileCacheItemL(aProfileId); - iAlrHandler->EnableProfileL(*item, aObserver); + TBool isVpnInUse = (FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && item->IsVpnInUse()); + + const CSIPConcreteProfile* profile = Profile(aProfileId); + if(FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && CheckApnSwitchEnabledL( *profile ) && !item->IsRfsInprogress() && !isVpnInUse ) + { + PROFILE_DEBUG1("CSIPProfileServerCore::EnableProfileL, SwichEnabled") + if(CheckIapSettings( aProfileId )) + { + PROFILE_DEBUG1("CSIPProfileServerCore::EnableProfileL, Settings are correct") + if(IsRegistrationAllowedWithCurrentApnSettings(item->Profile().IapId())) + { + PROFILE_DEBUG1("CSIPProfileServerCore::EnableProfileL, Registration is allowed") + iAlrHandler->EnableProfileL(*item, aObserver); + } + else + { + PROFILE_DEBUG1("CSIPProfileServerCore::EnableProfileL, Appending into Array") + TStoreSwitchEnabledProfile enableProfile; + enableProfile.iProfile = &item->Profile(); + enableProfile.iObserver = &aObserver; + enableProfile.operation = TStoreSwitchEnabledProfile::Enable; + iWaitForApnSettings.AppendL(enableProfile); + } + } + else + { + User::LeaveIfError(KErrNotSupported); + } + } + else + if (!item->IsRfsInprogress() && !isVpnInUse ) + { + iAlrHandler->EnableProfileL(*item, aObserver); + } return item->Profile().Status(); } @@ -988,10 +1168,40 @@ { for (TInt i = 0; i < iProfileCache.Count(); i++) { + TInt err(KErrNone); CSIPProfileCacheItem* item = iProfileCache[i]; if (item->Profile().IsAutoRegistrationEnabled()) { - TRAPD(err, item->StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue)); + TBool enabled(EFalse); + TRAPD(error, enabled = CheckApnSwitchEnabledL(item->Profile())) + if(FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + &&enabled && !error) + { + PROFILE_DEBUG1("CSIPProfileServerCore::RegisterProfiles, SwichEnabled") + if(CheckIapSettings( item->Profile().Id())) + { + PROFILE_DEBUG1("CSIPProfileServerCore::RegisterProfiles, Settings are correct") + if(IsRegistrationAllowedWithCurrentApnSettings(item->Profile().IapId())) + { + PROFILE_DEBUG1("CSIPProfileServerCore::RegisterProfiles, Registration is allowed") + TRAP(err, item->StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue)); + } + else + { + PROFILE_DEBUG1("CSIPProfileServerCore::RegisterProfiles, Appending into Array") + TStoreSwitchEnabledProfile registerProfile; + registerProfile.iProfile = &item->Profile(); + registerProfile.iObserver = NULL; + registerProfile.operation = TStoreSwitchEnabledProfile::Register; + TRAP_IGNORE(iWaitForApnSettings.AppendL(registerProfile)) + } + } + } + else + { + TRAP(err, item->StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue)); + } + if (err != KErrNone) { HandleAsyncError(*item, @@ -1405,6 +1615,10 @@ SendErrorEvent(aItem, aStatus, aError); } } + if(aItem.IsApnSwitchEnabled()) + { + UseBackupApn(aItem.Profile().IapId(), ETrue); + } } // ----------------------------------------------------------------------------- @@ -1740,6 +1954,13 @@ CSipSystemStateMonitor::ESystemState, 0, *this); iSystemStateMonitor->StartMonitoringL( CSipSystemStateMonitor::ERfsState, 0, *this); + + if ( FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) ) + { + // Start P&S key monitoring for communication between SIP and VPN. + iSystemStateMonitor->StartMonitoringL( + CSipSystemStateMonitor::EVpnState, 0, *this); + } } CleanupStack::Pop(); // TCleanupItem infoArray.ResetAndDestroy(); @@ -1801,7 +2022,11 @@ PROFILE_DEBUG1("CSIPProfileServerCore::ShouldChangeIap returns false") return EFalse; } - + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::AnyRegisteredProfileUsesIap +// ----------------------------------------------------------------------------- +// TBool CSIPProfileServerCore::AnyRegisteredProfileUsesIap(TUint aIap) const { @@ -1877,4 +2102,243 @@ CleanupStack::PopAndDestroy( db ); return count; } + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::StartConnectionCloseTimer +// ----------------------------------------------------------------------------- +// +void CSIPProfileServerCore::StartConnectionCloseTimer() + { + PROFILE_DEBUG1("CSIPProfileServerCore::StartConnectionCloseTimer") + iDeltaTimer->Remove(iDeltaTimerEntry); + TTimeIntervalMicroSeconds32 interval(KMicroSecInSec * KIdleTimer); + iDeltaTimer->Queue(interval, iDeltaTimerEntry); + } + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::ConnectionCloseTimerExpired +// ----------------------------------------------------------------------------- +// +TInt CSIPProfileServerCore::ConnectionCloseTimerExpired(TAny* aPtr) + { + PROFILE_DEBUG1("CSIPProfileServerCore::ConnectionCloseTimerExpired") + CSIPProfileServerCore* self = reinterpret_cast(aPtr); + self->ConfirmSystemstateMonitor(CSipSystemStateMonitor::ERfsState); + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::ConfirmSystemstateMonitor +// ----------------------------------------------------------------------------- +// +void CSIPProfileServerCore::ConfirmSystemstateMonitor( + CSipSystemStateMonitor::TSystemVariable aVariable) + { + iSystemStateMonitor->EventProcessingCompleted( + aVariable, 0, *this); + } +// ---------------------------------------------------------------------------- +//CSIPProfileServerCore::ApnChanged +// ---------------------------------------------------------------------------- +void CSIPProfileServerCore::ApnChanged( const TDesC8& /*aApn*/, TUint32 aIapId, TInt aError ) + { + PROFILE_DEBUG3( "CSIPProfileServerCore::ApnChanged, err:", aError ) + // Check if there is any profile waiting for correct Apn settings for IapId aIapId + + if ( IsRegistrationAllowedWithCurrentApnSettings( aIapId ) || aError != KErrNone ) + { + PROFILE_DEBUG1("CSIPProfileServerCore::ApnChanged, settings are correct") + CSIPConcreteProfile* profile = NULL; + TInt count = iWaitForApnSettings.Count(); + for (TInt i =0; i < count; i++) + { + TStoreSwitchEnabledProfile switchEnabledProfile = iWaitForApnSettings[i]; + if(switchEnabledProfile.iProfile->IapId()==aIapId) + { + profile = switchEnabledProfile.iProfile; + iWaitForApnSettings.Remove(i); + iWaitForApnSettings.Compress(); + i--; + count = iWaitForApnSettings.Count(); + PROFILE_DEBUG1("CSIPProfileServerCore::ApnChanged, Profile IapId matches") + + TInt err( aError ); + TInt error(KErrNone); + PROFILE_DEBUG3("CSIPProfileServerCore::ApnChanged, Profile Id", profile->Id()) + CSIPProfileCacheItem* item = ProfileCacheItem(profile->Id()); + TBool isVpnInUse = (FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && item->IsVpnInUse()); + if ( err == KErrNone && CheckIapSettings(profile->Id())) + { + if(switchEnabledProfile.operation == TStoreSwitchEnabledProfile::Update) + { + TRAP(error, item->UpdateRegistrationL(*(switchEnabledProfile.iObserver))); + } + else if(switchEnabledProfile.operation == TStoreSwitchEnabledProfile::Enable && !item->IsRfsInprogress() && !isVpnInUse) + { + TRAP(error, iAlrHandler->EnableProfileL(*item, *(switchEnabledProfile.iObserver))); + } + else if(switchEnabledProfile.operation == TStoreSwitchEnabledProfile::Register) + { + TRAP(error, item->StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue)); + } + } + if ( err != KErrNone || error) + { + PROFILE_DEBUG1("CSIPProfileServerCore::ApnChanged, error handling") + HandleAsyncError(*item, profile->Status(), err); + } + } + } + } + PROFILE_DEBUG1("CSIPProfileServerCore::ApnChanged, exit") + } + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::IsRegistrationAllowedWithCurrentApnSettings +// ----------------------------------------------------------------------------- +// +TBool CSIPProfileServerCore::IsRegistrationAllowedWithCurrentApnSettings( TUint32 aIapId ) + { + return ( iApnManager && iApnManager->IsPrimaryApnInUse( aIapId ) ); + } + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::SelectInitialApnL +// ----------------------------------------------------------------------------- +// +void CSIPProfileServerCore::SelectInitialApnL( const CSIPConcreteProfile& aProfile ) + { + PROFILE_DEBUG1("CSIPProfileServerCore::SelectInitialApnL" ) + CSIPProfileCacheItem* item = ProfileCacheItem(aProfile.Id()); + + if ( item && !item->IsInitialApnSelected()) + { + // If profile has stored APNs, use them + const TDesC8* primaryApn( NULL ); + if ( aProfile.ExtensionParameter( KPrimaryAPN, primaryApn ) == KErrNone ) + { + PROFILE_DEBUG1("UpdateApnL ETrue" ) + iApnManager->UpdateApnL( aProfile.IapId(), ETrue, *primaryApn ); + } + const TDesC8* secondaryApn( NULL ); + if ( aProfile.ExtensionParameter( KSecondaryAPN, secondaryApn ) == KErrNone ) + { + PROFILE_DEBUG1("UpdateApnL EFalse" ) + iApnManager->UpdateApnL( aProfile.IapId(), EFalse, *secondaryApn ); + } + + PROFILE_DEBUG1("SelectInitialApnL - WriteApnL, Primary APN" ) + iApnManager->WriteApnL( aProfile.IapId(), ETrue, primaryApn); + item->SetApnSelected(ETrue); + } + } + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::CheckApnSwitchEnabledL +// ----------------------------------------------------------------------------- +// +TBool CSIPProfileServerCore::CheckApnSwitchEnabledL( const CSIPConcreteProfile& aProfile ) + { + PROFILE_DEBUG1("CSIPProfileServerCore::CheckApnSwitchEnabledL" ) + TUint32 profileId = aProfile.Id(); + + PROFILE_DEBUG3("CSIPProfileServerCore::CheckApnSwitchEnabledL, IapId", profileId ) + + CSIPProfileCacheItem* item = ProfileCacheItem(profileId); + TUint32 snapId; + if(item && !item->IsSNAPConfigured( snapId )&& !item->IsApnSwitchEnabled()) + { + // If profile has stored APNs, use them + const TDesC8* primaryApn( NULL ); + const TDesC8* secondaryApn( NULL ); + TInt err = aProfile.ExtensionParameter( KPrimaryAPN, primaryApn ); + TInt error = aProfile.ExtensionParameter( KSecondaryAPN, secondaryApn ); + + if(err == KErrNone && error == KErrNone && primaryApn && secondaryApn) + { + TBool isIapGPRS = iApnManager->IsIapGPRSL( aProfile.IapId() ); + if (isIapGPRS) + item->SetApnSwitchStatus(ETrue); // Set Switch APN Enabled + } + } + PROFILE_DEBUG3("CSIPProfileServerCore::CheckApnSwitchEnabledL returns" + ,item->IsApnSwitchEnabled()) + return item->IsApnSwitchEnabled(); + } + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::CheckIapSettings +// ----------------------------------------------------------------------------- +// +TBool CSIPProfileServerCore::CheckIapSettings(TUint32 aProfileId) + { + PROFILE_DEBUG1("CSIPProfileServerCore::CheckIapSettings") + + const CSIPConcreteProfile* profile = Profile( aProfileId ); + CSIPProfileCacheItem* item = ProfileCacheItem( aProfileId ); + TInt err(KErrNone); + if(profile && item) + { + if(!iApnManager->IsFailed(profile->IapId())) + { + TRAP(err, SelectInitialApnL( *profile )); + UsePrimaryApn(profile->IapId()); + PROFILE_DEBUG1("CSIPProfileServerCore::CheckIapSettings returns ETrue") + return ETrue; + } + else + if(err || iApnManager->IsFailed(profile->IapId()) ) + { + PROFILE_DEBUG1("CSIPProfileServerCore::CheckIapSettings returns EFalse") + + item->SetApnSelected(ETrue); + return EFalse; + } + } + PROFILE_DEBUG1("CSIPProfileServerCore::CheckIapSettings, profile or item is NULL") + return EFalse; + } + +// ---------------------------------------------------------------------------- +// CSIPProfileServerCore::UsePrimaryApn +// ---------------------------------------------------------------------------- +// +void CSIPProfileServerCore::UsePrimaryApn(TUint32 aIapId) + { + PROFILE_DEBUG1("CSIPProfileServerCore::UsePrimaryApn") + + if (!iApnManager->IsPrimaryApnInUse( aIapId )) + { + iApnManager->SetFailed( aIapId, EFalse, EFalse ); + } + + PROFILE_DEBUG1("CSIPProfileServerCore::UsePrimaryApn, exit") + } + +// ---------------------------------------------------------------------------- +// CSIPProfileServerCore::UseBackupApn +// ---------------------------------------------------------------------------- +// +void CSIPProfileServerCore::UseBackupApn( TUint32 aIapId, TBool aFatalFailure ) + { + PROFILE_DEBUG1("CSIPProfileServerCore::UseBackupApn") + + if ( iApnManager->IsFailed( aIapId ) || aFatalFailure ) + { + iApnManager->SetFailed( aIapId, ETrue, aFatalFailure ); + } + + PROFILE_DEBUG1("CSIPIMSProfileAgent::UseBackupApn, exit") + } + +// ---------------------------------------------------------------------------- +// CSIPProfileServerCore::IsUpdateAllowed +// ---------------------------------------------------------------------------- +// +TBool CSIPProfileServerCore::IsUpdateAllowed( CSIPConcreteProfile *aProfile ) + { + PROFILE_DEBUG1("CSIPIMSProfileAgent::IsUpdateAllowed, enter") + return !(iApnManager->IsFailed(aProfile->IapId())); + } diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileState.cpp --- a/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileState.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileState.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -407,3 +407,22 @@ { PROFILE_DEBUG1("CSIPProfileState::NoNewIapAvailable") } + +// ----------------------------------------------------------------------------- +// CSIPProfileState::DeregisterWhileRegInProgressL +// ----------------------------------------------------------------------------- +// +void CSIPProfileState::DeregisterWhileRegInProgressL(CSIPProfileCacheItem& aItem, + CSIPProfileState& aUnregistered) + { + if ( !iPluginDirector.IsRegisterPending( aItem.UsedProfile() ) ) + { + CSIPConcreteProfile::TStatus status; + iPluginDirector.State( status, aItem.UsedProfile() ); + iPluginDirector.DeregisterL( aItem.UsedProfile() ); + if ( status == CSIPConcreteProfile::ERegistrationInProgress ) + { + aItem.ChangeStateL( &aUnregistered ); + } + } + } diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileStateRegInProg.cpp --- a/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileStateRegInProg.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileStateRegInProg.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -228,3 +228,14 @@ iPluginDirector.TerminateHandling(aItem.Profile()); aItem.HandleNewIapL(aSnapId, aNewIapId, EFalse, *iWaitForPermission); } + +// ----------------------------------------------------------------------------- +// CSIPProfileStateRegInProg::ShutdownInitiated +// Initiate de-registration. PluginDirector never has a pending register in +// registered state. +// ----------------------------------------------------------------------------- +// +void CSIPProfileStateRegInProg::ShutdownInitiated( CSIPProfileCacheItem& aItem ) + { + TRAP_IGNORE( DeregisterWhileRegInProgressL( aItem, *iUnregistered) ) + } diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileStateUnregistered.cpp --- a/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileStateUnregistered.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileStateUnregistered.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -27,6 +27,7 @@ #include "sipplugindirector.h" #include "sipalrmonitor.h" #include "SipProfileLog.h" +#include // ============================ MEMBER FUNCTIONS =============================== @@ -110,16 +111,19 @@ if (aItem.IsActiveState()) { aItem.SendUnregisteredStatusEventL(); - - if (aItem.IsReferred() && !aItem.IsShutdownInitiated() && !aItem.IsRfsInprogress()) - { - aItem.ClearOldProfile(); - aItem.StartRegisterL(*iWaitForIAP, *iRegInProg, getIap); - // CSIPProfileCacheItem::MonitorSnapL stops ALR monitor later if - // updating SNAP. - return; - } - } + TBool isVpnInUse = (FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && aItem.IsVpnInUse()); + + if ( aItem.IsReferred() && !aItem.IsShutdownInitiated() && + !aItem.IsRfsInprogress() && !isVpnInUse) + { + aItem.ClearOldProfile(); + aItem.StartRegisterL(*iWaitForIAP, *iRegInProg, getIap); + // CSIPProfileCacheItem::MonitorSnapL stops ALR monitor later if + // updating SNAP. + return; + } + } // Stay unregistered, no need to monitor SNAP aItem.StopSnapMonitoring(); iPluginDirector.TerminateHandling(aItem.UsedProfile()); @@ -228,12 +232,15 @@ __ASSERT_ALWAYS( iPluginDirector.State(state, aItem.Profile()) == KErrNotFound || state == CSIPConcreteProfile::EUnregistered, User::Leave(KErrArgument)); - - if (aItem.IsReferred() && !aItem.IsShutdownInitiated()) - { - aItem.StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue); - } - } + TBool isVpnInUse = (FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && aItem.IsVpnInUse()); + + if (aItem.IsReferred() && !aItem.IsShutdownInitiated() + && !aItem.IsRfsInprogress() && !isVpnInUse) + { + aItem.StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue); + } + } // ----------------------------------------------------------------------------- // CSIPProfileStateUnregistered::ErrorOccurred diff -r dd3853b8dc3f -r 1e1cc61f56c3 realtimenetprots/sipfw/SIP/SystemStateMonitor/Api/sipsystemstatemonitor.h --- a/realtimenetprots/sipfw/SIP/SystemStateMonitor/Api/sipsystemstatemonitor.h Fri Feb 19 23:10:33 2010 +0200 +++ b/realtimenetprots/sipfw/SIP/SystemStateMonitor/Api/sipsystemstatemonitor.h Fri Mar 12 15:44:11 2010 +0200 @@ -53,7 +53,9 @@ /** SNAP availability event */ ESnapAvailability, /** RFS State */ - ERfsState + ERfsState, + /** VPN State */ + EVpnState }; /** System states */ @@ -91,6 +93,14 @@ ERfsCompleted }; + enum TVpnState + { + /** Vpn is about to be started */ + EVpnInitiating = 0, + /** Vpn ended */ + EVpnTerminated + }; + public: // Constructors and destructor /** diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/inc/srtpaesctrcrypto.h --- a/rtp/srtpstack/inc/srtpaesctrcrypto.h Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/inc/srtpaesctrcrypto.h Fri Mar 12 15:44:11 2010 +0200 @@ -23,6 +23,7 @@ #include +class CAESEncryptor; class CSrtpAESCTRCrypto : public CBase { @@ -68,9 +69,16 @@ */ void IncreaseIV(TDes8& iv); + void CreateEncryptorL(const TDesC8& aKey); + +private: + + HBufC8* iKey; + CAESEncryptor* iEncryptor; + #ifdef EUNIT_TESTING friend class UT_CSrtpAESCTRCrypto; #endif }; -#endif // __SrtpAESCTRCrypto_H__ \ No newline at end of file +#endif // __SrtpAESCTRCrypto_H__ diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/inc/srtpauthentication_hmac_sha1.h --- a/rtp/srtpstack/inc/srtpauthentication_hmac_sha1.h Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/inc/srtpauthentication_hmac_sha1.h Fri Mar 12 15:44:11 2010 +0200 @@ -23,6 +23,8 @@ #include "msrtpauthentication.h" +class CHMAC; + class CSRTPAuthentication_HMAC_SHA1 : public CBase, public MSRTPAuthentication { public: @@ -64,7 +66,13 @@ */ CSRTPAuthentication_HMAC_SHA1(); - void ConstructL(); + void ConstructL(); + + void CreateHmacL(const TDesC8& aKey); + + private: // data + HBufC8* iKey; + CHMAC* iHmac; }; #endif // __SRTP_AUTHENTICATION_HMAC_SHA1_H__ diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/inc/srtpauthentication_rcc.h --- a/rtp/srtpstack/inc/srtpauthentication_rcc.h Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/inc/srtpauthentication_rcc.h Fri Mar 12 15:44:11 2010 +0200 @@ -23,6 +23,8 @@ #include "msrtpauthentication.h" +class CHMAC; + class CSrtpAuthentication_RCC : public CBase, public MSRTPAuthentication { public: @@ -65,7 +67,13 @@ */ CSrtpAuthentication_RCC(); - void ConstructL(); + void ConstructL(); + + void CreateHmacL(const TDesC8& aKey); + + private: // data + HBufC8* iKey; + CHMAC* iHmac; }; #endif //__SRTP_AUTHENTICATION_RCC_H__ diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/src/srtpaesctrcrypto.cpp --- a/rtp/srtpstack/src/srtpaesctrcrypto.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/src/srtpaesctrcrypto.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -41,6 +41,8 @@ // CSrtpAESCTRCrypto::~CSrtpAESCTRCrypto() { + delete iEncryptor; + delete iKey; } @@ -162,7 +164,6 @@ TBuf8<16> msg; //for a 128-bit piece of a message TInt count=0; // how many full 128-bit pieces can be made of a source - CAESEncryptor* encryptor = NULL; SRTP_DEBUG_TINT_VALUE( "EncryptL, Check aBitLengh ==16 and the length is", aKey.Length() ); @@ -214,7 +215,10 @@ User::Leave(KErrArgument); } - encryptor = CAESEncryptor::NewLC(aKey); + if ( !iEncryptor || !iKey || (*iKey != aKey) ) + { + CreateEncryptorL(aKey); + } for(int x = 0; x < count; x++) { @@ -222,7 +226,7 @@ data.Copy(iv); - encryptor->Transform(data); + iEncryptor->Transform(data); IncreaseIV(iv); @@ -244,7 +248,7 @@ msg.Copy(aSrc.Mid(count*16, bytesleft)); data.Copy(iv); - encryptor->Transform(data); + iEncryptor->Transform(data); // XOR last piece of message with encrypted IV for(int i = 0; i < bytesleft; i++) @@ -256,7 +260,6 @@ } - CleanupStack::PopAndDestroy(encryptor); CleanupStack::Pop(outputBuff); return outputBuff; @@ -302,4 +305,16 @@ } - +// --------------------------------------------------------------------------- +// CSrtpAESCTRCrypto::CreateEncryptorL +// --------------------------------------------------------------------------- +// +void CSrtpAESCTRCrypto::CreateEncryptorL(const TDesC8& aKey) + { + delete iEncryptor; + iEncryptor = 0; + delete iKey; + iKey = 0; + iKey = aKey.AllocL(); + iEncryptor = CAESEncryptor::NewL(*iKey); + } diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/src/srtpauthentication_hmac_sha1.cpp --- a/rtp/srtpstack/src/srtpauthentication_hmac_sha1.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/src/srtpauthentication_hmac_sha1.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -77,11 +77,11 @@ CleanupStack::PushL(result); - CSHA1* sha1 = CSHA1::NewL(); - CleanupStack::PushL(sha1); + if ( !iHmac || !iKey || (*iKey != aKey) ) + { + CreateHmacL(aKey); + } - CHMAC *hmac = CHMAC::NewL(aKey, sha1); - CleanupStack::Pop(sha1); CleanupStack::Pop(result); SRTP_DEBUG_TINT_VALUE( "HMAC INPUT and INPUT Length is ", aAuthPortion.Length() ); @@ -90,18 +90,16 @@ if(aRoc.Length()) { - hmac->Update(DES_AS_8_BIT(aAuthPortion)); - buf.Copy(hmac->Final(DES_AS_8_BIT(aRoc))); + iHmac->Update(DES_AS_8_BIT(aAuthPortion)); + buf.Copy(iHmac->Final(DES_AS_8_BIT(aRoc))); } else { - buf.Copy(hmac->Final(DES_AS_8_BIT(aAuthPortion))); + buf.Copy(iHmac->Final(DES_AS_8_BIT(aAuthPortion))); } *result = buf; ptrOutputBuff.SetLength(aBitLength/8); - delete hmac; - SRTP_DEBUG_DETAIL( "HMAC caculated Authentication tag"); SRTP_DEBUG_PACKET( *result ); SRTP_DEBUG_DETAIL( "CSRTPAuthentication_HMAC_SHA1::AuthenticateL Exit" ); @@ -124,7 +122,9 @@ // --------------------------------------------------------------------------- // CSRTPAuthentication_HMAC_SHA1::~CSRTPAuthentication_HMAC_SHA1() - { + { + delete iHmac; + delete iKey; } // --------------------------------------------------------------------------- @@ -136,3 +136,19 @@ } +// --------------------------------------------------------------------------- +// CSRTPAuthentication_HMAC_SHA1::CreateHmacL +// --------------------------------------------------------------------------- +// +void CSRTPAuthentication_HMAC_SHA1::CreateHmacL(const TDesC8& aKey) + { + delete iHmac; + iHmac = 0; + delete iKey; + iKey = 0; + iKey = aKey.AllocL(); + CSHA1* sha1 = CSHA1::NewL(); + CleanupStack::PushL(sha1); + iHmac = CHMAC::NewL(*iKey, sha1); + CleanupStack::Pop(sha1); + } diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/src/srtpauthentication_rcc.cpp --- a/rtp/srtpstack/src/srtpauthentication_rcc.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/src/srtpauthentication_rcc.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -77,11 +77,11 @@ CleanupStack::PushL(result); - CSHA1* sha1 = CSHA1::NewL(); - CleanupStack::PushL(sha1); - - CHMAC *hmac = CHMAC::NewL(aKey, sha1); - CleanupStack::Pop(sha1); + if ( !iHmac || !iKey || (*iKey != aKey) ) + { + CreateHmacL(aKey); + } + CleanupStack::Pop(result); SRTP_DEBUG_TINT_VALUE( "HMAC INPUT and INPUT Length is ", aAuthPortion.Length()); SRTP_DEBUG_TINT_VALUE( "HMAC INPUT and INPUT Size is ", aAuthPortion.Size()); @@ -89,17 +89,16 @@ if(aRoc.Length()) { - hmac->Update(DES_AS_8_BIT(aAuthPortion)); - buf.Copy(hmac->Final(DES_AS_8_BIT(aRoc))); + iHmac->Update(DES_AS_8_BIT(aAuthPortion)); + buf.Copy(iHmac->Final(DES_AS_8_BIT(aRoc))); } else { - buf.Copy(hmac->Final(DES_AS_8_BIT(aAuthPortion))); + buf.Copy(iHmac->Final(DES_AS_8_BIT(aAuthPortion))); } *result = buf; ptrOutputBuff.SetLength(aBitLength/8); - delete hmac; SRTP_DEBUG_DETAIL( "HMAC caculated Authentication tag" ); SRTP_DEBUG_PACKET( *result ); @@ -124,6 +123,8 @@ // CSrtpAuthentication_RCC::~CSrtpAuthentication_RCC() { + delete iHmac; + delete iKey; } // --------------------------------------------------------------------------- @@ -135,3 +136,20 @@ } +// --------------------------------------------------------------------------- +// CSrtpAuthentication_RCC::CreateHmacL +// --------------------------------------------------------------------------- +// +void CSrtpAuthentication_RCC::CreateHmacL(const TDesC8& aKey) + { + delete iHmac; + iHmac = 0; + delete iKey; + iKey = 0; + iKey = aKey.AllocL(); + CSHA1* sha1 = CSHA1::NewL(); + CleanupStack::PushL(sha1); + iHmac = CHMAC::NewL(*iKey, sha1); + CleanupStack::Pop(sha1); + } + diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/tsrc/ut_srtpstack/inc/UT_CSRTPCipherAESCM128.h --- a/rtp/srtpstack/tsrc/ut_srtpstack/inc/UT_CSRTPCipherAESCM128.h Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/tsrc/ut_srtpstack/inc/UT_CSRTPCipherAESCM128.h Fri Mar 12 15:44:11 2010 +0200 @@ -71,6 +71,8 @@ void UT_EncryptL_EncryptData3L(); void UT_EncryptL_EncryptData4L(); + + void UT_EncryptL_EncryptDataKeyChangesL(); void UT_EncryptL_DecryptDataL(); @@ -79,6 +81,8 @@ void UT_EncryptL_DecryptData3L(); void UT_EncryptL_DecryptData4L(); + + void UT_EncryptL_DecryptDataKeyChangesL(); void UT_EncryptL_ErrorTest1L(); diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/tsrc/ut_srtpstack/inc/UT_CSrtpAuthentication_RCC.h --- a/rtp/srtpstack/tsrc/ut_srtpstack/inc/UT_CSrtpAuthentication_RCC.h Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/tsrc/ut_srtpstack/inc/UT_CSrtpAuthentication_RCC.h Fri Mar 12 15:44:11 2010 +0200 @@ -94,6 +94,8 @@ void UT_AuthenticateL_RFC2202_Test7_80L(); void UT_AuthenticateL_RFC2202_Test7_32L(); void UT_AuthenticateL_Test8_32L( ); + void UT_AuthenticateL_Test_KeyChangedL(); + private: // Data CSrtpAuthentication_RCC* iAuthenticator; diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/tsrc/ut_srtpstack/inc/UT_SRTPAuthentication_HMAC_SHA1.h --- a/rtp/srtpstack/tsrc/ut_srtpstack/inc/UT_SRTPAuthentication_HMAC_SHA1.h Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/tsrc/ut_srtpstack/inc/UT_SRTPAuthentication_HMAC_SHA1.h Fri Mar 12 15:44:11 2010 +0200 @@ -82,6 +82,7 @@ void UT_AuthenticateL_RFC2202_Test7_80L(); void UT_AuthenticateL_RFC2202_Test7_32L(); void UT_AuthenticateL_Test8_32L( ); + void UT_AuthenticateL_Test_KeyChangedL(); void Hex(HBufC8& aString); diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/tsrc/ut_srtpstack/src/UT_CSRTPCipherAESCM128.cpp --- a/rtp/srtpstack/tsrc/ut_srtpstack/src/UT_CSRTPCipherAESCM128.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/tsrc/ut_srtpstack/src/UT_CSRTPCipherAESCM128.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -23,6 +23,7 @@ // EXTERNAL INCLUDES #include +#include // INTERNAL INCLUDES #include "srtpcipher_aescm128.h" @@ -212,7 +213,7 @@ EUNIT_ASSERT( result->Compare(*iRFC3686_TestCipherT256bits) == 0); CleanupStack::Pop(result); - delete result; + delete result; } void UT_CSRTPCipherAESCM128::UT_EncryptL_EncryptData3L( ) @@ -243,6 +244,12 @@ delete result; } +void UT_CSRTPCipherAESCM128::UT_EncryptL_EncryptDataKeyChangesL( ) + { + UT_EncryptL_EncryptDataL(); + UT_EncryptL_EncryptData2L(); + } + void UT_CSRTPCipherAESCM128::UT_EncryptL_DecryptDataL( ) { HBufC8* result = iEncryptor->TransformL(*iRFC3686_TestKey128bits, @@ -254,7 +261,7 @@ EUNIT_ASSERT( result->Compare(*iRFC3686_TestPlainT128bits) == 0); CleanupStack::Pop(result); - delete result; + delete result; } void UT_CSRTPCipherAESCM128::UT_EncryptL_DecryptData2L( ) @@ -299,6 +306,12 @@ delete result; } +void UT_CSRTPCipherAESCM128::UT_EncryptL_DecryptDataKeyChangesL( ) + { + UT_EncryptL_DecryptDataL(); + UT_EncryptL_DecryptData2L(); + } + void UT_CSRTPCipherAESCM128::UT_EncryptL_ErrorTest1L( ) { TInt err = KErrNone; @@ -417,6 +430,13 @@ SetupL, UT_EncryptL_EncryptData4L, Teardown) EUNIT_TEST( + "EncryptL encrypt data, key changes", + "CSRTPCipherAESCM128", + "EncryptL", + "FUNCTIONALITY", + SetupL, UT_EncryptL_EncryptDataKeyChangesL, Teardown) + +EUNIT_TEST( "EncryptL decrypt data", "CSRTPCipherAESCM128", "EncryptL", @@ -443,6 +463,13 @@ "EncryptL", "FUNCTIONALITY", SetupL, UT_EncryptL_DecryptData4L, Teardown) + +EUNIT_TEST( + "EncryptL decrypt data, key changes", + "CSRTPCipherAESCM128", + "EncryptL", + "FUNCTIONALITY", + SetupL, UT_EncryptL_DecryptDataKeyChangesL, Teardown) EUNIT_TEST( "EncryptL error 1", diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/tsrc/ut_srtpstack/src/UT_CSrtpAuthentication_RCC.cpp --- a/rtp/srtpstack/tsrc/ut_srtpstack/src/UT_CSrtpAuthentication_RCC.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/tsrc/ut_srtpstack/src/UT_CSrtpAuthentication_RCC.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -591,6 +591,12 @@ CleanupStack::PopAndDestroy(result); } +void UT_CSrtpAuthentication_RCC::UT_AuthenticateL_Test_KeyChangedL() +{ + UT_AuthenticateL_RFC2202_Test2_80L(); + UT_AuthenticateL_RFC2202_Test3_80L(); +} + void UT_CSrtpAuthentication_RCC::Hex(HBufC8& aString) { TPtr8 ptr=aString.Des(); @@ -722,7 +728,13 @@ "AuthenticateL with Real Packet", "FUNCTIONALITY", SetupL, UT_AuthenticateL_Test8_32L, Teardown) - + +EUNIT_TEST( + "AuthenticateL - KeyChanged", + "CSrtpAuthentication_RCC", + "AuthenticateL", + "FUNCTIONALITY", + SetupL, UT_AuthenticateL_Test_KeyChangedL, Teardown) EUNIT_END_TEST_TABLE diff -r dd3853b8dc3f -r 1e1cc61f56c3 rtp/srtpstack/tsrc/ut_srtpstack/src/UT_SRTPAuthentication_HMAC_SHA1.cpp --- a/rtp/srtpstack/tsrc/ut_srtpstack/src/UT_SRTPAuthentication_HMAC_SHA1.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/rtp/srtpstack/tsrc/ut_srtpstack/src/UT_SRTPAuthentication_HMAC_SHA1.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -630,6 +630,12 @@ CleanupStack::PopAndDestroy(result); } +void UT_SRTPAuthentication_HMAC_SHA1::UT_AuthenticateL_Test_KeyChangedL( ) + { + UT_AuthenticateL_RFC2202_Test1_80L(); + UT_AuthenticateL_RFC2202_Test1_32L(); + } + void UT_SRTPAuthentication_HMAC_SHA1::Hex(HBufC8& aString) { TPtr8 ptr=aString.Des(); @@ -762,7 +768,13 @@ "FUNCTIONALITY", SetupL, UT_AuthenticateL_Test8_32L, Teardown) - +EUNIT_TEST( + "AuthenticateL - KeyChanged", + "SRTPAuthentication_HMAC_SHA1", + "AuthenticateL", + "FUNCTIONALITY", + SetupL, UT_AuthenticateL_Test_KeyChangedL, Teardown) + EUNIT_END_TEST_TABLE // END OF FILE diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsipsettingsui/src/gssipmodel.cpp --- a/sipplugins/sippsipsettingsui/src/gssipmodel.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/sipplugins/sippsipsettingsui/src/gssipmodel.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -1205,7 +1205,9 @@ { profile->GetParameter( KSIPDefaultProfile, aDefault ); profile->GetParameter( KSIPProfileLocked, aLocked ); - aIsUse = iEngine->IsInUseL( *profile ); + TUint32 profileId; + profile->GetParameter( KSIPProfileId, profileId ); + aIsUse = CheckIsProfileInUseL( profileId ); } __GSLOGSTRING("CGSSIPModel::CheckProfileForDeleteL End" ) } @@ -1224,6 +1226,10 @@ if ( profile ) { profile->GetParameter( KSIPProfileRegistered, inUse ); + if ( !inUse ) + { + inUse = iEngine->IsInUseL( *profile ); + } } return inUse; diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsipsettingsui/src/sipsettingsmodel.cpp --- a/sipplugins/sippsipsettingsui/src/sipsettingsmodel.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/sipplugins/sippsipsettingsui/src/sipsettingsmodel.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -18,7 +18,7 @@ // INCLUDE FILES - +#include #include #include #include @@ -111,7 +111,18 @@ TInt aIndex ) { __GSLOGSTRING1("CSIPSettingsModel::SetDefaultProfileL index: %d", aIndex) - iHandler->SetDefaultProfileL( aIndex ); + TRAPD(err, iHandler->SetDefaultProfileL( aIndex )); + if ( err == KErrInUse ) + { + HBufC* txtErr = StringLoader::LoadLC( R_QTN_SIP_ERROR_PROFILE_USED ); + CAknErrorNote* note = new ( ELeave ) CAknErrorNote( ETrue ); + note->ExecuteLD( txtErr->Des() ); + CleanupStack::PopAndDestroy( txtErr ); + } + else + { + User::Leave( err ); + } } // ----------------------------------------------------------------------------- diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsystemstatemonitor/group/sipsystemstatemonitor.mmp --- a/sipplugins/sippsystemstatemonitor/group/sipsystemstatemonitor.mmp Fri Feb 19 23:10:33 2010 +0200 +++ b/sipplugins/sippsystemstatemonitor/group/sipsystemstatemonitor.mmp Fri Mar 12 15:44:11 2010 +0200 @@ -29,6 +29,7 @@ SOURCE CSystemStateConnUsagePermissionMonitor.cpp SOURCE siprfsmonitorao.cpp SOURCE sipdevicestateaware.cpp +SOURCE sipvpnmonitorao.cpp SOURCEPATH ../data START RESOURCE 10283311.rss @@ -46,6 +47,7 @@ LIBRARY connmon.lib LIBRARY centralrepository.lib LIBRARY ssmcmn.lib +LIBRARY featmgr.lib VENDORID VID_DEFAULT diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsystemstatemonitor/inc/sipdevicestateaware.h --- a/sipplugins/sippsystemstatemonitor/inc/sipdevicestateaware.h Fri Feb 19 23:10:33 2010 +0200 +++ b/sipplugins/sippsystemstatemonitor/inc/sipdevicestateaware.h Fri Mar 12 15:44:11 2010 +0200 @@ -49,14 +49,6 @@ * to stop themselves getting notified for system state changes */ void RemoveObserver( MSipSystemStateObserver& aObserver ); - - /** - * In case if profile de-registration could not be completed by - * observers, TimerExpiredL will call this function to indicate - * that event processing is complete and further notification will - * be given to the System State Manager. - */ - void EventProcessingCompleted(); /** * In case if the profiles de-registration is completed within the @@ -75,6 +67,7 @@ //Destructor ~CSipDeviceStateAware(); + private: //Default Construtor CSipDeviceStateAware(); @@ -90,6 +83,15 @@ * state of the phone changes */ void NotifyObservers(CSipSystemStateMonitor::TSystemState aState) const; + + /** + * In case if profile de-registration could not be completed by + * observers, TimerExpiredL will call this function to indicate + * that event processing is complete and further notification will + * be given to the System State Manager. + */ + void EventProcessingCompleted(); + private: //List of observers who have opted for system state changes diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsystemstatemonitor/inc/siprfsmonitorao.h --- a/sipplugins/sippsystemstatemonitor/inc/siprfsmonitorao.h Fri Feb 19 23:10:33 2010 +0200 +++ b/sipplugins/sippsystemstatemonitor/inc/siprfsmonitorao.h Fri Mar 12 15:44:11 2010 +0200 @@ -41,8 +41,6 @@ void RemoveObserver( MSipSystemStateObserver& aObserver ); void EventProcessingCompleted(MSipSystemStateObserver& aObserver); TBool MappedState(TInt aState); - void EventProcessingCompleted(); - static TInt TimerExpired(TAny* aSelf); private: void NotifyObservers(); @@ -58,7 +56,6 @@ RPointerArray iObservers; RProperty iProperty; CSipSystemStateMonitor::TRfsState iState; - CPeriodic* iGuardTimer; private: // For testing purposes friend class CSipRfsMonitorAoTestApp; diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsystemstatemonitor/inc/sipsystemstatemonitorimpl.h --- a/sipplugins/sippsystemstatemonitor/inc/sipsystemstatemonitorimpl.h Fri Feb 19 23:10:33 2010 +0200 +++ b/sipplugins/sippsystemstatemonitor/inc/sipsystemstatemonitorimpl.h Fri Mar 12 15:44:11 2010 +0200 @@ -29,6 +29,8 @@ class CSystemStateConnUsagePermissionMonitor; class CSipDeviceStateAware; class CSipRfsMonitorAo; +class CSipVpnMonitorAo; + // CLASS DECLARATION /** * The default implementation for Sip System State Monitor. @@ -78,6 +80,9 @@ CSystemStateConnUsagePermissionMonitor* iUsagePermissionMonitor; CSipRfsMonitorAo* iRfsMonitor; CSipDeviceStateAware* iSipDeviceAwareObject; + + // P&S monitor for SIP / VPN communication + CSipVpnMonitorAo* iVpnMonitor; private: // For testing purposes diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsystemstatemonitor/inc/sipvpnmonitorao.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sipplugins/sippsystemstatemonitor/inc/sipvpnmonitorao.h Fri Mar 12 15:44:11 2010 +0200 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 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 : P&S key monitor for communication between SIP Profile +* server and VPN client +* Name : sipvpnmonitorao.cpp +* Part of : Sip System State Monitor +* Version : 1.0 +* +*/ + +#ifndef SIPVPNMONITORAO_H +#define SIPVPNMONITORAO_H + +// INCLUDES +#include +#include +#include +#include +#include + +class CSipVpnMonitorAo : public CActive + { + public: // Constructors and destructor + static CSipVpnMonitorAo* NewL(); + ~CSipVpnMonitorAo(); + + private: // Constructors + CSipVpnMonitorAo(); + void ConstructL(); + + public: // New Functions + CSipSystemStateMonitor::TVpnState State() const; + void AddObserverL( MSipSystemStateObserver& aObserver ); + void RemoveObserver( MSipSystemStateObserver& aObserver ); + void EventProcessingCompleted(MSipSystemStateObserver& aObserver); + TBool MappedState(TInt aState); + static TInt TimerExpired(TAny* aSelf); + + private: + void NotifyObservers(); + void EventProcessingCompleted(); + private: // From CActive + void RunL(); + TInt RunError( TInt aError ); + void DoCancel(); + + private: // Data + TInt iCount; + // Observers not owned + RPointerArray iObservers; + RProperty iProperty; + CSipSystemStateMonitor::TVpnState iState; + CPeriodic* iGuardTimer; + + private: // For testing purposes + friend class CSipVpnMonitorAoTestApp; + }; +#endif /* SIPVPNMONITORAO_H */ diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsystemstatemonitor/src/siprfsmonitorao.cpp --- a/sipplugins/sippsystemstatemonitor/src/siprfsmonitorao.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/sipplugins/sippsystemstatemonitor/src/siprfsmonitorao.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -23,9 +23,6 @@ _LIT_SECURITY_POLICY_PASS( KSIPRfsAlwaysPass ); -static const TInt KMicroSecondsInSecond = 1000000; -static const TInt KGuardTimerSeconds = 20; - // ----------------------------------------------------------------------------- // CSipRfsMonitorAo::NewL // ----------------------------------------------------------------------------- @@ -45,7 +42,6 @@ // void CSipRfsMonitorAo::ConstructL () { - iGuardTimer = CPeriodic::NewL( EPriorityNormal ); TInt err = iProperty.Define( KPSSipRfsUid, KSipRfsState, RProperty::EInt, KSIPRfsAlwaysPass, KSIPRfsAlwaysPass); if ( KErrNone != err && KErrAlreadyExists != err && @@ -76,12 +72,6 @@ // CSipRfsMonitorAo::~CSipRfsMonitorAo() { - if(iGuardTimer) - { - iGuardTimer->Cancel(); - delete iGuardTimer; - iGuardTimer = NULL; - } CActive::Cancel(); iProperty.Close(); iProperty.Delete(KPSSipRfsUid,KSipRfsState); @@ -124,16 +114,7 @@ CSipSystemStateMonitor::ERfsState, 0, iState); - } - if(iObservers.Count() && iState == CSipSystemStateMonitor::ERfsStarted) - { - iGuardTimer->Cancel(); - iGuardTimer->Start( - TTimeIntervalMicroSeconds32( KGuardTimerSeconds * KMicroSecondsInSecond ), - TTimeIntervalMicroSeconds32( KGuardTimerSeconds * KMicroSecondsInSecond ), - TCallBack( TimerExpired, this ) ); - } - + } } // ----------------------------------------------------------------------------- @@ -150,30 +131,21 @@ // ----------------------------------------------------------------------------- // void CSipRfsMonitorAo::EventProcessingCompleted( - MSipSystemStateObserver& /*aObserver*/ ) - { - } - -// ----------------------------------------------------------------------------- -// CSipRfsMonitorAo::EventProcessingCompleted -// ----------------------------------------------------------------------------- -// -void CSipRfsMonitorAo::EventProcessingCompleted() + MSipSystemStateObserver& aObserver ) { - iGuardTimer->Cancel(); - iProperty.Set(KPSSipRfsUid, KSipRfsState, ESipRfsEventProcessingCompleted ); - iCount = 0; - } - -// ----------------------------------------------------------------------------- -// CSipRfsMonitorAo::TimerExpired -// ----------------------------------------------------------------------------- -// -TInt CSipRfsMonitorAo::TimerExpired(TAny* aSelf) - { - CSipRfsMonitorAo* self = reinterpret_cast(aSelf); - self->EventProcessingCompleted(); - return ETrue; + if (iState == CSipSystemStateMonitor::ERfsStarted) + { + TInt index = iObservers.Find( &aObserver ); + if ( index >= 0 ) + { + iCount++; + if( iObservers.Count() == iCount) + { + iProperty.Set(KPSSipRfsUid, KSipRfsState, ESipRfsEventProcessingCompleted ); + iCount = 0; + } + } + } } // ----------------------------------------------------------------------------- diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsystemstatemonitor/src/sipsystemstatemonitorao.cpp --- a/sipplugins/sippsystemstatemonitor/src/sipsystemstatemonitorao.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/sipplugins/sippsystemstatemonitor/src/sipsystemstatemonitorao.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -180,5 +180,7 @@ { return ( aSystemState == ESwStateNormalRfOn || aSystemState == ESwStateNormalRfOff || - aSystemState == ESwStateNormalBTSap ); + aSystemState == ESwStateNormalBTSap || + aSystemState == ESwStateEmergencyCallsOnly || + aSystemState == ESwStateSecurityCheck); } diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsystemstatemonitor/src/sipsystemstatemonitorimpl.cpp --- a/sipplugins/sippsystemstatemonitor/src/sipsystemstatemonitorimpl.cpp Fri Feb 19 23:10:33 2010 +0200 +++ b/sipplugins/sippsystemstatemonitor/src/sipsystemstatemonitorimpl.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -21,6 +21,8 @@ #include "CSystemStateConnUsagePermissionMonitor.h" #include "sipdevicestateaware.h" #include "siprfsmonitorao.h" +#include "sipvpnmonitorao.h" +#include // for Feature Manager // ----------------------------------------------------------------------------- // CSipSystemStateMonitorImpl::NewL @@ -62,6 +64,13 @@ // CSipSystemStateMonitorImpl::~CSipSystemStateMonitorImpl() { + // iVpnMonitor is created in StartMonitoringL(). + if ( FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) ) + { + delete iVpnMonitor; + iVpnMonitor = NULL; + } + delete iMonitorAo; iSnapMonitors.ResetAndDestroy(); delete iUsagePermissionMonitor; @@ -116,6 +125,16 @@ iRfsMonitor = iRfsMonitor?iRfsMonitor:CSipRfsMonitorAo::NewL(); iRfsMonitor->AddObserverL( aObserver ); } + // CSipVpnMonitorAo is created for P&S key change monitoring. + else if ( FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && ( aVariable == EVpnState ) ) + { + if ( !iVpnMonitor ) + { + iVpnMonitor = CSipVpnMonitorAo::NewL(); + } + iVpnMonitor->AddObserverL( aObserver ); + } else { User::Leave( KErrNotSupported ); @@ -155,6 +174,15 @@ if(iRfsMonitor) iRfsMonitor->RemoveObserver( aObserver ); } + // Remove the client as an observer when stops VPN P&S key monitoring. + else if ( FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && ( aVariable == EVpnState ) ) + { + if ( iVpnMonitor ) + { + iVpnMonitor->RemoveObserver( aObserver ); + } + } } // ----------------------------------------------------------------------------- @@ -188,6 +216,15 @@ if(iRfsMonitor) iRfsMonitor->State(); } + else if ( FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && ( aVariable == EVpnState ) ) + { + if( iVpnMonitor ) + { + return iVpnMonitor->State(); + } + } + return KErrNotFound; } @@ -208,6 +245,13 @@ { iSipDeviceAwareObject->EventProcessingCompleted(aObserver); } + // SIP deregistration for VPN session has been completed. + else if ( FeatureManager::FeatureSupported( KFeatureIdFfImsDeregistrationInVpn ) + && ( aVariable == EVpnState ) + && iVpnMonitor ) + { + iVpnMonitor->EventProcessingCompleted(aObserver); + } } // ----------------------------------------------------------------------------- diff -r dd3853b8dc3f -r 1e1cc61f56c3 sipplugins/sippsystemstatemonitor/src/sipvpnmonitorao.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sipplugins/sippsystemstatemonitor/src/sipvpnmonitorao.cpp Fri Mar 12 15:44:11 2010 +0200 @@ -0,0 +1,275 @@ +/* +* Copyright (c) 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 : P&S key monitor for communication between SIP Profile +* server and VPN client +* Name : sipvpnmonitorao.cpp +* Part of : Sip System State Monitor +* Version : 1.0 +* +*/ + +// INCLUDE FILES +#include "sipvpnmonitorao.h" +#include +#include + +_LIT_SECURITY_POLICY_PASS( KSIPVpnAlwaysPass ); + +static const TInt KMicroSecondsInSecond = 1000000; +static const TInt KGuardTimerSeconds = 10; + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::NewL +// ----------------------------------------------------------------------------- +// +CSipVpnMonitorAo* CSipVpnMonitorAo::NewL() + { + CSipVpnMonitorAo* self = new( ELeave )CSipVpnMonitorAo(); + + CleanupStack::PushL ( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::ConstructL +// ----------------------------------------------------------------------------- +// +void CSipVpnMonitorAo::ConstructL() + { + iGuardTimer = CPeriodic::NewL( EPriorityNormal ); + + // Define a P&S key for communication between SIP Profile Server and VPN client. + TInt err = iProperty.Define( KPSVpnSipUid, KVpnSipState, RProperty::EInt, + KSIPVpnAlwaysPass, KSIPVpnAlwaysPass ); + if ( KErrNone != err && KErrAlreadyExists != err && + KErrPermissionDenied != err ) + { + User::Leave( err ); + } + + User::LeaveIfError( iProperty.Attach( KPSVpnSipUid, KVpnSipState ) ); + + iProperty.Subscribe( iStatus ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::CSipVpnMonitorAo +// ----------------------------------------------------------------------------- +// +CSipVpnMonitorAo::CSipVpnMonitorAo(): + CActive(EPriorityStandard) + { + CActiveScheduler::Add( this ); + iCount = 0; + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::~CSipVpnMonitorAo +// ----------------------------------------------------------------------------- +// +CSipVpnMonitorAo::~CSipVpnMonitorAo() + { + if ( iGuardTimer ) + { + iGuardTimer->Cancel(); + delete iGuardTimer; + iGuardTimer = NULL; + } + + CActive::Cancel(); + + iProperty.Close(); + iProperty.Delete( KPSVpnSipUid, KVpnSipState ); + + iObservers.Close(); + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::AddObserverL +// ----------------------------------------------------------------------------- +// +void CSipVpnMonitorAo::AddObserverL( + MSipSystemStateObserver& aObserver ) + { + iObservers.InsertInAddressOrderL( &aObserver ); + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::RemoveObserver +// ----------------------------------------------------------------------------- +// +void CSipVpnMonitorAo::RemoveObserver( + MSipSystemStateObserver& aObserver ) + { + TInt index = iObservers.Find( &aObserver ); + if ( index >= 0 ) + { + iObservers.Remove( index ); + } + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::NotifyObservers +// ----------------------------------------------------------------------------- +// +void CSipVpnMonitorAo::NotifyObservers() + { + // Notify observers (SIP Profile Server) about the P&S key change. + for ( TInt i = iObservers.Count()-1; i >= 0; i-- ) + { + iObservers[i]->SystemVariableUpdated( + CSipSystemStateMonitor::EVpnState, + 0, + iState); + } + + // Start a guard timer so that VPN client don't wait forever for completion + // of deregistration. + if ( iObservers.Count() && iState == CSipSystemStateMonitor::EVpnInitiating ) + { + iGuardTimer->Cancel(); + iGuardTimer->Start( + TTimeIntervalMicroSeconds32( KGuardTimerSeconds * KMicroSecondsInSecond ), + TTimeIntervalMicroSeconds32( KGuardTimerSeconds * KMicroSecondsInSecond ), + TCallBack( TimerExpired, this ) ); + } + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::State +// ----------------------------------------------------------------------------- +// +CSipSystemStateMonitor::TVpnState CSipVpnMonitorAo::State() const + { + return iState; + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::EventProcessingCompleted +// ----------------------------------------------------------------------------- +// +void CSipVpnMonitorAo::EventProcessingCompleted( + MSipSystemStateObserver& aObserver ) + { + if (iState == CSipSystemStateMonitor::EVpnInitiating) + { + TInt index = iObservers.Find( &aObserver ); + if ( index >= 0 ) + { + iCount++; + if( iObservers.Count() == iCount) + { + iGuardTimer->Cancel(); + iProperty.Set(KPSVpnSipUid, KVpnSipState, ESipDeregisterCompleted ); + iCount = 0; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::EventProcessingCompleted +// ----------------------------------------------------------------------------- +// +void CSipVpnMonitorAo::EventProcessingCompleted() + { + // SIP deregistration has been completed. Stop the guard timer and tell + // the VPN client about it. + iGuardTimer->Cancel(); + + iProperty.Set( KPSVpnSipUid, KVpnSipState, ESipDeregisterCompleted ); + iCount = 0; + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::TimerExpired +// ----------------------------------------------------------------------------- +// +TInt CSipVpnMonitorAo::TimerExpired(TAny* aSelf) + { + // Guard timer expired. Tell VPN client to proceed its work without + // further waiting. + CSipVpnMonitorAo* self = reinterpret_cast(aSelf); + self->EventProcessingCompleted(); + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::RunL +// ----------------------------------------------------------------------------- +// +void CSipVpnMonitorAo::RunL() + { + TInt state( 0 ); + + // VPN client notifies that it has started a VPN session. + if ( KErrNone == iProperty.Get( state ) ) + { + if ( MappedState( state ) ) + { + NotifyObservers(); + } + } + + iProperty.Subscribe( iStatus ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::RunError +// ----------------------------------------------------------------------------- +// +TInt CSipVpnMonitorAo::RunError( TInt /*aError*/ ) + { + return KErrNone; // RunL cannot leave at the moment + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::DoCancel +// ----------------------------------------------------------------------------- +// +void CSipVpnMonitorAo::DoCancel() + { + iProperty.Cancel(); + } + +// ----------------------------------------------------------------------------- +// CSipVpnMonitorAo::MappedState +// ----------------------------------------------------------------------------- +// +TBool CSipVpnMonitorAo::MappedState( TInt aState ) + { + TBool ret = ETrue; + // Maps P&S key value to VPN state. + switch( aState ) + { + case EVpnInitiating: + iState = CSipSystemStateMonitor::EVpnInitiating; + break; + case EVpnTerminated: + iState = CSipSystemStateMonitor::EVpnTerminated; + break; + // Other P&S key values are not mapped to VPN state. + // Not an error situation. + default: + ret = EFalse; + } + + return ret; + }