diff -r 307788aac0a8 -r 8248b03a2669 realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileServerCore.cpp --- a/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileServerCore.cpp Tue Feb 02 01:03:15 2010 +0200 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileServerCore.cpp Fri Apr 16 15:18:54 2010 +0300 @@ -48,8 +48,16 @@ #include #include #include +#include // for Feature Manager +#include +#include +#include +using namespace CommsDat; +const TInt KMicroSecInSec = 1000000; +const TInt KIdleTimer = 2; + // ============================ MEMBER FUNCTIONS =============================== // ----------------------------------------------------------------------------- @@ -82,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), @@ -90,6 +99,8 @@ iMigrationControllers(1) #endif { + iFeatMgrInitialized = EFalse; + iDeltaTimerEntry.Set(iDeltaTimerCallBack); } // ----------------------------------------------------------------------------- @@ -99,6 +110,11 @@ void CSIPProfileServerCore::ConstructL() { User::LeaveIfError(iFs.Connect()); + + FeatureManager::InitializeLibL(); + iFeatMgrInitialized = ETrue; + + iDeltaTimer = CDeltaTimer::NewL(CActive::EPriorityStandard); iFindEntry = CSIPProfileCacheItem::NewL(*this, iUnregistered); @@ -144,6 +160,8 @@ *iUnregistered); iUnregisteringOldIAP->SetNeighbourStates(*iRegistered, *iUnregInProg); + iApnManager = CSIPApnManager::NewL( *this ); + LoadSystemStateMonitorL(); iAlrHandler = CSipAlrHandler::NewL(*this,iSystemStateMonitor); @@ -197,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") @@ -266,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(); } @@ -430,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 && @@ -445,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) @@ -460,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) @@ -492,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 @@ -820,6 +905,11 @@ return EFalse; } } + if (iApnManager->HasPendingTasks()) + { + PROFILE_DEBUG1("ApnManager has pending tasks, do not stop server yet") + return EFalse; + } return ETrue; } @@ -900,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( KFeatureIdFfSipApnSwitching)) + { + 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( KFeatureIdFfSipApnSwitching) + && 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); @@ -923,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( KFeatureIdFfSipApnSwitching ) + && 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(); } @@ -946,10 +1130,10 @@ // CSIPConcreteProfile::TStatus CSIPProfileServerCore::ForceDisableProfileL( TUint32 aProfileId, - const MSIPExtendedConcreteProfileObserver& aObserver) + const MSIPExtendedConcreteProfileObserver& /* aObserver */) { CSIPProfileCacheItem* item = ProfileCacheItemL(aProfileId); - (void)aObserver; + //When profile state is not unregistered, //perform cleanup and send event notification @@ -984,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( KFeatureIdFfSipApnSwitching ) + &&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, @@ -1401,6 +1615,10 @@ SendErrorEvent(aItem, aStatus, aError); } } + if(aItem.IsApnSwitchEnabled()) + { + UseBackupApn(aItem.Profile().IapId(), ETrue); + } } // ----------------------------------------------------------------------------- @@ -1736,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(); @@ -1771,26 +1996,37 @@ TBool CSIPProfileServerCore::ShouldChangeIap(CSIPConcreteProfile& aProfile, TInt aError) const { PROFILE_DEBUG3("CSIPProfileServerCore::ShouldChangeIap, error", aError) - TUint32 dummySnapId(0); - if ( aProfile.ExtensionParameter(KSIPSnapId, dummySnapId) == KErrNone && - !AnyRegisteredProfileUsesIap(aProfile.IapId()) ) + TUint32 snapId(0); + if ( aProfile.ExtensionParameter(KSIPSnapId, snapId) == KErrNone + && !AnyRegisteredProfileUsesIap(aProfile.IapId()) ) { PROFILE_DEBUG1("CSIPProfileServerCore::ShouldChangeIap, snap is in use") // This profile uses a SNAP. // There are no registered profiles using the same IAP as this profile. - - if ( aError == KErrTimedOut || - aError == KErrSIPResolvingFailure ) - { - PROFILE_DEBUG1("CSIPProfileServerCore::ShouldChangeIap returns True") - return ETrue; - } - } + + TUint iapCount(0); + TRAPD(err, iapCount = IAPCountL(snapId)); + if(KErrNone == err) + { + if ( (aError == KErrTimedOut || + aError == KErrSIPResolvingFailure) + && iapCount > 1) + { + PROFILE_DEBUG1("CSIPProfileServerCore::ShouldChangeIap returns True") + return ETrue; + } + } + + } PROFILE_DEBUG1("CSIPProfileServerCore::ShouldChangeIap returns false") return EFalse; } - + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::AnyRegisteredProfileUsesIap +// ----------------------------------------------------------------------------- +// TBool CSIPProfileServerCore::AnyRegisteredProfileUsesIap(TUint aIap) const { @@ -1839,3 +2075,270 @@ aItem.Profile().Status(), ESipProfileItcOpProfileForciblyDisabled)); } } + + +// ----------------------------------------------------------------------------- +// CSIPProfileServerCore::IAPCount +// ----------------------------------------------------------------------------- +// +TInt CSIPProfileServerCore::IAPCountL(TUint32 aSnapId) const + { + const TUint KRecordId = aSnapId; + TUint32 count(0); + CMDBSession* db = CMDBSession::NewLC( KCDVersion1_2); + db->SetAttributeMask( ECDHidden ); + + //Load the Selection Policy record + CCDIAPPrioritySelectionPolicyRecord *selPolRecord = (CCDIAPPrioritySelectionPolicyRecord *)CCDRecordBase::RecordFactoryL(KCDTIdIapPrioritySelectionPolicyRecord); + + CleanupStack::PushL(selPolRecord); + selPolRecord->SetRecordId(KRecordId); + + selPolRecord->LoadL( *db ); + count = selPolRecord->iIapCount; + PROFILE_DEBUG3("CSIPProfileServerCore::IAPCount, IAP Count", count) + + CleanupStack::PopAndDestroy(selPolRecord); + 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())); + }