coreapplicationuis/Rfs/src/rfsConnectionObserver.cpp
changeset 0 2e3d3ce01487
child 18 0818dd463d41
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 /*
       
     2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *   Implements CRfsPdpObserver class.
       
    16 *
       
    17 *
       
    18 */
       
    19 
       
    20 // SYSTEM INCLUDES
       
    21 #include <rfs.rsg>                      
       
    22 #include <PSVariables.h>
       
    23 #include <AknWaitDialog.h>
       
    24 #include <featmgr.h>
       
    25 #include <centralrepository.h>
       
    26 #include <AknWaitDialog.h>
       
    27 #include <pdpcontextmanagerpskeys.h>
       
    28 #include <pdpcontextmanagerinternalcrkeys.h>
       
    29 
       
    30 // P&S KEYS FROM SIP & PDP CONNECTION
       
    31 #include <e32property.h>
       
    32 #include <pdpcontextmanagerpskeys.h>
       
    33 #include <sipsystemstatemonitorpskeys.h>
       
    34 
       
    35 // USER INCLUDES
       
    36 #include "rfsConnectionObserver.h"
       
    37 #include "RfsTraces.h"
       
    38 
       
    39 // CONSTANTS
       
    40 const TInt KRfsAlwaysOnDisabled     = 0;
       
    41 const TInt KRfsAlwaysOnEnabled      = 1;
       
    42 
       
    43 
       
    44 // ---------------------------------------------------------------------------
       
    45 // two phased constructor
       
    46 // ---------------------------------------------------------------------------
       
    47 CRfsConnectionObserver* CRfsConnectionObserver::NewLC()
       
    48     {
       
    49     TRACES("CRfsConnectionObserver::NewLC()");
       
    50     
       
    51     CRfsConnectionObserver* self = new( ELeave ) CRfsConnectionObserver;
       
    52     CleanupStack::PushL( self );
       
    53     self->ConstructL();
       
    54     
       
    55     TRACES("CRfsConnectionObserver::NewLC(): End");
       
    56     return self;
       
    57     }
       
    58 
       
    59 // ---------------------------------------------------------------------------
       
    60 // second phased constructor
       
    61 // ---------------------------------------------------------------------------
       
    62 void CRfsConnectionObserver::ConstructL()
       
    63     {
       
    64     TRACES("CRfsConnectionObserver::ConstructL()");
       
    65     
       
    66     iIsPDPFeatureEnabled = IsAlwaysOnFeatureEnabledL();
       
    67     
       
    68     // We first check whether the required keys are defined or not 
       
    69     // i.e. SIP is there or not and PDP feature is there or not.
       
    70     // Following cases can arise:
       
    71     // 1. SIP present and PDP not defined -- Close the SIP connection (&) proceed with RFS
       
    72     // 2. SIP not defined and PDP present -- Close the PDP connection (&) proceed with RFS
       
    73     // 3. SIP and PDP not defined         -- Proceed to perform the RFS. Here no need to close any connection.
       
    74     // 4. Both defined                    -- Close SIP and PDP connection (&) proceed with RFS  
       
    75     //
       
    76     // OutCome: also record which is present and which is not present. This information will be needed
       
    77     // to set the future displaying of the dialog and to know whomo to send notifications and to whom not.
       
    78     //
       
    79     // If none of the active connections are present then no need to display the dialog. 
       
    80     // 
       
    81     // Here we need to inform the outside world (CRfsHandler) that we don't need to call rest of the methods
       
    82     // related to active connections closing operations if the third case is present.
       
    83     // The methods are:
       
    84     //      1. CloseAlwaysOnConnectionL()
       
    85     //      2. ReOpenConnection()
       
    86     
       
    87     TInt val(KErrNone);
       
    88     User::LeaveIfError( iSIPProperty.Attach(KPSSipRfsUid, KSipRfsState));
       
    89     TInt err = iSIPProperty.Get(KPSSipRfsUid, KSipRfsState, val);
       
    90     if (KErrNotFound == err)
       
    91         {
       
    92         // Record that SIP connection is not present
       
    93         iIsSIPConnectionsPresent = EFalse;
       
    94         }
       
    95     
       
    96     // No need to have a similar check for the PDP as the following boolean is sufficient
       
    97     if(iIsPDPFeatureEnabled)
       
    98         {
       
    99         User::LeaveIfError( iPDPProperty.Attach(KPDPContextManager2,KPDPContextManagerFactorySettingsReset ) );
       
   100         }
       
   101     
       
   102     // Following is the condition used to record that the dialog needs to be displayed
       
   103     // and the closing of the connections is possible
       
   104     if (iIsSIPConnectionsPresent || iIsPDPFeatureEnabled)
       
   105         {
       
   106         iIsDialogNeedToBeDisplayed = ETrue;
       
   107         iIsClosingConnectionsApplicable = ETrue;
       
   108         }
       
   109     
       
   110     // After finding out which type of connections need RFS notifications, we will 
       
   111     // proceed further to create a common dialog. This will be a wait for dialog which will be 
       
   112     // of synchrnous type and can only be closed inside the RunL() of this active class.
       
   113     // Provisions needed to be added to know whether this dialog needs resetting the pointer,
       
   114     // this will be the case when dialog is actually started using 'ExecuteLD()', 
       
   115     // Otherwise we need to delete this dialog and reset the pointer to NULL.
       
   116     if (iIsDialogNeedToBeDisplayed)
       
   117         {
       
   118         iWaitDialog = new( ELeave ) CAknWaitDialog(reinterpret_cast<CEikDialog**>( &iWaitDialog ) );
       
   119         }
       
   120    
       
   121     // Now we proceed further to setting of the next state i,e, enter the state machine of this active object
       
   122     // which will start from closing of the active connections and proceed to close the other connections
       
   123     // serially in a state wise manner.
       
   124     // N.B the states are put in order and should be maintained. High Priority
       
   125     //
       
   126     // As soon as 'iStatus' changes we will go to RunL() to close the SIP connection
       
   127     // and hence forth take up the activity of closing PDP connection.
       
   128     if (iIsSIPConnectionsPresent)
       
   129         {
       
   130         iState =  ESipConnectionClose;
       
   131         }
       
   132     else if (iIsPDPFeatureEnabled)
       
   133         {
       
   134         iState =  EPdpConnectionClose;
       
   135         }
       
   136     
       
   137     // After setting the state machine i.e. proper entry point into the RunL()
       
   138     // we will give an asynchronous listening and publishing request to the keys.  
       
   139     if (iIsSIPConnectionsPresent || iIsPDPFeatureEnabled)
       
   140         {
       
   141         Subscribe();
       
   142         }
       
   143     
       
   144     TRACES("CRfsConnectionObserver::ConstructL(): End");
       
   145     }
       
   146 
       
   147 // ---------------------------------------------------------------------------
       
   148 // C++ constructor
       
   149 // ---------------------------------------------------------------------------
       
   150 CRfsConnectionObserver::CRfsConnectionObserver():CActive( EPriorityStandard )
       
   151     {
       
   152     TRACES("CRfsConnectionObserver::CRfsConnectionObserver()");
       
   153 
       
   154     iIsSIPConnectionsPresent = ETrue;
       
   155     iIsPDPFeatureEnabled = ETrue;
       
   156     iIsWaitForDialogExecuted = EFalse;
       
   157     iIsDialogNeedToBeDisplayed = EFalse;
       
   158     iIsSipInformedForClosingAllConnection = EFalse;
       
   159     iIsPDPInformedforClosingAllConnection = EFalse;
       
   160     iIsClosingConnectionsApplicable = EFalse;
       
   161     
       
   162     CActiveScheduler::Add( this );
       
   163     
       
   164     TRACES("CRfsConnectionObserver::CRfsConnectionObserver(): End");
       
   165     }
       
   166              
       
   167 // ---------------------------------------------------------------------------
       
   168 // C++ destructor
       
   169 // ---------------------------------------------------------------------------
       
   170 CRfsConnectionObserver::~CRfsConnectionObserver()
       
   171     {
       
   172     TRACES("CRfsConnectionObserver::~CRfsConnectionObserver()");
       
   173     Cancel();
       
   174     TRACES("CRfsConnectionObserver::~CRfsConnectionObserver(): End");
       
   175     }
       
   176 
       
   177 // ---------------------------------------------------------------------------
       
   178 // CRfsConnectionObserver::CloseAlwaysOnConnectionL
       
   179 // ---------------------------------------------------------------------------
       
   180 TBool CRfsConnectionObserver::CloseAlwaysOnConnectionL()
       
   181     {
       
   182     TRACES("CRfsConnectionObserver::CloseAlwaysOnConnectionL()");
       
   183     
       
   184     if (iIsClosingConnectionsApplicable == EFalse)
       
   185         {
       
   186         // pretend that we have dsplayed the dialog and closed all the active connections
       
   187         return ETrue;
       
   188         }
       
   189 
       
   190     // only perform the following operation if the 'iIsClosingConnectionsApplicable' is ETrue 
       
   191     iAllConnectionClosed = EFalse;
       
   192       
       
   193     // Send P&S notification to SIP that RFS has started
       
   194     TInt err(KErrNone);
       
   195     if (iIsSIPConnectionsPresent && iState == ESipConnectionClose)
       
   196         {
       
   197         err = iSIPProperty.Set(KPSSipRfsUid, KSipRfsState, ESipRfsStarted );
       
   198         iIsSipInformedForClosingAllConnection = ETrue;
       
   199         }
       
   200     else if (iIsPDPFeatureEnabled && iState == EPdpConnectionClose)
       
   201         {
       
   202         err = iPDPProperty.Set(KPDPContextManager2,KPDPContextManagerFactorySettingsReset,EPDPContextManagerFactorySettingsResetStart );
       
   203         iIsPDPInformedforClosingAllConnection = ETrue;
       
   204         }
       
   205     
       
   206     
       
   207     // Leave from here is there is any error setting the intial handshake information
       
   208     // This means that RFS has failed as there was some problem setting the P&S keys
       
   209     User::LeaveIfError(err);
       
   210     if(err != KErrNone)
       
   211         {
       
   212         TRACES1("CRfsConnectionObserver::CloseAlwaysOnConnectionL(): Err = %d", err);
       
   213         // This means that the RFS has failed
       
   214         return EFalse; 
       
   215         }
       
   216     
       
   217     // we set the flag to indicate ExecuteLD is called and the dialog needs to be
       
   218     // dismissed from within the RunL()
       
   219     iIsWaitForDialogExecuted = ETrue;
       
   220     // Start displaying the dialog which will then be closed form the RunL()
       
   221     // Here the code execution blocks and we will proceed further only when 
       
   222     // this dialog is canceled
       
   223     err = iWaitDialog->ExecuteLD( R_CLOSING_CONNECTIONS );
       
   224     
       
   225     
       
   226     // following is the case when the user presses the Cancel button from the wait 
       
   227     // for dialog and in that case we need to resend the notificaiton of RFS failed
       
   228     // to whom all we have told previous of this to close the RFS connection
       
   229     if (err == EEikBidCancel)
       
   230         {
       
   231         if (iIsSipInformedForClosingAllConnection)
       
   232             {
       
   233             err = iSIPProperty.Set(KPSSipRfsUid, KSipRfsState, ESipRfsFailed );
       
   234             }
       
   235         if (iIsPDPInformedforClosingAllConnection)
       
   236             {
       
   237             iPDPProperty.Set(KPDPContextManager2,KPDPContextManagerFactorySettingsReset,EPDPContextManagerFactorySettingsResetStop);
       
   238             }
       
   239         }
       
   240     return iAllConnectionClosed;
       
   241     }
       
   242 
       
   243 void CRfsConnectionObserver::ReportRfsCompletionToSip()
       
   244     {
       
   245     TRACES("CRfsConnectionObserver::ReportRfsCompletionToSip()");
       
   246     
       
   247     // Only perform the following operation if the 'iIsClosingConnectionsApplicable' 
       
   248     if (!iIsClosingConnectionsApplicable)
       
   249         {
       
   250         // Pretend that we have re-opened all the closed connections and return doinng nothing
       
   251         return;
       
   252         }
       
   253     if (iIsSipInformedForClosingAllConnection)
       
   254         {
       
   255         iSIPProperty.Set(KPSSipRfsUid, KSipRfsState, ESipRfsCompleted );
       
   256         }
       
   257     
       
   258     TRACES("CRfsConnectionObserver::ReportRfsCompletionToSip(): End");
       
   259     }
       
   260 
       
   261 void CRfsConnectionObserver::ReportRfsFailureToSip()
       
   262     {
       
   263     TRACES("CRfsConnectionObserver::ReportRfsFailureToSip()");
       
   264     
       
   265     // Only perform the following operation if the 'iIsClosingConnectionsApplicable' 
       
   266     if (!iIsClosingConnectionsApplicable)
       
   267         {
       
   268         // Pretend that we have re-opened all the closed connections and return doinng nothing
       
   269         return;
       
   270         }
       
   271     if (iIsSipInformedForClosingAllConnection)
       
   272         {
       
   273         iSIPProperty.Set(KPSSipRfsUid, KSipRfsState, ESipRfsFailed );
       
   274         }
       
   275     
       
   276     TRACES("CRfsConnectionObserver::ReportRfsFailureToSip(): End");
       
   277     }
       
   278 
       
   279 void CRfsConnectionObserver::ReOpenPDPConnection()
       
   280     {
       
   281     TRACES("CRfsConnectionObserver::ReOpenPDPConnection()");
       
   282     
       
   283     // Only perform the following operation if the 'iIsClosingConnectionsApplicable' 
       
   284     if (!iIsClosingConnectionsApplicable)
       
   285         {
       
   286         // Pretend that we have re-opened all the closed connections and return doinng nothing
       
   287         return;
       
   288         }
       
   289     
       
   290     if (iIsPDPInformedforClosingAllConnection )
       
   291          {
       
   292          iPDPProperty.Set(KPDPContextManager2,KPDPContextManagerFactorySettingsReset,EPDPContextManagerFactorySettingsResetStop );
       
   293          }
       
   294     
       
   295     TRACES("CRfsConnectionObserver::ReOpenPDPConnection(): End");
       
   296     }
       
   297 
       
   298 // ---------------------------------------------------------------------------
       
   299 // CRfsConnectionObserver::RunL
       
   300 // ---------------------------------------------------------------------------
       
   301 void CRfsConnectionObserver::RunL()
       
   302     {
       
   303     // First call this is to enroll for the next handshake information to be recieved either from SIP or PDP
       
   304    Subscribe(); 
       
   305     
       
   306     switch(iState)
       
   307         {
       
   308         case ESipConnectionClose:
       
   309             {
       
   310             // Send P&S message to SIP 
       
   311             TInt val;
       
   312             TInt err = iSIPProperty.Get(KPSSipRfsUid, KSipRfsState, val);
       
   313             if ( err == KErrNone && val == ESipRfsEventProcessingCompleted)
       
   314                 {
       
   315                 if (iIsWaitForDialogExecuted && !iIsPDPFeatureEnabled)
       
   316                     {
       
   317                     // set the information that we have closed all the active connections
       
   318                     // here itself because the PDP connection/feature doen't exist
       
   319                     iAllConnectionClosed = ETrue;
       
   320                     DismissWaitDialog();
       
   321                     }
       
   322                 
       
   323                 if (iIsPDPFeatureEnabled)
       
   324                     {
       
   325                     iPDPProperty.Set(KPDPContextManager2,KPDPContextManagerFactorySettingsReset,EPDPContextManagerFactorySettingsResetStart );
       
   326                     
       
   327                     // change the state to the next from within this as we are done with closing the SIP connection
       
   328                     iState = EPdpConnectionClose;
       
   329                     //
       
   330                     // Under following cases the 'iIsPDPInformedforClosingAllConnection' will be set
       
   331                     //
       
   332                     // CASE 1:
       
   333                     //          When from within CloseAlwaysOnConnectionL we inform the PDP to 
       
   334                     //          close its connection, that time this will be set.
       
   335                     // CASE 2: 
       
   336                     //          The other case covers when the SIP exists, then this flag will be set 
       
   337                     //          when we come to RunL straight to this  switch-case after just previous to
       
   338                     //          switch-case being of closing All the SIP active connections.
       
   339                     //
       
   340                     // RATIONALE: (behind the use of following flag):
       
   341                     //            Setting of this flag will actually help us in the case when
       
   342                     //            the user cancels the PDP closing connections
       
   343                     iIsPDPInformedforClosingAllConnection = ETrue;
       
   344                     }
       
   345                 TRACES1("CRfsConnectionObserver::RunL(): iPDPProperty.Set returned Err = %d", err);
       
   346                 }
       
   347             break;
       
   348             }
       
   349         case EPdpConnectionClose:
       
   350             {
       
   351             // When we reach here we should assume that:
       
   352             //      1. the WAIT FOR dialog is being tothe user of the device 
       
   353             //      2. If SIP existed then it has successfully closed all its active connections
       
   354             //               
       
   355             // What needs to be done at this point of time is to :
       
   356             //      1. Check of what message has been published to the 'KPDPContextManagerFactorySettingsReset' key
       
   357             //      2. If the PDP has replied with all its active connections closed then we should close the dialog 
       
   358             //         and set the information that we have closed all the active connections including SIP if it existed
       
   359             //         at the time when the user requested for an RFS 
       
   360              
       
   361             TInt val;
       
   362             TInt err = iPDPProperty.Get(KPDPContextManager2,KPDPContextManagerFactorySettingsReset, val);
       
   363             if (err == KErrNone && val == EPDPContextManagerFactorySettingsResetStartReply && iAllConnectionClosed == EFalse )
       
   364                 {
       
   365                 // The response from PDP of closing all its connections have been recieved 
       
   366                 // Now we may proceed to dsmiss the dialog and also set the state to the True for 
       
   367                 // all active connections closed
       
   368                 iAllConnectionClosed = ETrue;
       
   369                 DismissWaitDialog();
       
   370                 }
       
   371             }
       
   372         } // end switch-case block
       
   373     }
       
   374 
       
   375 
       
   376 // ---------------------------------------------------------------------------
       
   377 // CRfsConnectionObserver::IsAlwaysOnFeatureEnabledL
       
   378 // ---------------------------------------------------------------------------
       
   379 TInt CRfsConnectionObserver::IsAlwaysOnFeatureEnabledL()
       
   380     {
       
   381     TInt alwaysOnEnabled = KRfsAlwaysOnDisabled;
       
   382     if( FeatureManager::FeatureSupported( KFeatureIdAlwaysOnlinePDPContext2 ) )
       
   383         {
       
   384         // Check if always on feature enabled
       
   385         CRepository* cenRep = CRepository::NewLC( KCRUidPDPContextManager );
       
   386         TInt err = cenRep->Get( KPDPContextAlwaysOnEnabled, alwaysOnEnabled );
       
   387         if( err != KErrNone )
       
   388             {
       
   389             alwaysOnEnabled = KRfsAlwaysOnEnabled;
       
   390             }
       
   391         CleanupStack::PopAndDestroy(cenRep); 
       
   392         }
       
   393     return alwaysOnEnabled;
       
   394     }
       
   395 
       
   396 // ---------------------------------------------------------------------------
       
   397 // CRfsConnectionObserver::DoCancel
       
   398 // ---------------------------------------------------------------------------
       
   399 void CRfsConnectionObserver::DoCancel()
       
   400     {
       
   401     TRACES("CRfsConnectionObserver::DoCancel()");
       
   402     
       
   403     if(iIsPDPFeatureEnabled)
       
   404         {
       
   405         iPDPProperty.Cancel();
       
   406         }
       
   407     if(iIsSIPConnectionsPresent)
       
   408         {
       
   409         iSIPProperty.Cancel();
       
   410         }
       
   411 
       
   412     DismissWaitDialog();
       
   413     
       
   414     TRACES("CRfsConnectionObserver::DoCancel(): End");
       
   415     }
       
   416 
       
   417 // ---------------------------------------------------------------------------
       
   418 // CRfsConnectionObserver::Subscribe
       
   419 // ---------------------------------------------------------------------------
       
   420 void CRfsConnectionObserver::Subscribe()
       
   421     {
       
   422     switch(iState)
       
   423         {
       
   424         case ESipConnectionClose: 
       
   425             {
       
   426             // SIP connection first [Always]
       
   427             iSIPProperty.Subscribe(iStatus);
       
   428             break;
       
   429             }
       
   430         case EPdpConnectionClose:
       
   431             {
       
   432             iPDPProperty.Subscribe(iStatus);
       
   433             break;
       
   434             }
       
   435         }
       
   436     SetActive();
       
   437     }
       
   438 
       
   439 // ---------------------------------------------------------------------------
       
   440 // CRfsConnectionObserver::DismissWaitDialog
       
   441 // ---------------------------------------------------------------------------
       
   442 void CRfsConnectionObserver::DismissWaitDialog()
       
   443     {
       
   444     TRACES("CRfsConnectionObserver::DismissWaitDialog()");
       
   445     
       
   446     if ( iWaitDialog && iIsWaitForDialogExecuted)
       
   447         {
       
   448         TRAP_IGNORE( iWaitDialog->ProcessFinishedL() );
       
   449         }
       
   450     
       
   451     // Sanity Check:
       
   452     // It can be a case when dialog was need to be displayed but was not due to some error
       
   453     // this means that the 'iWaitDialog' was constructed but never used and destroyed
       
   454     // i.e. the ExecuteLD() was never called
       
   455     else if(iIsDialogNeedToBeDisplayed && !iIsWaitForDialogExecuted)
       
   456         {
       
   457         delete iWaitDialog;
       
   458         }
       
   459     
       
   460     // Reset the pointer to NULL
       
   461     iWaitDialog = NULL;
       
   462     
       
   463     TRACES("CRfsConnectionObserver::DismissWaitDialog(): End");
       
   464     }
       
   465