wlan_bearer/wlanengine/wlan_symbian/wlanengine_symbian_3.1/src/wlantimerservices.cpp
changeset 0 c40eb8fe8501
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 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 the License "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:  This class implements timer service with callback functionality.
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 2 %
       
    20 */
       
    21 
       
    22 #include <e32std.h>
       
    23 #include <e32base.h>
       
    24 #include "wlantimerservices.h"
       
    25 #include "am_debug.h"
       
    26 
       
    27 const TInt KMaxTimerTimeout            = 0x7FFFFFFF;
       
    28 const TInt KFirstItemIndex             = 0;
       
    29 const TInt KNoRequests                 = -1;
       
    30 const TInt KEntriesAreEqual            = 0;
       
    31 const TInt KFirstEntryIsBigger         = 1;
       
    32 const TInt KFirstEntryIsSmaller        = -1;
       
    33 
       
    34 #ifdef _DEBUG
       
    35 /**
       
    36  * Formatting of date time debug string.
       
    37  */
       
    38 _LIT( KWlanTimerServicesDateTimeFormat, "%F %*E %*N %D %H:%T:%S" );
       
    39 
       
    40 /**
       
    41  * Maximun length for date time debug string.
       
    42  */
       
    43 const TInt KWlanTimerServicesMaxDateTimeStrLen = 50;
       
    44 #endif
       
    45 
       
    46 // ================= MEMBER FUNCTIONS =======================
       
    47 
       
    48 // C++ default constructor can NOT contain any code, that
       
    49 // might leave.
       
    50 //
       
    51 CWlanTimerServices::CWlanTimerServices() :
       
    52     CActive( CActive::EPriorityStandard ),
       
    53     iRequestId( 0 )
       
    54     {
       
    55     DEBUG( "CWlanTimerServices::CWlanTimerServices()" );
       
    56     }
       
    57 
       
    58 // Static constructor.
       
    59 CWlanTimerServices* CWlanTimerServices::NewL()
       
    60     {
       
    61     DEBUG( "CWlanTimerServices::NewL()" );
       
    62     CWlanTimerServices* self =
       
    63         new (ELeave) CWlanTimerServices();
       
    64     CleanupStack::PushL( self );
       
    65     self->ConstructL();
       
    66     CleanupStack::Pop( self );
       
    67     return self;
       
    68     }
       
    69 
       
    70 // Symbian 2nd phase constructor can leave.
       
    71 void CWlanTimerServices::ConstructL()
       
    72     {
       
    73     DEBUG( "CWlanTimerServices::ConstructL()" );
       
    74 
       
    75     CActiveScheduler::Add( this );
       
    76     User::LeaveIfError( iTimer.CreateLocal() );
       
    77     
       
    78     DEBUG( "CWlanTimerServices::ConstructL() - done" );
       
    79     }
       
    80 
       
    81 // Destructor
       
    82 CWlanTimerServices::~CWlanTimerServices()
       
    83     {
       
    84     DEBUG( "CWlanTimerServices::~CWlanTimerServices()" );
       
    85 
       
    86     Cancel();
       
    87     iTimer.Close();
       
    88     iRequests.Close();
       
    89     }
       
    90 
       
    91 // ---------------------------------------------------------
       
    92 // CWlanTimerServices::DoCancel
       
    93 // Is called by CActive::Cancel()
       
    94 // ---------------------------------------------------------
       
    95 //
       
    96 void CWlanTimerServices::DoCancel()
       
    97     {
       
    98     DEBUG( "CWlanTimerServices::DoCancel()" );
       
    99     iTimer.Cancel();
       
   100     }
       
   101 
       
   102 // ---------------------------------------------------------
       
   103 // CWlanTimerServices::CompareTimeouts
       
   104 // ---------------------------------------------------------
       
   105 //
       
   106 TInt CWlanTimerServices::CompareTimeouts( const CTimeoutRequestEntry& aFirst,
       
   107                                           const CTimeoutRequestEntry& aSecond )
       
   108     {
       
   109     DEBUG( "CWlanTimerServices::CompareTimeouts()" );
       
   110 
       
   111     TInt ret( 0 );
       
   112     
       
   113     if( aFirst.At() == aSecond.At() )
       
   114         {
       
   115         ret = KEntriesAreEqual;
       
   116         }
       
   117     else if( aFirst.At() > aSecond.At() )
       
   118         {
       
   119         ret = KFirstEntryIsBigger;
       
   120         }
       
   121     else
       
   122         {
       
   123         ret = KFirstEntryIsSmaller;
       
   124         }
       
   125     
       
   126     DEBUG1( "CWlanTimerServices::CompareTimeouts() - returning %d", ret );
       
   127     return ret;
       
   128     }
       
   129 
       
   130 // ---------------------------------------------------------
       
   131 // CWlanTimerServices::CalculateInterval
       
   132 // ---------------------------------------------------------
       
   133 //
       
   134 TInt CWlanTimerServices::CalculateInterval( TTimeIntervalMicroSeconds32& aInterval, TTime& aAt, TBool& aDoSeveralRounds ) const
       
   135     {
       
   136     TTime currentTime;
       
   137     currentTime.HomeTime();
       
   138     
       
   139 #ifdef _DEBUG
       
   140     TBuf<KWlanTimerServicesMaxDateTimeStrLen> dbgString, timeoutDbgStr;
       
   141     TRAP_IGNORE( aAt.FormatL( timeoutDbgStr, KWlanTimerServicesDateTimeFormat ) );
       
   142     DEBUG1( "CWlanTimerServices::CalculateInterval() - timeout:  %S", &timeoutDbgStr );
       
   143     TRAP_IGNORE( currentTime.FormatL( dbgString, KWlanTimerServicesDateTimeFormat ) );
       
   144     DEBUG1( "CWlanTimerServices::CalculateInterval() - time now: %S", &dbgString );
       
   145 #endif
       
   146     
       
   147     if( aAt < currentTime )
       
   148         {
       
   149         DEBUG( "CWlanTimerServices::CalculateInterval() - timeout happens in past, returning KErrArgument" );
       
   150         return KErrArgument;
       
   151         }
       
   152     
       
   153     TTimeIntervalDays days( aAt.DaysFrom( currentTime ) );
       
   154     DEBUG1( "CWlanTimerServices::CalculateInterval() - difference %d day(s)", days.Int() );
       
   155     if( days.Int() != 0 )
       
   156         {
       
   157         DEBUG( "CWlanTimerServices::CalculateInterval() - difference day or more, adjusting timeout to same day" );
       
   158         TDateTime timeout = aAt.DateTime();
       
   159         TDateTime now = currentTime.DateTime();
       
   160         timeout.SetYear( now.Year() );
       
   161         timeout.SetMonth( now.Month() );
       
   162         timeout.SetDay( now.Day() );
       
   163         aAt = TTime( timeout );
       
   164         if( aAt < currentTime )
       
   165             {
       
   166             DEBUG1( "CWlanTimerServices::CalculateInterval() - timeout would happen in past, adding %d day(s) to it", days.Int() );
       
   167             aAt += days;
       
   168             }
       
   169         
       
   170 #ifdef _DEBUG
       
   171         TBuf<KWlanTimerServicesMaxDateTimeStrLen> newTimeoutDbgStr;
       
   172         TRAP_IGNORE( aAt.FormatL( newTimeoutDbgStr, KWlanTimerServicesDateTimeFormat ) );
       
   173         DEBUG1( "CWlanTimerServices::CalculateInterval() - timeout:  %S", &newTimeoutDbgStr );
       
   174 #endif
       
   175         }
       
   176     
       
   177     TTimeIntervalMicroSeconds difference = aAt.MicroSecondsFrom( currentTime );
       
   178     
       
   179     TTimeIntervalMicroSeconds32 newInterval_32bit( KMaxTimerTimeout );
       
   180     
       
   181     TTimeIntervalMicroSeconds interval_64bit( newInterval_32bit.Int() );
       
   182     
       
   183     if ( difference < interval_64bit )
       
   184         {
       
   185         newInterval_32bit = static_cast<TTimeIntervalMicroSeconds32>( difference.Int64() );
       
   186         aDoSeveralRounds = EFalse;
       
   187         }
       
   188     else
       
   189         {
       
   190         DEBUG( "CWlanTimerServices::CalculateInterval() - requested timeout so big it requires several timer rounds" );
       
   191         aDoSeveralRounds = ETrue;
       
   192         }
       
   193 
       
   194     aInterval = newInterval_32bit;
       
   195     
       
   196     return KErrNone;
       
   197     }
       
   198 
       
   199 // ---------------------------------------------------------
       
   200 // CWlanTimerServices::StartTimer
       
   201 // ---------------------------------------------------------
       
   202 //
       
   203 TInt CWlanTimerServices::StartTimer( TUint& aRequestId, TTime& aAt, MWlanTimerServiceCallback& aCb )
       
   204     {
       
   205     TTimeIntervalMicroSeconds32 newInterval( 0 );
       
   206     TBool doSeveralRounds( EFalse );
       
   207     
       
   208     TInt err = CalculateInterval( newInterval, aAt, doSeveralRounds );
       
   209     
       
   210     if( err != KErrNone ) 
       
   211         {
       
   212         DEBUG1( "CWlanTimerServices::StartTimer() - CalculateInterval() returned %d", err );
       
   213         return err;
       
   214         }
       
   215         
       
   216     CTimeoutRequestEntry entry( aAt, aCb, ++iRequestId, doSeveralRounds );
       
   217     
       
   218     TInt requestIdOfOriginallyFirstEntry( RequestIdOfFirstEntry() );
       
   219     
       
   220     TLinearOrder<CTimeoutRequestEntry> order( CWlanTimerServices::CompareTimeouts );
       
   221     err = iRequests.InsertInOrder( entry, order );
       
   222     
       
   223     if( err != KErrNone )
       
   224         {
       
   225         DEBUG1( "CWlanTimerServices::StartTimer() - InsertInOrder() returned %d", err );
       
   226         return err;
       
   227         }
       
   228 
       
   229     DEBUG1( "CWlanTimerServices::StartTimer() - new entry added to queue, request id %d", entry.RequestId() );
       
   230     
       
   231 #ifdef _DEBUG
       
   232     for( TInt i = 0; i < iRequests.Count(); i++ )
       
   233         {
       
   234         DEBUG3( "CWlanTimerServices::StartTimer() - entry[%d]: request id %u, located @ 0x%08X",
       
   235                 i,
       
   236                 iRequests[i].RequestId(),
       
   237                 &iRequests[i] );
       
   238         }
       
   239 #endif
       
   240     
       
   241     if( requestIdOfOriginallyFirstEntry != iRequests[0].RequestId() )
       
   242         {
       
   243         // first request has changed, restart timer
       
   244         ActivateTimer( newInterval );
       
   245         }
       
   246     
       
   247     aRequestId = iRequestId;
       
   248     
       
   249     DEBUG( "CWlanTimerServices::StartTimer() - done" );
       
   250     return KErrNone;
       
   251     }
       
   252 
       
   253 // ---------------------------------------------------------
       
   254 // CWlanTimerServices::RequestIdOfFirstEntry   
       
   255 // ---------------------------------------------------------
       
   256 //
       
   257 TInt CWlanTimerServices::RequestIdOfFirstEntry()
       
   258     {
       
   259     TInt idOfFirstEntry = KNoRequests;
       
   260     if( iRequests.Count() > 0 )
       
   261         {
       
   262         idOfFirstEntry = iRequests[KFirstItemIndex].RequestId();
       
   263         }
       
   264     DEBUG1( "CWlanTimerServices::RequestIdOfFirstEntry() - returning %d", idOfFirstEntry );
       
   265     return idOfFirstEntry;
       
   266     }    
       
   267 
       
   268 // ---------------------------------------------------------
       
   269 // CWlanTimerServices::RemoveRequest   
       
   270 // ---------------------------------------------------------
       
   271 //
       
   272 void CWlanTimerServices::RemoveRequest( const TUint& aRequestId )
       
   273     {
       
   274     DEBUG1( "CWlanTimerServices::RemoveRequest( aRequestId: %u )", aRequestId );
       
   275     
       
   276     TInt numOfRequests( iRequests.Count() );
       
   277     DEBUG1( "CWlanTimerServices::RemoveRequest() - numOfRequests: %d", numOfRequests );
       
   278     
       
   279     for( TInt index( 0 ); index < numOfRequests; index++ )
       
   280         {
       
   281         DEBUG2( "CWlanTimerServices::RemoveRequest() - checking iRequests[%d].RequestId: %d", index, iRequests[index].RequestId() );
       
   282         if( iRequests[index].RequestId() == aRequestId )
       
   283             {
       
   284             DEBUG1( "CWlanTimerServices::RemoveRequest() - matching request id found, removing index: %d", index );
       
   285             iRequests.Remove( index );
       
   286             break;
       
   287             }
       
   288         }
       
   289     
       
   290     DEBUG( "CWlanTimerServices::RemoveRequest() - done" );
       
   291     }
       
   292 
       
   293 // ---------------------------------------------------------
       
   294 // CWlanTimerServices::StopTimer   
       
   295 // ---------------------------------------------------------
       
   296 //
       
   297 void CWlanTimerServices::StopTimer( const TUint& aRequestId )
       
   298     {
       
   299     DEBUG1( "CWlanTimerServices::StopTimer( aRequestId: %u )", aRequestId );
       
   300     
       
   301     TInt numOfRequests( iRequests.Count() );
       
   302     DEBUG1( "CWlanTimerServices::StopTimer() - numOfRequests: %d", numOfRequests );
       
   303 
       
   304     TInt requestIdOfOriginallyFirstEntry( RequestIdOfFirstEntry() );
       
   305     
       
   306     DEBUG( "CWlanTimerServices::StopTimer() - calling RemoveRequest()" );
       
   307     RemoveRequest( aRequestId );
       
   308     DEBUG( "CWlanTimerServices::StopTimer() - RemoveRequest() returned" );
       
   309 
       
   310     if( iRequests.Count() > 0 )
       
   311         {
       
   312         if( requestIdOfOriginallyFirstEntry != iRequests[0].RequestId() )
       
   313             {
       
   314             DEBUG( "CWlanTimerServices::StopTimer() - first request changed, updating timer" );
       
   315             
       
   316             TTimeIntervalMicroSeconds32 newInterval( GetIntervalForNextRequest() );
       
   317                         
       
   318             ActivateTimer( newInterval );
       
   319             }
       
   320 #ifdef _DEBUG
       
   321         else
       
   322             {
       
   323             DEBUG( "CWlanTimerServices::StopTimer() - first request hasn't changed" );
       
   324             }
       
   325 #endif
       
   326         }
       
   327     else
       
   328         {
       
   329         DEBUG( "CWlanTimerServices::StopTimer() - request count is zero, cancelling timer" );
       
   330         Cancel();
       
   331         iTimer.Cancel();
       
   332         }
       
   333     DEBUG( "CWlanTimerServices::StopTimer() - done" );
       
   334     }    
       
   335 
       
   336 // ---------------------------------------------------------
       
   337 // CWlanTimerServices::GetIntervalForNextRequest
       
   338 // ---------------------------------------------------------
       
   339 //
       
   340 TTimeIntervalMicroSeconds32 CWlanTimerServices::GetIntervalForNextRequest()
       
   341     {
       
   342     DEBUG( "CWlanTimerServices::GetIntervalForNextRequest()" );
       
   343     
       
   344     TTimeIntervalMicroSeconds32 interval( 0 );
       
   345     
       
   346     while( iRequests.Count() > 0  && 
       
   347             KErrArgument == CalculateInterval( interval,
       
   348                         iRequests[KFirstItemIndex].GetAt(),
       
   349                         iRequests[KFirstItemIndex].GetDoSeveralRounds() ))
       
   350         {
       
   351         DEBUG1( "CWlanTimerServices::GetIntervalForNextRequest() - request %u happens in past, time out and remove it", iRequests[KFirstItemIndex].RequestId() );
       
   352         TUint requestToBeRemoved = iRequests[KFirstItemIndex].RequestId();
       
   353         iRequests[KFirstItemIndex].Timeout();
       
   354         RemoveRequest( requestToBeRemoved );
       
   355         }
       
   356     
       
   357     DEBUG( "CWlanTimerServices::GetIntervalForNextRequest() - done" );
       
   358     return interval;
       
   359     }
       
   360 
       
   361 // ---------------------------------------------------------
       
   362 // CWlanTimerServices::RunL
       
   363 // Timer has expired. 
       
   364 // ---------------------------------------------------------
       
   365 //
       
   366 void CWlanTimerServices::RunL()
       
   367     {
       
   368 
       
   369     DEBUG1( "CWlanTimerServices::RunL() - iStatus: %d", iStatus.Int() );
       
   370     switch( iStatus.Int() )
       
   371         {
       
   372         case KErrCancel:
       
   373             {
       
   374             DEBUG( "CWlanTimerServices::RunL() - iStatus == KErrCancel -> timer cancelled" );
       
   375             break;
       
   376             }
       
   377         case KErrNone:
       
   378             {
       
   379             DEBUG( "CWlanTimerServices::RunL() - iStatus == KErrNone -> timeout occurred" );
       
   380             HandleTimeout();
       
   381             break;
       
   382             }
       
   383         default:
       
   384             {
       
   385             DEBUG( "CWlanTimerServices::RunL() - unexpected iStatus!" );
       
   386             ASSERT( 0 );
       
   387             }
       
   388         }
       
   389     DEBUG( "CWlanTimerServices::RunL() - done" );
       
   390     }
       
   391 
       
   392 // ---------------------------------------------------------
       
   393 // CWlanTimerServices::HandleTimeout
       
   394 // ---------------------------------------------------------
       
   395 //
       
   396 void CWlanTimerServices::HandleTimeout()
       
   397     {
       
   398     DEBUG( "CWlanTimerServices::HandleTimeout()" );
       
   399 
       
   400     Cancel();
       
   401     iTimer.Cancel();
       
   402     
       
   403     // if requests exist...
       
   404     if( iRequests.Count() )
       
   405         {
       
   406         // if there's no need to do several rounds...
       
   407         if( !IsTimeInFuture( iRequests[KFirstItemIndex].At() ) )
       
   408         //if( iRequests[KFirstItemIndex].GetDoSeveralRounds() == EFalse )
       
   409             {
       
   410             // store id of the request to be timed out
       
   411             TUint requestIdToTimeout = iRequests[KFirstItemIndex].RequestId();
       
   412             DEBUG1( "CWlanTimerServices::HandleTimeout() - timeout request %u", requestIdToTimeout );
       
   413             iRequests[KFirstItemIndex].Timeout();
       
   414             DEBUG( "CWlanTimerServices::HandleTimeout() - make sure timed out request is removed" );
       
   415             RemoveRequest( requestIdToTimeout );
       
   416             }
       
   417         
       
   418         TTimeIntervalMicroSeconds32 newInterval( GetIntervalForNextRequest() );
       
   419 
       
   420         ActivateTimer( newInterval );
       
   421 
       
   422         }
       
   423 #ifdef _DEBUG
       
   424     else
       
   425         {
       
   426         DEBUG( "CWlanTimerServices::HandleTimeout() - no requests" );
       
   427         }
       
   428 #endif
       
   429     DEBUG( "CWlanTimerServices::HandleTimeout() - done" );
       
   430     }
       
   431 
       
   432 // ---------------------------------------------------------
       
   433 // CWlanTimerServices::HandleTimeout
       
   434 // ---------------------------------------------------------
       
   435 //
       
   436 TBool CWlanTimerServices::IsTimeInFuture( const TTime& aAt ) const
       
   437     {
       
   438     DEBUG( "CWlanTimerServices::IsTimeInFuture()" );
       
   439 
       
   440     TBool ret( ETrue );
       
   441     
       
   442     TTime currentTime;
       
   443     currentTime.HomeTime();
       
   444     
       
   445 #ifdef _DEBUG
       
   446     TBuf<KWlanTimerServicesMaxDateTimeStrLen> dbgString, timeoutDbgStr;
       
   447     TRAP_IGNORE( aAt.FormatL( timeoutDbgStr, KWlanTimerServicesDateTimeFormat ) );
       
   448     DEBUG1( "CWlanTimerServices::IsTimeInFuture() - time to check: %S", &timeoutDbgStr );
       
   449     TRAP_IGNORE( currentTime.FormatL( dbgString, KWlanTimerServicesDateTimeFormat ) );
       
   450     DEBUG1( "CWlanTimerServices::IsTimeInFuture() - time now:      %S", &dbgString );
       
   451 #endif
       
   452     
       
   453     if( aAt <= currentTime )
       
   454         {
       
   455         DEBUG( "CWlanTimerServices::IsTimeInFuture() - time is not in the future" );
       
   456         ret = EFalse;
       
   457         }
       
   458     
       
   459     DEBUG1( "CWlanTimerServices::IsTimeInFuture() - returning %d", ret );
       
   460     return ret;
       
   461     }
       
   462 
       
   463 // ---------------------------------------------------------
       
   464 // CWlanTimerServices::ActivateTimer
       
   465 // ---------------------------------------------------------
       
   466 //
       
   467 void CWlanTimerServices::ActivateTimer( const TTimeIntervalMicroSeconds32& aInterval )
       
   468     {
       
   469     DEBUG( "CWlanTimerServices::ActivateTimer()" );
       
   470 
       
   471     if( aInterval.Int() )
       
   472         {
       
   473         Cancel();
       
   474         iTimer.Cancel();
       
   475         iTimer.After( iStatus, aInterval );
       
   476         SetActive();
       
   477         DEBUG( "CWlanTimerServices::ActivateTimer() - timer active" );
       
   478         }   
       
   479     }
       
   480