IMPSengine/engsrv/src/impsalivemanager.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2003 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: Alive manager for IMPS engine.
       
    15 *
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    <s32std.h>
       
    22 #include    "impsalivemanager.h"
       
    23 #include    "impsutils.h"
       
    24 #include    "impscspsessionapi.h"
       
    25 #include    "impstimer.h"
       
    26 #include    "impserrors.h"
       
    27 
       
    28 // MACROS
       
    29 #ifndef _DEBUG
       
    30 #define _NO_IMPS_LOGGING_
       
    31 #endif
       
    32 
       
    33 // ================= MEMBER FUNCTIONS =======================
       
    34 
       
    35 
       
    36 // ---------------------------------------------------------
       
    37 // CImpsAliveManager::CImpsAliveManager
       
    38 // ---------------------------------------------------------
       
    39 //
       
    40 CImpsAliveManager::CImpsAliveManager( MImpsCSPSession& aServer )
       
    41         : CActive( 0 ),
       
    42         iState( EImpsAliveIdle ),
       
    43         iServer( aServer ),
       
    44         iTimer( NULL ),
       
    45         iScheduled( EFalse ),
       
    46         iTid( KNullDesC ),
       
    47         iSeconds( 0 )
       
    48     {
       
    49     // Add this to the scheduler
       
    50     CActiveScheduler::Add( this );
       
    51     }
       
    52 
       
    53 // Two-phased constructor.
       
    54 CImpsAliveManager* CImpsAliveManager::NewL( MImpsCSPSession& aServer )
       
    55     {
       
    56     CImpsAliveManager* self = new ( ELeave ) CImpsAliveManager( aServer );
       
    57 
       
    58     CleanupStack::PushL( self );
       
    59     self->ConstructL( );
       
    60     CleanupStack::Pop( );
       
    61 
       
    62     return self;
       
    63     }
       
    64 
       
    65 
       
    66 // ---------------------------------------------------------
       
    67 // CImpsAliveManager::ConstructL
       
    68 // ---------------------------------------------------------
       
    69 //
       
    70 void CImpsAliveManager::ConstructL()
       
    71     {
       
    72     iTimer = new ( ELeave ) CImpsAliveTimer( *this, CActive::EPriorityStandard );
       
    73     }
       
    74 
       
    75 // ---------------------------------------------------------
       
    76 // CImpsAliveManager::~CImpsAliveManager
       
    77 // ---------------------------------------------------------
       
    78 //
       
    79 CImpsAliveManager::~CImpsAliveManager(  )
       
    80     {
       
    81     Cancel();
       
    82     delete iTimer;
       
    83     }
       
    84 
       
    85 // ---------------------------------------------------------
       
    86 // CImpsAliveManager::StartTimer
       
    87 // Server core calls this always when receving KeepAliveResp.
       
    88 // ---------------------------------------------------------
       
    89 //
       
    90 void CImpsAliveManager::StartTimer( TInt aInterval )
       
    91     {
       
    92 #ifndef _NO_IMPS_LOGGING_
       
    93     CImpsClientLogger::Log( _L( "AliveManager: StartTimer" ) );
       
    94 #endif
       
    95     iState = EImpsAliveActive;
       
    96 #ifndef _NO_IMPS_LOGGING_
       
    97     CImpsClientLogger::Log( _L( "AliveManager: iState = %d " ), iState );
       
    98 #endif
       
    99     iFailCount = 0;
       
   100     iTimerFail = 0;
       
   101     // Some time needed to open PDP, that's why 60 seconds decreased
       
   102     TInt myInterval = ( aInterval / 2 ) - 60;
       
   103     if ( myInterval < 60 )
       
   104         {
       
   105         myInterval = aInterval / 2;
       
   106         }
       
   107     iSeconds = myInterval;
       
   108     iTimer->Start( iSeconds );
       
   109     }
       
   110 
       
   111 // ---------------------------------------------------------
       
   112 // CImpsAliveManager::StopTimer
       
   113 // ---------------------------------------------------------
       
   114 //
       
   115 void CImpsAliveManager::StopTimer(  )
       
   116     {
       
   117 #ifndef _NO_IMPS_LOGGING_
       
   118     CImpsClientLogger::Log( _L( "AliveManager: StopTimer" ) );
       
   119 #endif
       
   120     iTimer->Stop();
       
   121     iState = EImpsAliveIdle;
       
   122 #ifndef _NO_IMPS_LOGGING_
       
   123     CImpsClientLogger::Log( _L( "AliveManager: iState = %d " ), iState );
       
   124 #endif
       
   125     }
       
   126 
       
   127 // ---------------------------------------------------------
       
   128 // CImpsAliveManager::CheckResp
       
   129 // ---------------------------------------------------------
       
   130 //
       
   131 void CImpsAliveManager::CheckResp( TInt aCode )
       
   132     {
       
   133     // Session id check should already be done in engine core.
       
   134     // Any normal transport response resets the timer
       
   135     if ( iState != EImpsAlivePending )
       
   136         {
       
   137         iTimer->Start( iSeconds );
       
   138         return;
       
   139         }
       
   140 
       
   141     // Something is received within the session.
       
   142     // We are not interested to get the particular response for
       
   143     // KeepAliveReq transaction.
       
   144     if ( aCode !=  600 &&
       
   145          aCode !=  601 &&
       
   146          aCode !=  604 )
       
   147         {
       
   148         iState = EImpsAliveActive;
       
   149 #ifndef _NO_IMPS_LOGGING_
       
   150         CImpsClientLogger::Log( _L( "AliveManager: CheckResp resets iState = %d " ), iState );
       
   151 #endif
       
   152         iFailCount = 0;
       
   153         iTimerFail = 0;
       
   154         return;
       
   155         }
       
   156     else
       
   157         {
       
   158 #ifndef _NO_IMPS_LOGGING_
       
   159         CImpsClientLogger::Log( _L( "AliveManager: CheckResp 60x" ) );
       
   160 #endif
       
   161         // Just stop timer here. DoLogout is called later in engine core,
       
   162         // after the possible response event is created for the client.
       
   163         StopTimer();
       
   164         }
       
   165     }
       
   166 
       
   167 // ---------------------------------------------------------
       
   168 // CImpsAliveManager::CheckError
       
   169 // ---------------------------------------------------------
       
   170 //
       
   171 void CImpsAliveManager::CheckError( const TDesC& aTid )
       
   172     {
       
   173 #ifndef _NO_IMPS_LOGGING_
       
   174     CImpsClientLogger::Log( _L( "AliveManager: CheckError %d" ),
       
   175                             iState );
       
   176 #endif
       
   177     if ( iState != EImpsAlivePending )
       
   178         {
       
   179         return;
       
   180         }
       
   181     // Open PDP errors come here without TID and then error handling is required.
       
   182     if ( aTid.Length() && iTid.Compare( aTid ) )
       
   183         {
       
   184         // This was not KeepAliveReguest transaction
       
   185         return;
       
   186         }
       
   187     iState = EImpsAliveActive;
       
   188 #ifndef _NO_IMPS_LOGGING_
       
   189     CImpsClientLogger::Log( _L( "AliveManager: iState = %d " ), iState );
       
   190 #endif
       
   191     DoHandleError( );
       
   192     }
       
   193 
       
   194 // ---------------------------------------------------------
       
   195 // CImpsAliveManager::SendKeepAlive
       
   196 // ---------------------------------------------------------
       
   197 //
       
   198 void CImpsAliveManager::SendKeepAlive(
       
   199     TBool aSchedule )
       
   200     {
       
   201 #ifndef _NO_IMPS_LOGGING_
       
   202     CImpsClientLogger::Log( _L( "AliveManager: SendKeepAlive sch=%d state=%d fc=%d tf=%d" ),
       
   203                             aSchedule, iState, iFailCount, iTimerFail );
       
   204 #endif
       
   205 
       
   206     if ( iState == EImpsAliveActive )
       
   207         {
       
   208         iState = EImpsAlivePending;
       
   209         iScheduled = aSchedule;
       
   210 #ifndef _NO_IMPS_LOGGING_
       
   211         CImpsClientLogger::Log( _L( "AliveManager: iState = %d " ), iState );
       
   212 #endif
       
   213 
       
   214         TRAPD( err, ( iTid = iServer.SendAliveL( ) ) );
       
   215         if ( err )
       
   216             {
       
   217             // Error received immediately and
       
   218             // since going back to active state.
       
   219             iState = EImpsAliveActive;
       
   220             DoHandleError( );
       
   221             }
       
   222         }
       
   223     else if ( iState == EImpsAliveIdle )
       
   224         {
       
   225         return;
       
   226         }
       
   227     else // if ( iState == EImpsAlivePending )
       
   228         {
       
   229         if ( aSchedule )
       
   230             {
       
   231             // Previous request not complete!
       
   232             iTimerFail++;
       
   233             iFailCount = 0;
       
   234             if ( iTimerFail > KImpsMaxAliveScheduleErr )
       
   235                 {
       
   236                 // current CSP session seems to be lost!
       
   237                 DoSessionClose();
       
   238                 return;
       
   239                 }
       
   240             }
       
   241         TRAPD( err, ( iTid = iServer.SendAliveL( ) ) );
       
   242         if ( err )
       
   243             {
       
   244             DoHandleError( );
       
   245             }
       
   246         }
       
   247     }
       
   248 
       
   249 // ---------------------------------------------------------
       
   250 // CImpsAliveManager::DoHandleError
       
   251 // ---------------------------------------------------------
       
   252 //
       
   253 void CImpsAliveManager::DoHandleError( )
       
   254     {
       
   255 #ifndef _NO_IMPS_LOGGING_
       
   256     CImpsClientLogger::Log( _L( "AliveManager: DoHandleError" ) );
       
   257 #endif
       
   258     if ( IsActive() )
       
   259         {
       
   260 #ifndef _NO_IMPS_LOGGING_
       
   261         CImpsClientLogger::Log( _L( "AliveManager: DoHandleError was active" ) );
       
   262 #endif
       
   263         return;
       
   264         }
       
   265     TRequestStatus* s = &iStatus;
       
   266     iFailCount++;
       
   267     if ( iFailCount > KImpsMaxAliveRetryOnce )
       
   268         {
       
   269         if ( !iScheduled )
       
   270             {
       
   271 #ifndef _NO_IMPS_LOGGING_
       
   272             CImpsClientLogger::Log( _L( "AliveManager: DoHandleError !scheduled" ) );
       
   273 #endif
       
   274             return;
       
   275             }
       
   276         iTimerFail++;
       
   277         iFailCount = 0;
       
   278         if ( iTimerFail > KImpsMaxAliveScheduleErr )
       
   279             {
       
   280             // current CSP session seems to be lost!
       
   281             // Yield control to scheduler
       
   282 #ifndef _NO_IMPS_LOGGING_
       
   283             CImpsClientLogger::Log( _L( "AliveManager: DoHandleError NOK stop" ) );
       
   284 #endif
       
   285             iStatus = KRequestPending;
       
   286             SetActive();
       
   287             User::RequestComplete( s, KImpsNotLoggedStatus );
       
   288             }
       
   289         // else not try more until scheduled by the timer
       
   290         }
       
   291     else
       
   292         {
       
   293 #ifndef _NO_IMPS_LOGGING_
       
   294         CImpsClientLogger::Log( _L( "AliveManager: DoHandleError OK retry" ) );
       
   295 #endif
       
   296         // Tell CSP session to send KeepAlive when GPRS resumes
       
   297         iServer.SendAliveInResume();
       
   298         // Yield control to scheduler and retry in RunL
       
   299         iStatus = KRequestPending;
       
   300         SetActive();
       
   301         User::RequestComplete( s, KErrNone );
       
   302         }
       
   303 
       
   304 #ifndef _NO_IMPS_LOGGING_
       
   305     CImpsClientLogger::Log( _L( "AliveManager: DoHandleError END" ) );
       
   306 #endif
       
   307     }
       
   308 
       
   309 // ---------------------------------------------------------
       
   310 // CImpsAliveManager::DoSessionClose
       
   311 // ---------------------------------------------------------
       
   312 //
       
   313 void CImpsAliveManager::DoSessionClose( )
       
   314     {
       
   315 #ifndef _NO_IMPS_LOGGING_
       
   316     CImpsClientLogger::Log( _L( "AliveManager: DoSessionClose" ) );
       
   317 #endif
       
   318     iTimer->Stop();
       
   319     iState = EImpsAliveIdle;
       
   320 #ifndef _NO_IMPS_LOGGING_
       
   321     CImpsClientLogger::Log( _L( "AliveManager: iState = %d " ), iState );
       
   322 #endif
       
   323     iServer.DoLogout();
       
   324     }
       
   325 
       
   326 // ---------------------------------------------------------
       
   327 // CImpsAliveManager::DoCancel
       
   328 // ---------------------------------------------------------
       
   329 //
       
   330 void CImpsAliveManager::DoCancel()
       
   331     {
       
   332     iTimer->Stop();
       
   333     iState = EImpsAliveIdle;
       
   334 #ifndef _NO_IMPS_LOGGING_
       
   335     CImpsClientLogger::Log( _L( "AliveManager: iState = %d " ), iState );
       
   336 #endif
       
   337     }
       
   338 
       
   339 // ---------------------------------------------------------
       
   340 // CImpsAliveManager::RunL
       
   341 // ---------------------------------------------------------
       
   342 //
       
   343 void CImpsAliveManager::RunL()
       
   344     {
       
   345 #ifndef _NO_IMPS_LOGGING_
       
   346     CImpsClientLogger::Log( _L( "AliveManager: RunL %d" ), iState );
       
   347 #endif
       
   348     if ( iState == EImpsAliveIdle )
       
   349         {
       
   350         // Cancelled
       
   351         return;
       
   352         }
       
   353     if ( iStatus == KImpsNotLoggedStatus )
       
   354         {
       
   355         // current CSP session is lost
       
   356         DoSessionClose();
       
   357         }
       
   358     else
       
   359         {
       
   360         // Retry
       
   361         SendKeepAlive( iScheduled );
       
   362         }
       
   363 #ifndef _NO_IMPS_LOGGING_
       
   364     CImpsClientLogger::Log( _L( "AliveManager: RunL ends" ) );
       
   365 #endif
       
   366     }
       
   367 
       
   368 //**********************************
       
   369 // CImpsAliveTimer
       
   370 //**********************************
       
   371 
       
   372 CImpsAliveTimer::CImpsAliveTimer(
       
   373     CImpsAliveManager& aServer,
       
   374     TInt aPriority )
       
   375         : CActive( aPriority ),
       
   376         iMgr( aServer ),
       
   377         iReset( EFalse ),
       
   378         iCanceled( EFalse )
       
   379     {
       
   380     // Add this to the scheduler
       
   381     ( void ) iTimer.CreateLocal();
       
   382     CActiveScheduler::Add( this );
       
   383     }
       
   384 
       
   385 CImpsAliveTimer::~CImpsAliveTimer()
       
   386     {
       
   387     Cancel();
       
   388     iTimer.Close();
       
   389     }
       
   390 
       
   391 // ---------------------------------------------------------
       
   392 // CImpsAliveTimer::Start
       
   393 // ---------------------------------------------------------
       
   394 //
       
   395 void CImpsAliveTimer::Start( TInt aWaitSeconds )
       
   396     {
       
   397 #ifndef _NO_IMPS_LOGGING_
       
   398     CImpsClientLogger::Log( _L( "AliveTimer: Start %d sec" ), aWaitSeconds );
       
   399 #endif
       
   400     iReset = EFalse;
       
   401     if ( aWaitSeconds <= 0 )
       
   402         {
       
   403         return;
       
   404         }
       
   405     // Cancel is needed because of the timer may be reset.
       
   406     Cancel();
       
   407     iSeconds = aWaitSeconds;
       
   408 
       
   409     // The At function caused a CUserbase-Panic 46 in very small
       
   410     // time values. 1-4 seconds. Now if the KeepAlive time
       
   411     // is smaller than UseAfterLimit, then we use the After function
       
   412     // If it is larger then use the At function
       
   413     // The reason not to use the After function for every situation is
       
   414     // that the TInt overflows after 35 minutes. 1000000*60*36 > 2^31
       
   415     if ( iSeconds < KUseAfterLimit )
       
   416         {
       
   417         iTimer.After( iStatus, iSeconds * 1000000 );
       
   418         }
       
   419     else
       
   420         {
       
   421         TTime myKeepAlive;
       
   422         myKeepAlive.HomeTime();
       
   423         myKeepAlive += TTimeIntervalSeconds( iSeconds );
       
   424         iTimer.At( iStatus, myKeepAlive );
       
   425         }
       
   426 
       
   427     iStatus = KRequestPending;
       
   428     SetActive();
       
   429 
       
   430     }
       
   431 
       
   432 // ---------------------------------------------------------
       
   433 // CImpsAliveTimer::Stop
       
   434 // ---------------------------------------------------------
       
   435 //
       
   436 void CImpsAliveTimer::Stop( )
       
   437     {
       
   438 #ifndef _NO_IMPS_LOGGING_
       
   439     CImpsClientLogger::Log( _L( "AliveTimer: Stop" ) );
       
   440 #endif
       
   441     iReset = ETrue;
       
   442     Cancel();
       
   443     // The following is needed because of the timer may just
       
   444     // have triggered and thus it is not active, but the request is
       
   445     // waiting in the scheduler and coming to RunL later.
       
   446     iCanceled = ETrue;
       
   447     }
       
   448 
       
   449 // ---------------------------------------------------------
       
   450 // CImpsAliveTimer::DoCancel
       
   451 // ---------------------------------------------------------
       
   452 //
       
   453 void CImpsAliveTimer::DoCancel()
       
   454     {
       
   455     iTimer.Cancel();
       
   456     }
       
   457 
       
   458 // ---------------------------------------------------------
       
   459 // CImpsAliveTimer::RunL
       
   460 // ---------------------------------------------------------
       
   461 //
       
   462 void CImpsAliveTimer::RunL()
       
   463     {
       
   464 #ifndef _NO_IMPS_LOGGING_
       
   465     CImpsClientLogger::Log( _L( "AliveTimer: RunL" ) );
       
   466 #endif
       
   467     if ( iCanceled )
       
   468         {
       
   469         return;
       
   470         }
       
   471     if ( !iReset )
       
   472         {
       
   473         iMgr.SendKeepAlive( ETrue );
       
   474         }
       
   475     iReset = EFalse;
       
   476     Start( iSeconds );
       
   477     }
       
   478 
       
   479 // ================= OTHER EXPORTED FUNCTIONS ==============
       
   480 
       
   481 //  End of File
       
   482