email/alwaysonlineemailplugin/src/AlwaysOnlineEmailAgentBase.cpp
changeset 0 72b543305e3a
child 22 1367103c24e2
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2002 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 *     Email agent base class. common functions and data
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDES
       
    21 #include <AlwaysOnlineManagerCommon.h>
       
    22 #include <AlwaysOnlineStatusQueryInterface.h>
       
    23 #include <pop3set.h>
       
    24 #include <imapset.h>
       
    25 #include <SenduiMtmUids.h>
       
    26 #include <StringLoader.h>
       
    27 #include <AknGlobalNote.h>
       
    28 #include <stringresourcereader.h>
       
    29 #include <avkon.rsg>                            // Resouce identifiers
       
    30 #include <iapprefs.h>
       
    31 #include <rconnmon.h>
       
    32 #include <cdbcols.h>							// for some constants
       
    33 #include <MuiuMsvUiServiceUtilities.h>
       
    34 #include <messagingvariant.hrh>                 // Local variation flags
       
    35 #include <data_caging_path_literals.hrh>
       
    36 #include <messaginginternalcrkeys.h>            // Messaging keys
       
    37 #include <muiuemailtools.h>                     // MuiuEmailTools
       
    38 #include <ImumInternalApi.h>
       
    39 #include <ImumInSettingsData.h>
       
    40 #include <ImumInSettingsKeys.h>
       
    41 
       
    42 #include <cmconnectionmethoddef.h>
       
    43 #include <cmpluginvpndef.h>
       
    44 #include <ImumDaSettingsKeys.h>
       
    45 
       
    46 #include "AlwaysOnlineEmailPluginLogging.h"
       
    47 #include "AlwaysOnlineEmailLoggingTools.h"
       
    48 #include "AlwaysOnlineEmailAgentBase.h"
       
    49 #include "AlwaysOnlineEmailPluginTimer.h"
       
    50 #include "AlwaysOnlineEmailAgent.h"
       
    51 #include <AlwaysOnlineEmailPluginData.rsg>
       
    52 
       
    53 // CONSTANTS
       
    54 // Correct path is added to literal when it is used.
       
    55 _LIT(KEmailPluginResource, "AlwaysOnlineEmailPluginData.rsc");
       
    56 const TInt KEmailAgentBaseOperationsGranularity = 2;
       
    57 const TInt KFileLoggerCounter = 100;
       
    58 const TInt KMailSettingsIapPreferenceNumber     = 0;
       
    59 const TInt KEmailPluginQueryTextLength    = 150;
       
    60 
       
    61 const TInt KAoInterval5Min   = 5;
       
    62 const TInt KAoInterval15Min  = 15;
       
    63 const TInt KAoInterval30Min  = 30;
       
    64 const TInt KAoInterval1Hour  = 60;
       
    65 const TInt KAoInterval2Hours = 120;
       
    66 const TInt KAoInterval4Hours = 240;
       
    67 const TInt KAoInterval6Hours = 360;
       
    68 
       
    69 // ----------------------------------------------------------------------------
       
    70 // CAlwaysOnlineEmailAgentBase()
       
    71 // ----------------------------------------------------------------------------
       
    72 CAlwaysOnlineEmailAgentBase::CAlwaysOnlineEmailAgentBase(
       
    73     CMsvSession& aSession, CClientMtmRegistry& aClientMtmRegistry,
       
    74     MAlwaysOnlineStatusQueryInterface& aAlwaysOnlineManager,
       
    75     CAlwaysOnlineEmailAgent& aEmailAgent )
       
    76     :
       
    77     iClientMtmRegistry( aClientMtmRegistry ),
       
    78     iSession( aSession ),
       
    79     iEntry ( NULL ),
       
    80     iOperations( KEmailAgentBaseOperationsGranularity ),
       
    81     iState( EEmailAgentInitialised ),
       
    82     iRetryCounter( 0 ),
       
    83     iLoggerFileCounter( KFileLoggerCounter ),
       
    84     iMailboxApi( NULL ),
       
    85     iMailboxSettings( NULL ),
       
    86     iError( KErrNone ),
       
    87     iNcnNotification ( NULL ),
       
    88     iStatusQueryInterface( aAlwaysOnlineManager ),
       
    89     iEmailAgent( aEmailAgent ),
       
    90     iFlags( NULL )
       
    91     {
       
    92     }
       
    93 
       
    94 // ----------------------------------------------------------------------------
       
    95 // ~CAlwaysOnlineEmailAgentBase ()
       
    96 // ----------------------------------------------------------------------------
       
    97 CAlwaysOnlineEmailAgentBase::~CAlwaysOnlineEmailAgentBase()
       
    98     {
       
    99     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::~CAlwaysOnlineEmailAgentBase" );
       
   100     delete iMailboxApi;
       
   101     iMailboxApi = NULL;
       
   102     delete iMailboxSettings;
       
   103     iMailboxSettings = NULL;
       
   104 
       
   105     delete iNcnNotification;
       
   106     delete iEntry;
       
   107 
       
   108     iCmManager.Close();
       
   109     }
       
   110 
       
   111 // ----------------------------------------------------------------------------
       
   112 // ConstructL
       
   113 // ----------------------------------------------------------------------------
       
   114 void CAlwaysOnlineEmailAgentBase::ConstructL( TMsvId aMailboxId )
       
   115     {
       
   116     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::ConstructL" );
       
   117     iIntervalWaitId = KErrNotFound;
       
   118     iConnectOpId = KErrNotFound;
       
   119     iConnectSyncOpId = KErrNotFound;
       
   120     iSyncOpId = KErrNotFound;
       
   121     iWaitForStartOpId = KErrNotFound;
       
   122     iWaitForStopOpId = KErrNotFound;
       
   123     iStartDelayOpId = KErrNotFound;
       
   124     iConnectAndStayOnlineOpId = KErrNotFound;
       
   125     iDisconnectOpId = KErrNotFound;
       
   126     iFolderUpdateTimerOpId = KErrNotFound;
       
   127     iFolderSyncOpId = KErrNotFound;
       
   128     iFilteredPopulateOpId = KErrNotFound;
       
   129 
       
   130     iEntry = iSession.GetEntryL( aMailboxId );
       
   131     // Handle flags, including variation
       
   132     AlwaysOnlineFlagsL();
       
   133 
       
   134     iMailboxApi = CreateEmailApiL( &iSession );
       
   135     iMailboxSettings =
       
   136         iMailboxApi->MailboxServicesL().LoadMailboxSettingsL( aMailboxId );
       
   137 
       
   138 
       
   139     iRetryCounter = 0;
       
   140 
       
   141     iCmManager.OpenL();
       
   142     }
       
   143 
       
   144 // ----------------------------------------------------------------------------
       
   145 // OpCompleted
       
   146 // ----------------------------------------------------------------------------
       
   147 void CAlwaysOnlineEmailAgentBase::OpCompleted(
       
   148     CMsvSingleOpWatcher& aOpWatcher,
       
   149     TInt /*aCompletionCode*/ )
       
   150     {
       
   151     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::OpCompleted" );
       
   152     CMsvOperation* op=&aOpWatcher.Operation();
       
   153     TMsvOp opId = op->Id();
       
   154     KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::OpCompleted() Op Id: %d", opId);
       
   155     const TInt count = iOperations.Count();
       
   156 
       
   157     for ( TInt i = count - 1; i >= 0; i-- )
       
   158         {
       
   159         // We need to check the id of a completed operation that it
       
   160         // matches to what we expect, because there may be several
       
   161         // simultaneous operations and there is no guarantee that
       
   162         // they comlete in the order we think they do.
       
   163         CMsvOperation& oper = iOperations[i]->Operation();
       
   164 
       
   165         if ( oper.Id() == opId )
       
   166             {
       
   167             CMsvSingleOpWatcher* opWatcher = iOperations[i];
       
   168             KAOEMAIL_LOGGER_WRITE_FORMAT(">>>> iOperations count before : %d", iOperations.Count());
       
   169             iOperations.Delete( i );
       
   170             // The operations matches, handle it
       
   171             HandleCompletingOperation( opId, *op, op->Mtm() );
       
   172             KAOEMAIL_LOGGER_WRITE_FORMAT(">>>> iOperations count after : %d", iOperations.Count());
       
   173             delete opWatcher;
       
   174 
       
   175             break;
       
   176             }
       
   177         }
       
   178 
       
   179     // Change the state
       
   180     TRAPD( err, ChangeNextStateL() );
       
   181     if ( err != KErrNone )
       
   182         {
       
   183         //not much to do if this fails for some reason. Just reset all and restart
       
   184         KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::OpCompleted() ChangeNextStateL returned error: %d , resetting all!", err );
       
   185         ResetAll();
       
   186         iState = EEmailAgentInitialised;
       
   187 
       
   188         // Just catch the possible leaving and continue execution
       
   189         TRAP( err, CreateCompletedOpL() );
       
   190         }
       
   191 
       
   192     }
       
   193 
       
   194 // ----------------------------------------------------------------------------
       
   195 // AppendWatcherAndSetOperationL
       
   196 // ----------------------------------------------------------------------------
       
   197 void CAlwaysOnlineEmailAgentBase::AppendWatcherAndSetOperationL(
       
   198     CMsvSingleOpWatcher* aWatcher,
       
   199     CMsvOperation* aOperation )
       
   200     {
       
   201     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::AppendWatcherAndSetOperationL" );
       
   202     iOperations.AppendL( aWatcher );
       
   203     aWatcher->SetOperation( aOperation ); // takes immediately ownership
       
   204 
       
   205     KAOEMAIL_LOGGER_WRITE( "-------------------<APPEND: OpInfo>-----------------" );
       
   206     KAOEMAIL_LOGGER_WRITE_FORMAT( "Completing operation: aOpId: %d", aOperation->Id() );
       
   207     KAOEMAIL_LOGGER_WRITE_FORMAT( "Completing operation: aUid: %d", aOperation->Mtm().iUid );
       
   208     KAOEMAIL_LOGGER_WRITE_FORMAT( "Completing operation: Op Count: %d", iOperations.Count() );
       
   209     KAOEMAIL_LOGGER_WRITE( "-------------------<APPEND: OpInfo>-----------------" );
       
   210     }
       
   211 
       
   212 // ----------------------------------------------------------------------------
       
   213 // MailboxId
       
   214 // ----------------------------------------------------------------------------
       
   215 TMsvId CAlwaysOnlineEmailAgentBase::MailboxId() const
       
   216     {
       
   217     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::MailboxId" );
       
   218     return iEntry->Entry().Id();
       
   219     }
       
   220 
       
   221 //-----------------------------------------------------------------------------
       
   222 // EmailAddress
       
   223 //-----------------------------------------------------------------------------
       
   224 void CAlwaysOnlineEmailAgentBase::EmailAddress( TDes& aEmailAddress )
       
   225     {
       
   226     iMailboxSettings->GetAttr(
       
   227         TImumDaSettings::EKeyEmailAddress, aEmailAddress );
       
   228     }
       
   229 
       
   230 //-----------------------------------------------------------------------------
       
   231 // Username
       
   232 //-----------------------------------------------------------------------------
       
   233 void CAlwaysOnlineEmailAgentBase::Username( TDes8& aUsername )
       
   234     {
       
   235     // trap ignored, only leave descriptor empty in case of error
       
   236     TRAP_IGNORE( aUsername = LoadSettingL<TImumDaSettings::TTextUserName>( // CSI: 59 # trap has leaving code
       
   237                  TImumDaSettings::EKeyUsername, ETrue); );
       
   238     }
       
   239 
       
   240 
       
   241 //-----------------------------------------------------------------------------
       
   242 // ServerAddress
       
   243 //-----------------------------------------------------------------------------
       
   244 void CAlwaysOnlineEmailAgentBase::ServerAddress( TDes& aServer )
       
   245     {
       
   246     // leave descriptor empty in case of error
       
   247     TRAP_IGNORE( aServer = LoadSettingL<TImumDaSettings::TTextServerAddress>( // CSI: 59 # trap has leaving code
       
   248                  TImumDaSettings::EKeyServer, ETrue); );
       
   249     }
       
   250 
       
   251 //-----------------------------------------------------------------------------
       
   252 // StartTimerOperationL
       
   253 // ----------------------------------------------------------------------------
       
   254 void CAlwaysOnlineEmailAgentBase::StartTimerOperationL(
       
   255     const TTime& aTime,
       
   256     TMsvOp& aOpId )
       
   257     {
       
   258     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::StartTimerOperationL" );
       
   259     CMsvSingleOpWatcher* watcher = CMsvSingleOpWatcher::NewL(*this);
       
   260     CleanupStack::PushL( watcher );
       
   261 
       
   262     CAlwaysOnlineEmailPluginTimer* timer = 
       
   263         CAlwaysOnlineEmailPluginTimer::NewL( iSession, watcher->iStatus );
       
   264     CleanupStack::PushL( timer );
       
   265     KAOEMAIL_LOGGER_WRITE_DATETIME("CAlwaysOnlineEmailAgentBase::StartTimerOperationL() Expires at: ", aTime);
       
   266     timer->At( aTime );  // CSI: 1 # not an array
       
   267 
       
   268     aOpId = timer->Id();
       
   269 
       
   270     AppendWatcherAndSetOperationL( watcher, timer ); // takes immediately ownership
       
   271     CleanupStack::Pop( 2, watcher ); // timer // CSI: 12,47 # nothing worng
       
   272     }
       
   273 
       
   274 
       
   275 // ---------------------------------------------------------------------------
       
   276 // CAlwaysOnlineEmailAgentBase::AoState()
       
   277 // ---------------------------------------------------------------------------
       
   278 //
       
   279 TInt CAlwaysOnlineEmailAgentBase::AoState() const
       
   280     {
       
   281     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::AoState" );
       
   282     TInt state = 0;
       
   283     iMailboxSettings->GetAttr(
       
   284         TImumDaSettings::EKeyAutoRetrieval, state );
       
   285     return state;
       
   286     }
       
   287 
       
   288 // ---------------------------------------------------------------------------
       
   289 // CAlwaysOnlineEmailAgentBase::EmnState()
       
   290 // ---------------------------------------------------------------------------
       
   291 //
       
   292 TInt CAlwaysOnlineEmailAgentBase::EmnState() const
       
   293     {
       
   294     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::EmnState" );
       
   295     TInt state = 0;
       
   296     iMailboxSettings->GetAttr(
       
   297         TImumDaSettings::EKeyAutoNotifications, state );
       
   298     return state;
       
   299     }
       
   300 
       
   301 
       
   302 // ----------------------------------------------------------------------------
       
   303 // ConnectL
       
   304 // ----------------------------------------------------------------------------
       
   305 void CAlwaysOnlineEmailAgentBase::ConnectL()
       
   306     {
       
   307     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::ConnectL" );
       
   308     KAOEMAIL_LOGGER_FN1("CAlwaysOnlineEmailAgentBase::ConnectL");
       
   309 
       
   310     if ( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelWithOverheadL(
       
   311             iSession, 0, KAOSafetyMargin ) && !IsTemporary() )
       
   312         {
       
   313         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ConnectL(): Disk full, setting AO of.");
       
   314         DisplayGlobalErrorNoteL( EEmailAgentOutOfDisk );
       
   315         SwitchAutoUpdateOffL();
       
   316         return;
       
   317         }
       
   318 
       
   319     TBool allowed = ETrue;
       
   320 
       
   321     TBool offline =
       
   322         reinterpret_cast<TBool>( iStatusQueryInterface.QueryStatusL(
       
   323             EAOManagerStatusQueryOffline ) );
       
   324 
       
   325     if ( offline )
       
   326         {
       
   327         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ConnectL(). Trying to connect while offline mode! Not allowing!");
       
   328         allowed = EFalse;
       
   329         }
       
   330 
       
   331     TAlwaysOnlineEmailIAPNotes invalidity;
       
   332 
       
   333     if ( allowed && IsIAPInvalidL( invalidity ) )
       
   334         {
       
   335         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ConnectL(). Accesspoint faulty or prompting password, switching off!");
       
   336         DisplayGlobalErrorNoteL( invalidity );
       
   337         SwitchAutoUpdateOffL();
       
   338         return;
       
   339         }
       
   340 
       
   341 
       
   342     if ( allowed && AoState() == TImumDaSettings::EValueAutoOff &&
       
   343         EmnState() == TImumDaSettings::EValueNotificationsOff )
       
   344         {
       
   345         // User is propably in settings, and we're turned off.
       
   346         // Wait timer event just has been running and completed while
       
   347         // user launched settings. Don't connect.
       
   348         allowed = EFalse;
       
   349         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ConnectL(). Settings dialog seems to be open. Won't connect.");
       
   350         }
       
   351 
       
   352     // UI takes care that either AO or EMN is turned on.
       
   353     if ( allowed && (AoState() == TImumDaSettings::EValueAutoHomeNetwork ||
       
   354         EmnState() == TImumDaSettings::EValueNotificationsHome) )
       
   355         {
       
   356         TInt networkStatus =
       
   357             reinterpret_cast< TInt >( iStatusQueryInterface.QueryStatusL(
       
   358                 EAOManagerStatusQueryNetwork ) );
       
   359 
       
   360         KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::ConnectL() Network status: %d", networkStatus );
       
   361 
       
   362         if( networkStatus != ENetworkRegistrationHomeNetwork )
       
   363             {
       
   364             KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ConnectL(). We're not on home network. Won't connect");
       
   365             allowed = EFalse;
       
   366             }
       
   367         }
       
   368 
       
   369     if ( !allowed )
       
   370         {
       
   371         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ConnectL(). Connect not allowed -> idle");
       
   372         iState = EEmailAgentIdle;
       
   373         CreateCompletedOpL();
       
   374         return;
       
   375         }
       
   376 
       
   377     ConnectAndUpdateHeadersL();
       
   378     KAOEMAIL_LOGGER_FN2("CAlwaysOnlineEmailAgentBase::ConnectL");
       
   379     }
       
   380 
       
   381 // ----------------------------------------------------------------------------
       
   382 // CAlwaysOnlineEmailAgentBase::CleanOperation()
       
   383 // ----------------------------------------------------------------------------
       
   384 //
       
   385 void CAlwaysOnlineEmailAgentBase::CleanOperation( TMsvOp& aOpId )
       
   386     {
       
   387     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::CleanOperation" );
       
   388     const TInt count = iOperations.Count();
       
   389 
       
   390     for ( TInt i=0; i < count; i++ )
       
   391         {
       
   392         if ( iOperations[i]->Operation().Id() == aOpId )
       
   393             {
       
   394             KAOEMAIL_LOGGER_WRITE( "-------------------<REMOVE: OpInfo>-----------------" );
       
   395             KAOEMAIL_LOGGER_WRITE_FORMAT( "Completing operation: aOpId: %d", aOpId );
       
   396             KAOEMAIL_LOGGER_WRITE_FORMAT( "Completing operation: aUid: %d", iOperations[i]->Operation().Mtm().iUid );
       
   397 
       
   398             // First set id to KErrNotFound so OpCompleted won't
       
   399             // take any action because of this
       
   400             aOpId = KErrNotFound;
       
   401             delete iOperations[i];
       
   402             iOperations[i] = NULL;
       
   403             iOperations.Delete(i);
       
   404 
       
   405             KAOEMAIL_LOGGER_WRITE_FORMAT( "Completing operation: Op Count: %d", iOperations.Count() );
       
   406             KAOEMAIL_LOGGER_WRITE( "-------------------<REMOVE: OpInfo>-----------------" );
       
   407             break;
       
   408             }//if
       
   409         }//for
       
   410     }
       
   411 
       
   412 // ----------------------------------------------------------------------------
       
   413 // CAlwaysOnlineEmailAgentBase::LaunchStartTimerL()
       
   414 // ----------------------------------------------------------------------------
       
   415 //
       
   416 void CAlwaysOnlineEmailAgentBase::LaunchStartTimerL(
       
   417     TTime& aClock,
       
   418     const TTimeIntervalSeconds& aSeconds )
       
   419     {
       
   420     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::LaunchStartTimerL" );
       
   421     //wait for start
       
   422     KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::LaunchStartTimerL() Checking for wait for START schedule");
       
   423 
       
   424     // The connection is on, and the connection is required, this means
       
   425     // the mailbox in online during the time it should not be
       
   426     if ( iConnectAndStayOnlineOpId != KErrNotFound )
       
   427         {
       
   428         DisconnectL( ETrue );
       
   429         }
       
   430 
       
   431     KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::LaunchStartTimerL. Minutes to wait ( time ): %d ",( aSeconds.Int()/60 ) ); // CSI: 47 # seconds to minutes
       
   432 
       
   433     aClock += aSeconds;
       
   434     StartTimerOperationL( aClock, iWaitForStartOpId );
       
   435 
       
   436     KAOEMAIL_LOGGER_WRITE_DATETIME("Started waitForStartTimer. Expiring at: ", aClock);
       
   437 
       
   438     iState = EEmailAgentTimerWaitingForStart;
       
   439     KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::LaunchStartTimerL. Setting state:  %d ",iState );
       
   440 
       
   441     CleanOperation( iWaitForStopOpId );
       
   442     iWaitForStopOpId = KErrNotFound;//set to KErrNotFound
       
   443 
       
   444     // If waiting for start, we don't need to connect after saving settings,
       
   445     // thus set this to false.
       
   446     iFlags->ClearFlag( EAOBFConnectNow );
       
   447     }
       
   448 
       
   449 // ----------------------------------------------------------------------------
       
   450 // CAlwaysOnlineEmailAgentBase::LaunchStopTimerL()
       
   451 // ----------------------------------------------------------------------------
       
   452 //
       
   453 void CAlwaysOnlineEmailAgentBase::LaunchStopTimerL(
       
   454     TTime& aClock,
       
   455     const TTimeIntervalSeconds& aSeconds )
       
   456     {
       
   457     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::LaunchStopTimerL" );
       
   458     //wait for stop
       
   459     KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::LaunchStopTimerL() Checking for wait for STOP schedule");
       
   460 
       
   461     if( aSeconds.Int() == 0)
       
   462         {
       
   463         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::LaunchStopTimerL() All days and all hours scheduled");
       
   464         iState = EEmailAgentTimerWaitingForStart;//causes us to connect
       
   465         KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::LaunchStopTimerL(). Setting state:  %d ",iState );
       
   466         CreateCompletedOpL();//creates completed operation
       
   467         return;
       
   468         }
       
   469     else
       
   470         {
       
   471         KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::LaunchStopTimerL. Minutes to wait ( time ): %d ",( aSeconds.Int()/60 + 0.5 ) ); // CSI: 47 # seconds to minutes
       
   472         aClock += aSeconds;
       
   473         StartTimerOperationL( aClock, iWaitForStopOpId );
       
   474 
       
   475         CleanOperation( iWaitForStartOpId );
       
   476         iWaitForStartOpId = KErrNotFound;//set to KErrNotFound
       
   477 
       
   478         KAOEMAIL_LOGGER_WRITE_DATETIME("Started waitForStopTimer. Expiring at: ", aClock);
       
   479         }
       
   480     }
       
   481 
       
   482 // ----------------------------------------------------------------------------
       
   483 // CheckAndHandleSchedulingL
       
   484 // ----------------------------------------------------------------------------
       
   485 void CAlwaysOnlineEmailAgentBase::CheckAndHandleSchedulingL()
       
   486     {
       
   487     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::CheckAndHandleSchedulingL" );
       
   488     TTime clock;
       
   489     clock.HomeTime();
       
   490 
       
   491     TTimeIntervalSeconds secondsInterval;
       
   492     TInt64 connectionState = 0x00;
       
   493     iMailboxApi->MailboxUtilitiesL().NextAlwaysOnlineIntervalL(
       
   494         iEntry->Entry().Id(),
       
   495         connectionState, secondsInterval );
       
   496 
       
   497     KAOEMAIL_LOGGER_WRITE_FORMAT( "Stop Timer: %d", iWaitForStopOpId );
       
   498     KAOEMAIL_LOGGER_WRITE_FORMAT( "Start Timer: %d", iWaitForStartOpId );
       
   499     KAOEMAIL_LOGGER_WRITE_FORMAT( "Interval Timer: %d", iIntervalWaitId );
       
   500 
       
   501     if ( iWaitForStopOpId != KErrNotFound )
       
   502         {
       
   503         KAOEMAIL_LOGGER_WRITE( "* Cleaning stop timer *" );
       
   504         CleanOperation( iWaitForStopOpId );
       
   505         }
       
   506 
       
   507     if ( iWaitForStartOpId != KErrNotFound )
       
   508         {
       
   509         KAOEMAIL_LOGGER_WRITE( "* Cleaning start timer *" );
       
   510         CleanOperation( iWaitForStartOpId );
       
   511         }
       
   512 
       
   513     if( iIntervalWaitId != KErrNotFound )
       
   514         {
       
   515         KAOEMAIL_LOGGER_WRITE( "* Cleaning interval timer *" );
       
   516         CleanOperation( iIntervalWaitId );
       
   517         }
       
   518 
       
   519     // Not connected and should connect
       
   520     if ( connectionState & MImumInMailboxUtilities::EFlagWaitingToConnect )
       
   521         {
       
   522         LaunchStartTimerL( clock, secondsInterval );
       
   523         }
       
   524     // Connected and should disconnect
       
   525     else
       
   526         {
       
   527         LaunchStopTimerL( clock, secondsInterval );
       
   528         }
       
   529     }
       
   530 
       
   531 // ----------------------------------------------------------------------------
       
   532 // ResetAll
       
   533 // ----------------------------------------------------------------------------
       
   534 void CAlwaysOnlineEmailAgentBase::ResetAll()
       
   535     {
       
   536     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::ResetAll" );
       
   537     KAOEMAIL_LOGGER_WRITE_FORMAT("ResetAll() Reset All called. Operation count: %d", iOperations.Count() );
       
   538 
       
   539     iOperations.ResetAndDestroy();
       
   540 
       
   541     //if we're still connected, do sync disconnet. Connect check is inside this function
       
   542     //can leave, so trap. ResetAll() is not leaving function
       
   543     TRAP_IGNORE( DoSyncDisconnectL() );
       
   544 
       
   545     iIntervalWaitId = KErrNotFound;
       
   546     iConnectOpId = KErrNotFound;
       
   547     iConnectSyncOpId = KErrNotFound;
       
   548     iSyncOpId = KErrNotFound;
       
   549     iWaitForStartOpId = KErrNotFound;
       
   550     iWaitForStopOpId = KErrNotFound;
       
   551     iConnectAndStayOnlineOpId = KErrNotFound;
       
   552     iDisconnectOpId = KErrNotFound;
       
   553     iFolderUpdateTimerOpId = KErrNotFound;
       
   554     iFolderSyncOpId = KErrNotFound;
       
   555     iFilteredPopulateOpId = KErrNotFound;
       
   556     }
       
   557 
       
   558 
       
   559 // ----------------------------------------------------------------------------
       
   560 // Suspend
       
   561 // ----------------------------------------------------------------------------
       
   562 void CAlwaysOnlineEmailAgentBase::Suspend()
       
   563     {
       
   564     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::Suspend" );
       
   565     KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::SuspendL() Suspend called. Resetting and going to idle");
       
   566     ResetAll();
       
   567     iState = EEmailAgentIdle;
       
   568     // We may start up suspended, so set this to false.
       
   569     iFlags->ClearFlag( EAOBFConnectNow );
       
   570     }
       
   571 
       
   572 // ----------------------------------------------------------------------------
       
   573 // ResumeL
       
   574 // ----------------------------------------------------------------------------
       
   575 void CAlwaysOnlineEmailAgentBase::ResumeL( const TBool aConnectNow )
       
   576     {
       
   577     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::ResumeL" );
       
   578     // We are here, because agent got resume command, so we need to refresh our
       
   579     // settings objects by deleting current settings. New settings objects are
       
   580     // created and loaded when certain setting is used first time after resume.
       
   581     // iAlwaysOnlineEmailScheduler's settings reference is also updated, this
       
   582     // happens in ExtensionSettings() function.
       
   583 
       
   584     // Update the settings here
       
   585     delete iMailboxSettings;
       
   586     iMailboxSettings = NULL;
       
   587 
       
   588     iMailboxSettings =
       
   589         iMailboxApi->MailboxServicesL().LoadMailboxSettingsL(
       
   590             iEntry->Entry().Id() );
       
   591 
       
   592     // Set connection status, so the connection can be made, if needed
       
   593     iFlags->ChangeFlag( EAOBFConnectNow, aConnectNow );
       
   594 
       
   595     KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::ResumeL() iState: %d", iState );
       
   596     if ( iState == EEmailAgentIdle )
       
   597         {
       
   598         if ( AoState() != TImumDaSettings::EValueAutoOn )
       
   599             {
       
   600             //check does roaming setting allow us to resume
       
   601             TInt networkStatus =
       
   602                 reinterpret_cast<TInt>( iStatusQueryInterface.QueryStatusL(
       
   603                     EAOManagerStatusQueryNetwork ) );
       
   604 
       
   605             KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::ResumeL() Network status: %d", networkStatus );
       
   606             if ( networkStatus != ENetworkRegistrationHomeNetwork )
       
   607                 {
       
   608                 //not going to resume, stay idle
       
   609                 KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ResumeL() Resume called. Home only setting won't allow us to resume. Still idling");
       
   610                 return;
       
   611                 }//if
       
   612             }//if
       
   613         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ResumeL() Resume called. Settings state to Initialised ( 0 )");
       
   614         iState = EEmailAgentInitialised;
       
   615         CreateCompletedOpL();
       
   616         }
       
   617     }
       
   618 
       
   619 // ----------------------------------------------------------------------------
       
   620 // HandleRoamingEventL
       
   621 // ----------------------------------------------------------------------------
       
   622 void CAlwaysOnlineEmailAgentBase::HandleRoamingEventL()
       
   623     {
       
   624     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::HandleRoamingEventL" );
       
   625     // UI takes care that either AO or EMN is turned on.
       
   626     if ( AoState() != TImumDaSettings::EValueAutoOn ||
       
   627          EmnState() != TImumDaSettings::EValueNotificationsOn )
       
   628         {
       
   629         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleRoamingEventL() Roaming started and we're not set to update during roaming, going to idle");
       
   630         ResetAll();
       
   631         iState = EEmailAgentIdle;
       
   632         }
       
   633     }
       
   634 
       
   635 
       
   636 // ----------------------------------------------------------------------------
       
   637 // HandleOutOfDiskEventL
       
   638 // ----------------------------------------------------------------------------
       
   639 void CAlwaysOnlineEmailAgentBase::HandleOutOfDiskEventL()
       
   640     {
       
   641     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::HandleOutOfDiskEventL" );
       
   642     KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleOutOfDiskEventL() Ran out of disk! Switching off!");
       
   643     // Check if agent is temporary, which means that we are not allowed to show
       
   644     // any notes. Only IMAP mailbox can have temporary agent.
       
   645     if ( !IsTemporary() )
       
   646         {
       
   647         DisplayGlobalErrorNoteL(
       
   648             TAlwaysOnlineEmailIAPNotes( EEmailAgentOutOfDisk ) );
       
   649         SwitchAutoUpdateOffL();
       
   650         }
       
   651     }
       
   652 
       
   653 // ----------------------------------------------------------------------------
       
   654 // SwitchOffL
       
   655 // ----------------------------------------------------------------------------
       
   656 void CAlwaysOnlineEmailAgentBase::SwitchOffL()
       
   657     {
       
   658     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::SwitchOffL" );
       
   659     KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::SwitchOffL() ORDERED TO SWITCH OFF, COMPLYING!");
       
   660     SwitchAutoUpdateOffL();
       
   661     }
       
   662 
       
   663 // ----------------------------------------------------------------------------
       
   664 // HandleHomeNetworkEventL
       
   665 // ----------------------------------------------------------------------------
       
   666 void CAlwaysOnlineEmailAgentBase::HandleHomeNetworkEventL()
       
   667     {
       
   668     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::HandleHomeNetworkEventL" );
       
   669     // This might be true when there is a temporary mail agent.
       
   670     if ( AoState() != TImumDaSettings::EValueAutoOn ||
       
   671          EmnState() != TImumDaSettings::EValueNotificationsOn )
       
   672         {
       
   673         if( iState == EEmailAgentIdle )
       
   674             {
       
   675             KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleHomeNetworkEventL() HomeNetwork event received, starting up");
       
   676             iState = EEmailAgentInitialised;
       
   677             CreateCompletedOpL();
       
   678             }
       
   679         else
       
   680             {
       
   681             KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleHomeNetworkEventL() HomeNetwork event received But we're running already...ignore");
       
   682             }
       
   683         }
       
   684     }
       
   685 
       
   686 // ----------------------------------------------------------------------------
       
   687 // SetLastSuccessfulUpdate
       
   688 // ----------------------------------------------------------------------------
       
   689 void CAlwaysOnlineEmailAgentBase::SetLastSuccessfulUpdate()
       
   690     {
       
   691     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::SetLastSuccessfulUpdate" );
       
   692     TBool lastUpdateFailed = EFalse;
       
   693     TTime time = TTime();
       
   694     TBool updSuccess = ETrue;
       
   695     time.HomeTime();
       
   696     iMailboxSettings->SetAttr(
       
   697         TImumInSettings::EKeyInfoLastUpdateFailed,
       
   698         lastUpdateFailed );
       
   699     iMailboxSettings->SetAttr(
       
   700         TImumInSettings::EKeyInfoLastSuccessfulUpdate,
       
   701         time.Int64() );
       
   702     iMailboxSettings->SetAttr(
       
   703         TImumInSettings::EKeyAoUpdateSuccessfulWithCurSettings, updSuccess );
       
   704 
       
   705     TRAP_IGNORE( iMailboxApi->MailboxServicesL().SaveMailboxSettingsL( *iMailboxSettings ) );
       
   706     }
       
   707 
       
   708 // ----------------------------------------------------------------------------
       
   709 // SetLastUpdateFailedL
       
   710 // ----------------------------------------------------------------------------
       
   711 void CAlwaysOnlineEmailAgentBase::SetLastUpdateFailed()
       
   712     {
       
   713     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::SetLastUpdateFailed" );
       
   714     TBool updateFailed = LoadSettingL<TInt>(
       
   715         TImumInSettings::EKeyInfoLastUpdateFailed, EFalse );
       
   716 
       
   717     if ( !updateFailed )
       
   718         {
       
   719         iMailboxSettings->SetAttr(
       
   720             TImumInSettings::EKeyInfoLastUpdateFailed,
       
   721             ETrue );
       
   722         TRAP_IGNORE( iMailboxApi->MailboxServicesL().SaveMailboxSettingsL(
       
   723             *iMailboxSettings ) );
       
   724         }
       
   725 
       
   726     }
       
   727 
       
   728 // ----------------------------------------------------------------------------
       
   729 // DisplayGlobalErrorNoteL
       
   730 // ----------------------------------------------------------------------------
       
   731 void CAlwaysOnlineEmailAgentBase::DisplayGlobalErrorNoteL(
       
   732         TAlwaysOnlineEmailIAPNotes aInvalidity )
       
   733     {
       
   734     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::DisplayGlobalErrorNoteL" );
       
   735     //NOTE: WHEN USING THIS FUNCTION TO SHOW ERROR NOTES,
       
   736     //STRINGS MUST CONTAIN %U PARAMETER FOR MAILBOX NAME
       
   737 
       
   738     TFileName resourceFile;
       
   739     TParse tp;
       
   740     tp.Set( KEmailPluginResource, &KDC_RESOURCE_FILES_DIR, NULL );
       
   741     resourceFile.Copy( tp.FullName() );
       
   742     CStringResourceReader* resourceReader = NULL;
       
   743     TRAPD( err, resourceReader = CStringResourceReader::NewL( resourceFile ) );
       
   744     if ( err != KErrNone )
       
   745         {
       
   746         //if resource not present for some reason, just return.
       
   747         //User will not see error note, but no other harm done.
       
   748         return;
       
   749         }
       
   750     CleanupStack::PushL( resourceReader );//can't use LC in TRAPD
       
   751 
       
   752     TBuf<KEmailPluginQueryTextLength> tempText;
       
   753 
       
   754     switch ( aInvalidity )
       
   755         {
       
   756         case EEmailAgentCSDIAP:
       
   757             tempText = resourceReader->ReadResourceString(
       
   758                 R_EMAIL_PLUGIN_INVALID_AP_BEARER );
       
   759             break;
       
   760         case EEmailAgentOutOfDisk:
       
   761             tempText = resourceReader->ReadResourceString(
       
   762                 R_EMAIL_PLUGIN_OUT_OF_DISK );
       
   763             break;
       
   764         case EEmailAgentInvalidInterval:
       
   765         case EEmailAgentEMNFatalError:
       
   766         case EEmailAgentOtherInvalidity:
       
   767         default:
       
   768             tempText = resourceReader->ReadResourceString(
       
   769                 R_EMAIL_PLUGIN_ALWAYS_INCORRECT );
       
   770             break;
       
   771         }
       
   772 
       
   773     TBuf<KEmailPluginQueryTextLength> noteText;
       
   774     StringLoader::Format(
       
   775         noteText,
       
   776         tempText,
       
   777         -1,
       
   778         iEntry->Entry().iDetails.Left(
       
   779                     KEmailPluginQueryTextLength - tempText.Length() )
       
   780         );
       
   781 
       
   782     CAknGlobalNote* note = CAknGlobalNote::NewL();
       
   783     CleanupStack::PushL( note );
       
   784     note->SetSoftkeys( R_AVKON_SOFTKEYS_OK_EMPTY__OK );
       
   785     note->ShowNoteL( EAknGlobalErrorNote, noteText );
       
   786     CleanupStack::PopAndDestroy( 2, resourceReader ); // note // CSI: 12,47 # nothing wrong
       
   787     }
       
   788 
       
   789 
       
   790 // ----------------------------------------------------------------------------
       
   791 // QueryAndHandleAOServerInfoL
       
   792 // ----------------------------------------------------------------------------
       
   793 void CAlwaysOnlineEmailAgentBase::QueryAndHandleAOServerInfoL( TBool& aSuspended )
       
   794     {
       
   795     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::QueryAndHandleAOServerInfoL" );
       
   796     TInt networkStatus =
       
   797         reinterpret_cast<TInt>( iStatusQueryInterface.QueryStatusL(
       
   798             EAOManagerStatusQueryNetwork ) );
       
   799 
       
   800     KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::QueryAndHandleAOServerInfoL() Network status: %d", networkStatus );
       
   801 
       
   802     TBool offline =
       
   803         reinterpret_cast<TBool>( iStatusQueryInterface.QueryStatusL(
       
   804             EAOManagerStatusQueryOffline ) );
       
   805 
       
   806     aSuspended = EFalse;
       
   807 
       
   808     if ( offline )
       
   809         {
       
   810         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::QueryAndHandleAOServerInfoL() We are in offline mode. Going into susped");
       
   811         Suspend();
       
   812         aSuspended = ETrue;
       
   813         }
       
   814 
       
   815     if ( !aSuspended &&
       
   816          ( CheckIfAgentHomeOnly() &&
       
   817            networkStatus != ENetworkRegistrationHomeNetwork ) )
       
   818         {
       
   819         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::QueryAndHandleAOServerInfoL() We are not in home network and HomeNetworkOnly is selected. Going into suspend");
       
   820         Suspend();
       
   821         aSuspended = ETrue;
       
   822         }
       
   823     }
       
   824 
       
   825 // ----------------------------------------------------------------------------
       
   826 // CheckAgentHomeNetwork
       
   827 // ----------------------------------------------------------------------------
       
   828 TBool CAlwaysOnlineEmailAgentBase::CheckIfAgentHomeOnly()
       
   829     {
       
   830     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::CheckIfAgentHomeOnly" );
       
   831     if ( AoState() == TImumDaSettings::EValueAutoHomeNetwork ||
       
   832          EmnState() == TImumDaSettings::EValueNotificationsHome )
       
   833         {
       
   834         return ETrue;
       
   835         }
       
   836     return EFalse;
       
   837     }
       
   838 
       
   839 // ----------------------------------------------------------------------------
       
   840 // SwitchAutoUpdateOffL
       
   841 // ----------------------------------------------------------------------------
       
   842 void CAlwaysOnlineEmailAgentBase::SwitchAutoUpdateOffL()
       
   843     {
       
   844     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::SwitchAutoUpdateOffL" );
       
   845     KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::SwitchAutoUpdateOffL() Switching Auto Update OFF!");
       
   846 
       
   847     //first call suspend so all timer operations will be deleted
       
   848     Suspend();
       
   849 
       
   850     if ( IsEmn() )
       
   851         {
       
   852         iMailboxSettings->SetAttr(
       
   853             TImumDaSettings::EKeyAutoNotifications,
       
   854             TImumDaSettings::EValueNotificationsOff );
       
   855         }
       
   856     else
       
   857         {
       
   858         iMailboxSettings->SetAttr(
       
   859             TImumDaSettings::EKeyAutoRetrieval,
       
   860             TImumDaSettings::EValueAutoOff );
       
   861         }
       
   862 
       
   863     iMailboxApi->MailboxServicesL().SaveMailboxSettingsL(
       
   864         *iMailboxSettings );
       
   865 
       
   866 
       
   867     RemoveMe();//completely removes us
       
   868     }
       
   869 
       
   870 
       
   871 // ----------------------------------------------------------------------------
       
   872 // GetConnectionMethodL
       
   873 // ----------------------------------------------------------------------------
       
   874 RCmConnectionMethod CAlwaysOnlineEmailAgentBase::GetConnectionMethodLC()
       
   875     {
       
   876     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::GetIapIdL" );
       
   877     KAOEMAIL_LOGGER_FN1("CAlwaysOnlineEmailAgentBase::GetIapIdL");
       
   878 
       
   879     CImIAPPreferences* apPrefs = CImIAPPreferences::NewLC();
       
   880     CEmailAccounts* accounts = CEmailAccounts::NewLC();
       
   881 
       
   882     // Load account settings according to used protocol
       
   883     if ( iFlags->Flag( EAOBFIsImap4 ) )
       
   884         {
       
   885         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::GetIapIdL(): Load Imap IAP settings");
       
   886         TImapAccount account;
       
   887         accounts->GetImapAccountL( iEntry->Entry().Id(), account );
       
   888         accounts->LoadImapIapSettingsL( account, *apPrefs );
       
   889         }
       
   890     else // POP3
       
   891         {
       
   892         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::GetIapIdL(): Load Pop IAP settings");
       
   893         TPopAccount account;
       
   894         accounts->GetPopAccountL( iEntry->Entry().Id(), account );
       
   895         accounts->LoadPopIapSettingsL( account, *apPrefs );
       
   896         }
       
   897     CleanupStack::PopAndDestroy( accounts ); // accounts
       
   898 
       
   899     // Check ap preferences
       
   900     TImIAPChoice iapChoice = apPrefs->IAPPreference( KMailSettingsIapPreferenceNumber );
       
   901     TInt iapId = iapChoice.iIAP;
       
   902 
       
   903     // if iapId is 0, assume default connection
       
   904     // else the iapId points to the actual iap
       
   905     if( iapId == 0 )
       
   906     	{
       
   907     	// Default Connection is in use
       
   908         TCmDefConnValue defConSetting;
       
   909         iCmManager.ReadDefConnL( defConSetting );
       
   910         if( defConSetting.iType == ECmDefConnAlwaysAsk ||
       
   911         	defConSetting.iType == ECmDefConnAskOnce )
       
   912         	{
       
   913         	// always ask not supported in always online plugin
       
   914         	User::Leave( KErrNotSupported );
       
   915         	}
       
   916         else
       
   917         	{
       
   918         	iapId = defConSetting.iId;
       
   919         	}
       
   920     	}
       
   921 
       
   922     RCmConnectionMethod connMethod = iCmManager.ConnectionMethodL( iapId );
       
   923     CleanupStack::PopAndDestroy( apPrefs ); // apPrefs
       
   924     CleanupClosePushL( connMethod );
       
   925 
       
   926     KAOEMAIL_LOGGER_FN2("CAlwaysOnlineEmailAgentBase::GetIapIdL");
       
   927     return connMethod;
       
   928     }
       
   929 
       
   930 // ----------------------------------------------------------------------------
       
   931 // IsIAPInvalidL
       
   932 // ----------------------------------------------------------------------------
       
   933 TBool CAlwaysOnlineEmailAgentBase::IsIAPInvalidL( TAlwaysOnlineEmailIAPNotes& aInvalidity )
       
   934     {
       
   935     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::IsIAPInvalidL" );
       
   936     TBool retVal = EFalse;
       
   937 
       
   938     // Get the connection method that's used, leaves if no
       
   939     // connection methods found
       
   940     RCmConnectionMethod connectionMethod = GetConnectionMethodLC();
       
   941 
       
   942     // << VARIATED FEATURE START
       
   943     // Check for CSD type
       
   944     // Always online can be activated for CSD only if EAOLFAlwaysOnlineCSD
       
   945     // flag is on
       
   946     TInt bearerType = connectionMethod.GetIntAttributeL( CMManager::ECmBearerType );
       
   947     if ( !iFlags->LF( EAOLFAlwaysOnlineCSD ) )
       
   948     	{
       
   949     	if( bearerType == KCommDbBearerCSD )
       
   950     		{
       
   951     		// IAP is invalid, feature flag is off but bearer type is
       
   952     		// still CSD
       
   953     		CleanupStack::PopAndDestroy(); // connMethod // CSI: 12 # RClass not checked 
       
   954     		aInvalidity = EEmailAgentCSDIAP;
       
   955     		return ETrue;
       
   956     		}
       
   957     	}
       
   958     // CSD VARIATED FEATURE END >>
       
   959 
       
   960     // VPN APs should make the same checks, for example CSD
       
   961     if( bearerType == KPluginVPNBearerTypeUid )
       
   962     	{
       
   963     	TInt homeIAP = connectionMethod.GetIntAttributeL( CMManager::EVpnIapId );
       
   964 
       
   965     	RCmManager connMan;
       
   966     	connMan.OpenLC();
       
   967     	RCmConnectionMethod vpnMethod = connMan.ConnectionMethodL( homeIAP );
       
   968     	CleanupClosePushL( vpnMethod );
       
   969     	TInt vpnBearerType = vpnMethod.GetIntAttributeL( CMManager::ECmBearerType );
       
   970 
       
   971         if ( !iFlags->LF( EAOLFAlwaysOnlineCSD ) )
       
   972         	{
       
   973         	if( vpnBearerType == KCommDbBearerCSD )
       
   974         		{
       
   975         		// IAP is invalid, feature flag is off but the VPN home
       
   976         		// IAP's bearer type is still CSD
       
   977         		CleanupStack::PopAndDestroy( 2 ); // vpnMethod, connectionMethod // CSI: 12,47 # RClass not checked 
       
   978         		aInvalidity = EEmailAgentCSDIAP;
       
   979         		return ETrue;
       
   980         		}
       
   981         	}
       
   982     	CleanupStack::PopAndDestroy(); // vpnMethod // CSI: 12 # RClass not checked 
       
   983     	}
       
   984 
       
   985     CleanupStack::PopAndDestroy(); // connectionMethod // CSI: 12 # RClass not checked 
       
   986     return retVal;
       
   987     }
       
   988 
       
   989 // ----------------------------------------------------------------------------
       
   990 // CAlwaysOnlineEmailAgentBase::IsBearerCSDL()
       
   991 // ----------------------------------------------------------------------------
       
   992 TBool CAlwaysOnlineEmailAgentBase::IsBearerCSDL()
       
   993     {
       
   994     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::IsBearerCSDL" );
       
   995     TBool csdIAP = EFalse;
       
   996 
       
   997     // Get the connection method that's used, leaves if no
       
   998     // connection methods found
       
   999     RCmConnectionMethod connectionMethod = GetConnectionMethodLC();
       
  1000     TInt bearerType = connectionMethod.GetIntAttributeL( CMManager::ECmBearerType );
       
  1001 
       
  1002 	if( bearerType == KCommDbBearerCSD )
       
  1003 		{
       
  1004 		// IAP is invalid, feature flag is off but bearer type is
       
  1005 		// still CSD
       
  1006 		csdIAP = ETrue;
       
  1007 		}
       
  1008 
       
  1009     CleanupStack::PopAndDestroy(); // connectionMethod // CSI: 12 # RClass not checked
       
  1010 
       
  1011     return csdIAP;
       
  1012     }
       
  1013 
       
  1014 
       
  1015 // ----------------------------------------------------------------------------
       
  1016 // CAlwaysOnlineEmailAgentBase::RemoveMe()
       
  1017 // ----------------------------------------------------------------------------
       
  1018 //
       
  1019 void CAlwaysOnlineEmailAgentBase::RemoveMe()
       
  1020     {
       
  1021     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::RemoveMe" );
       
  1022     KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::RemoveMe() EmailAgent signalled to remove us!");
       
  1023     //refresh will see that our setting is "not enabled" and removes us
       
  1024     iEmailAgent.DeleteMailbox( iEntry->Entry().Id() );
       
  1025     }
       
  1026 
       
  1027 // ----------------------------------------------------------------------------
       
  1028 // CAlwaysOnlineEmailAgentBase::CreateSingleOpWatcherLC()
       
  1029 // ----------------------------------------------------------------------------
       
  1030 //
       
  1031 CMsvSingleOpWatcher* CAlwaysOnlineEmailAgentBase::CreateSingleOpWatcherLC()
       
  1032     {
       
  1033     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::CreateSingleOpWatcherLC" );
       
  1034     CMsvSingleOpWatcher* watcher = CMsvSingleOpWatcher::NewL(*this);
       
  1035     CleanupStack::PushL( watcher );
       
  1036     return watcher;
       
  1037     }
       
  1038 
       
  1039 // ----------------------------------------------------------------------------
       
  1040 // CAlwaysOnlineEmailAgentBase::HandleCompletingOperation()
       
  1041 // ----------------------------------------------------------------------------
       
  1042 //
       
  1043 void CAlwaysOnlineEmailAgentBase::HandleCompletingOperation(
       
  1044     const TMsvOp& aOpId,
       
  1045     CMsvOperation& aOp,
       
  1046     const TUid& aUid )
       
  1047     {
       
  1048     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::HandleCompletingOperation" );
       
  1049     TInt error = aOp.iStatus.Int();
       
  1050 
       
  1051     KAOEMAIL_LOGGER_WRITE( "-------------------<COMPLETE: OpInfo>-----------------" );
       
  1052     KAOEMAIL_LOGGER_WRITE_FORMAT( "Completing operation: aOpId: %d", aOpId );
       
  1053     KAOEMAIL_LOGGER_WRITE_FORMAT( "Completing operation: aUid: %d", aUid.iUid );
       
  1054     KAOEMAIL_LOGGER_WRITE_FORMAT( "Completing operation: error: %d", error );
       
  1055     KAOEMAIL_LOGGER_WRITE( "-------------------<COMPLETE: OpInfo>-----------------" );
       
  1056 
       
  1057     // Check if we are using IMAP4
       
  1058     if( error == KErrNone )
       
  1059         {
       
  1060         if ( aUid == KSenduiMtmImap4Uid )
       
  1061             {
       
  1062             TPckgBuf<TImap4CompoundProgress> prgBuf;
       
  1063             TRAP( error, prgBuf.Copy( aOp.ProgressL() ) );
       
  1064 
       
  1065             // Check that we have the descriptor with us
       
  1066             if ( error == KErrNone )
       
  1067                 {
       
  1068                 const TImap4CompoundProgress& opPrg = prgBuf();
       
  1069                 const TImap4GenericProgress& genProg =
       
  1070                 opPrg.iGenericProgress;
       
  1071                 error = genProg.iErrorCode;
       
  1072                 }
       
  1073             }
       
  1074         // Check if we are using POP3
       
  1075         else if( aUid == KSenduiMtmPop3Uid )
       
  1076             {
       
  1077             TPckgBuf<TPop3Progress> paramPack;
       
  1078             TRAP( error, paramPack.Copy( aOp.ProgressL() ) );
       
  1079 
       
  1080             // Check that we have the descriptor with us
       
  1081             if ( error == KErrNone )
       
  1082                 {
       
  1083                 const TPop3Progress& progress = paramPack();
       
  1084                 error = progress.iErrorCode;
       
  1085                 }
       
  1086             }
       
  1087         }
       
  1088 
       
  1089     // Handle operation completion
       
  1090     HandleOpCompleted( aOpId, error );
       
  1091     }
       
  1092 
       
  1093 // ----------------------------------------------------------------------------
       
  1094 // CAlwaysOnlineEmailAgentBase::ConnectIfAllowed()
       
  1095 // ----------------------------------------------------------------------------
       
  1096 //
       
  1097 void CAlwaysOnlineEmailAgentBase::ConnectIfAllowedL( const TMsvOp& aOperation )
       
  1098     {
       
  1099     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::ConnectIfAllowedL" );
       
  1100     KAOEMAIL_LOGGER_FN1("CAlwaysOnlineEmailAgentBase::ConnectIfAllowedL");
       
  1101     if( aOperation == KErrNotFound )
       
  1102         {
       
  1103         if ( !IsEmn() )
       
  1104             {
       
  1105             KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ConnectIfAllowedL(): Not EMN -> Check scheduling");
       
  1106             // Starts schedule timers and sets state accordingly
       
  1107             CheckAndHandleSchedulingL();
       
  1108 
       
  1109             // No start or stop waiters, all times
       
  1110             if( iWaitForStopOpId != KErrNotFound ||
       
  1111                   ( iWaitForStopOpId == KErrNotFound &&
       
  1112                   iWaitForStartOpId == KErrNotFound ) )
       
  1113                 {
       
  1114                 ConnectL();
       
  1115                 }
       
  1116             }
       
  1117         else
       
  1118             {
       
  1119             KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::ConnectIfAllowedL(): EMN -> ConnectL");
       
  1120             // When EMN used, we don't have to care about scheduling,
       
  1121             // just connect
       
  1122             ConnectL();
       
  1123             }
       
  1124         }
       
  1125 
       
  1126     KAOEMAIL_LOGGER_FN2("CAlwaysOnlineEmailAgentBase::ConnectIfAllowedL");
       
  1127     }
       
  1128 
       
  1129 // ----------------------------------------------------------------------------
       
  1130 // CAlwaysOnlineEmailAgentBase::CallNewMessagesL()
       
  1131 // ----------------------------------------------------------------------------
       
  1132 //
       
  1133 void CAlwaysOnlineEmailAgentBase::CallNewMessagesL()
       
  1134     {
       
  1135     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::CallNewMessagesL" );
       
  1136     KAOEMAIL_LOGGER_FN1("CAlwaysOnlineEmailAgentBase::CallNewMessagesL");
       
  1137 
       
  1138     // Create a dummy array. It is not currently used to anything.
       
  1139     CDesCArrayFlat* dummyArray = new (ELeave) CDesCArrayFlat( 1 );
       
  1140     CleanupStack::PushL( dummyArray );
       
  1141 
       
  1142     if ( !iNcnNotification )
       
  1143         {
       
  1144         // If notification haven't been created let's do it now!
       
  1145         TRAPD(error, iNcnNotification =
       
  1146                 MNcnInternalNotification::CreateMNcnInternalNotificationL() );
       
  1147         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::CallNewMessagesL(): NCN notification connection retry");
       
  1148         if ( error != KErrNone )
       
  1149             {
       
  1150             // if construction wasn't fully successful
       
  1151             delete iNcnNotification;
       
  1152             iNcnNotification = NULL;
       
  1153             }
       
  1154         }
       
  1155 
       
  1156     if ( iNcnNotification )
       
  1157         {
       
  1158         TInt result = iNcnNotification->NewMessages(
       
  1159             EMailMessage, iEntry->Entry().Id(), *dummyArray );
       
  1160         KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::CallNewMessagesL(): NewMessages result = %d", result );
       
  1161         }
       
  1162     else
       
  1163         {
       
  1164         // write log if we couldn't create notification
       
  1165         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::CallNewMessagesL(): NewMessages not called!, retry faild");
       
  1166         }
       
  1167 
       
  1168     CleanupStack::PopAndDestroy( dummyArray );
       
  1169     KAOEMAIL_LOGGER_FN2("CAlwaysOnlineEmailAgentBase::CallNewMessagesL");
       
  1170     }
       
  1171 
       
  1172 // ----------------------------------------------------------------------------
       
  1173 // CAlwaysOnlineEmailAgentBase::AlwaysOnlineFlagsL()
       
  1174 // ----------------------------------------------------------------------------
       
  1175 //
       
  1176 CMuiuFlags* CAlwaysOnlineEmailAgentBase::AlwaysOnlineFlagsL()
       
  1177     {
       
  1178     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::AlwaysOnlineFlagsL" );
       
  1179     KAOEMAIL_LOGGER_FN1("CAlwaysOnlineEmailAgentBase::AlwaysOnlineFlagsL()");
       
  1180     TMuiuLocalFeatureArray locals;
       
  1181 
       
  1182     TMuiuGlobalFeatureArray globals;
       
  1183 
       
  1184     // EAOLFAlwaysOnlineCSD
       
  1185     TMuiuLocalFeatureItem temp = {
       
  1186         KCRUidMuiuVariation, KMuiuEmailConfigFlags,
       
  1187         KEmailFeatureIdAlwaysOnlineCSD, ETrue };
       
  1188     locals.Append( temp );
       
  1189 
       
  1190     // EAOLFAlwaysOnlineVPN
       
  1191     temp.iFlag = KEmailFeatureIdEmailVPNAllowed;
       
  1192     locals.Append( temp );
       
  1193 
       
  1194     iFlags = CMuiuFlags::NewL( &globals, &locals );
       
  1195     globals.Reset();
       
  1196     locals.Reset();
       
  1197 
       
  1198     KAOEMAIL_LOGGER_WRITE( "********************* FEATURES *******************" );
       
  1199     KAOEMAIL_LOGGER_WRITE_FORMAT( "CSD support: %d", iFlags->LF( EAOLFAlwaysOnlineCSD ) );
       
  1200 
       
  1201     KAOEMAIL_LOGGER_WRITE_FORMAT( "VPN support: %d", iFlags->LF( EAOLFAlwaysOnlineVPN )  );
       
  1202     KAOEMAIL_LOGGER_WRITE( "********************* FEATURES *******************" );
       
  1203 
       
  1204     KAOEMAIL_LOGGER_FN2("CAlwaysOnlineEmailAgentBase::AlwaysOnlineFlagsL()");
       
  1205     return iFlags;
       
  1206     }
       
  1207 
       
  1208 
       
  1209 // ----------------------------------------------------------------------------
       
  1210 // CAlwaysOnlineEmailAgentBase::AlwaysOnlineDynamicFlags()
       
  1211 // ----------------------------------------------------------------------------
       
  1212 //
       
  1213 // ----------------------------------------------------------------------------
       
  1214 // CAlwaysOnlineEmailAgentBase::CloseServices()
       
  1215 // ----------------------------------------------------------------------------
       
  1216 //
       
  1217 void CAlwaysOnlineEmailAgentBase::CloseServices()
       
  1218 	{
       
  1219 	AOLOG_IN( "CAlwaysOnlineEmailAgentBase::CloseServices" );
       
  1220     iOperations.ResetAndDestroy();
       
  1221 	}
       
  1222 
       
  1223 // ----------------------------------------------------------------------------
       
  1224 // CAlwaysOnlineEmailAgentBase::IsTemporary()
       
  1225 // ----------------------------------------------------------------------------
       
  1226 //
       
  1227 TBool CAlwaysOnlineEmailAgentBase::IsTemporary() const
       
  1228 	{
       
  1229 	AOLOG_IN( "CAlwaysOnlineEmailAgentBase::IsTemporary" );
       
  1230 	KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::IsTemporary: Default EFalse" );
       
  1231     return EFalse;
       
  1232 	}
       
  1233 
       
  1234 
       
  1235 
       
  1236 // ----------------------------------------------------------------------------
       
  1237 // CAlwaysOnlineEmailAgentBase::HandleDefaultError()
       
  1238 // ----------------------------------------------------------------------------
       
  1239 //
       
  1240 void CAlwaysOnlineEmailAgentBase::HandleDefaultError()
       
  1241     {
       
  1242     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::HandleDefaultError" );
       
  1243 
       
  1244     if ( iError == KErrAoServerNotFound )
       
  1245         {
       
  1246         // there have been one connection attempt, incement iRetryCounter
       
  1247         ++iRetryCounter;
       
  1248         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleDefaultError. KErrAoServerNotFound catched" );
       
  1249         // if connection have been successful with current settings keep trying forever
       
  1250         // else ao is shut down immediatelly
       
  1251 
       
  1252         TBool wasSuccess = LoadSettingL<TInt>(
       
  1253             TImumInSettings::EKeyAoUpdateSuccessfulWithCurSettings, EFalse );
       
  1254 
       
  1255         if ( wasSuccess && !IsEmn() )
       
  1256             {
       
  1257             KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleDefaultError. KErrAoServerNotFound, but keep trying" );
       
  1258             iState = EEmailAgentConnectFailed;
       
  1259             }
       
  1260         else
       
  1261             {
       
  1262             KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleDefaultError. KErrAoServerNotFound, ao will go off" );
       
  1263             iState = EEmailAgentFatalError;
       
  1264             iRetryCounter = 0;
       
  1265             }
       
  1266 
       
  1267         }
       
  1268     //try to reconnect only if we were connecting
       
  1269     else if ( iState == EEmailAgentConnecting ||
       
  1270               iState == EEmailAgentPlainConnecting ||
       
  1271               iState == EEmailAgentConnectingToStayOnline )
       
  1272         {
       
  1273         iRetryCounter++;
       
  1274         KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineEmailAgentBase::HandleDefaultError. Default error handling, retry counter: %d .",iRetryCounter );
       
  1275 
       
  1276         // if connection have been tried three times whitout success
       
  1277         if ( (iRetryCounter % KAOMaxRetries)==0 )
       
  1278             {
       
  1279 
       
  1280             // always online should switch off if no successful update in last 15 attempts,
       
  1281             // but if ao have before updated succesfully, then keep trying forever
       
  1282 
       
  1283         TBool wasSuccess = LoadSettingL<TInt>(
       
  1284             TImumInSettings::EKeyAoUpdateSuccessfulWithCurSettings, EFalse );
       
  1285 
       
  1286             if ( iRetryCounter >= KAOMaxRetriesSwitchOff && !wasSuccess )
       
  1287                 {
       
  1288                 //ao will be shutted down immediatelly
       
  1289                 iState = EEmailAgentFatalError;
       
  1290                 iRetryCounter = 0;
       
  1291                 KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleDefaultError. EEailAgentFatalError Ao is goingt to shut down " );
       
  1292 
       
  1293                 }
       
  1294             else
       
  1295                 {
       
  1296                 // keep trying
       
  1297                 iState = EEmailAgentConnectFailed;
       
  1298                 KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleDefaultError. Ao connection failed, but keep trying" );
       
  1299                 }
       
  1300             }
       
  1301         else
       
  1302             {
       
  1303             // reconnect in few seconds
       
  1304             iState = EEmailAgentReconnecting;
       
  1305             KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleDefaultError. State EEmailAgentReconnecting " );
       
  1306             }
       
  1307         }
       
  1308     else
       
  1309         {
       
  1310         //make sure that something is done in case if() didn't catch
       
  1311         iState = EEmailAgentConnTerminated;
       
  1312         KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineEmailAgentBase::HandleDefaultError. If did not catch, setting state: EEmailAgentConnTerminated ");
       
  1313         }
       
  1314     }
       
  1315 
       
  1316 // ----------------------------------------------------------------------------
       
  1317 // CAlwaysOnlineEmailAgentBase::IsReconnectAfterError()
       
  1318 // ----------------------------------------------------------------------------
       
  1319 //
       
  1320 TBool CAlwaysOnlineEmailAgentBase::IsReconnectAfterError()
       
  1321 {
       
  1322     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::IsReconnectAfterError" );
       
  1323     // switch - case set this boolean true if we should disconnect
       
  1324     TBool isReconnect = ETrue;
       
  1325 
       
  1326     //if manually connected or emn is not on, then always reconnect
       
  1327     if ( IsEmn() && !IsTemporary() )
       
  1328         {
       
  1329         switch ( iState )
       
  1330             {
       
  1331             case EEmailAgentQueued:
       
  1332             case EEmailAgentReconnecting:
       
  1333                 // if allready tried KAOMaxRetries time, give up
       
  1334                 isReconnect = iRetryCounter < KAOMaxRetries;
       
  1335                 break;
       
  1336             case EEmailAgentAutoDisconnecting:
       
  1337             case EEmailAgentConnectFailed:
       
  1338             case EEmailAgentUserDisconnecting:
       
  1339             case EEmailAgentConnTerminated:
       
  1340             default:
       
  1341                 isReconnect = EFalse;
       
  1342                 break;
       
  1343             }
       
  1344         }
       
  1345 
       
  1346     return isReconnect;
       
  1347 }
       
  1348 
       
  1349 // ----------------------------------------------------------------------------
       
  1350 // CAlwaysOnlineEmailAgentBase::RetrievalIntervalInMinutes()
       
  1351 // ----------------------------------------------------------------------------
       
  1352 //
       
  1353 TInt CAlwaysOnlineEmailAgentBase::RetrievalIntervalInMinutes( TInt aIntervalIndex )
       
  1354     {
       
  1355     AOLOG_IN( "CAlwaysOnlineEmailAgentBase::RetrievalIntervalInMinutes" );
       
  1356     
       
  1357     switch( aIntervalIndex )
       
  1358         {
       
  1359         case TImumDaSettings::EValue5Minutes:
       
  1360             {
       
  1361             return KAoInterval5Min;
       
  1362             }
       
  1363 
       
  1364         case TImumDaSettings::EValue15Minutes:
       
  1365             {
       
  1366             return KAoInterval15Min;
       
  1367             }
       
  1368         
       
  1369         case TImumDaSettings::EValue30Minutes:
       
  1370             {
       
  1371             return KAoInterval30Min;
       
  1372             }
       
  1373         
       
  1374         case TImumDaSettings::EValue1Hour:
       
  1375             {
       
  1376             return KAoInterval1Hour;
       
  1377             }
       
  1378         
       
  1379         case TImumDaSettings::EValue2Hours:
       
  1380             {
       
  1381             return KAoInterval2Hours;
       
  1382             }
       
  1383         
       
  1384         case TImumDaSettings::EValue4Hours:
       
  1385             {
       
  1386             return KAoInterval4Hours;
       
  1387             }
       
  1388         
       
  1389         case TImumDaSettings::EValue6Hours:
       
  1390             {
       
  1391             return KAoInterval6Hours;
       
  1392             }
       
  1393         }
       
  1394     
       
  1395     // default
       
  1396     return KAoInterval1Hour;
       
  1397     }
       
  1398 
       
  1399 //EOF