--- 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 <siperr.h>
#include <sipsystemstatemonitor.h>
#include <random.h>
+#include <featmgr.h> // for Feature Manager
+#include <commsdattypesv1_1.h>
+#include <metadatabase.h>
+#include <commsdattypeinfov1_1_internal.h>
+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<CSIPProfileServerCore*>(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()));
+ }