messagingappbase/msgerrorwatcher/src/MsgErrorWatcher.cpp
changeset 0 72b543305e3a
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 *     CMsgErrorWatcher implementation file
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <e32base.h>
       
    23 
       
    24 #include <msvapi.h>
       
    25 #include <msvids.h>          //Msv index entry ID's
       
    26 #include <msvuids.h>
       
    27 #include <mmscmds.h>         //EMmsScheduledReceiveForced
       
    28 #include <mmsconst.h>        //Notification folder
       
    29 #include <SenduiMtmUids.h>   //MTM Uids
       
    30 #include <mtclreg.h>         //ClientMtmRegistry
       
    31 #include <watcher.h>
       
    32 #include <mmserrors.h>
       
    33 #include <mmsclient.h>
       
    34 #include <mmssettings.h>
       
    35 #include <MsgErrorWatcherData.rsg>   // resouce identifiers
       
    36 #include <avkon.rsg>            // resouce identifiers
       
    37 #include <data_caging_path_literals.hrh> 
       
    38 
       
    39 #include <avkon.hrh>
       
    40 #include <AknGlobalNote.h>
       
    41 #include <AknPhoneNumberGrouping.h>
       
    42 #include <AknUtils.h>
       
    43 
       
    44 #include <stringresourcereader.h>
       
    45 #include <StringLoader.h>
       
    46 #include <textresolver.h>
       
    47 #include <in_iface.h>            // KErrIfAuthenticationFailure
       
    48 #include <etelpckt.h>            // KErrGprsInsufficientResources, etc.
       
    49 #include <exterror.h>            // KErrGsmMMServiceOptionTemporaryOutOfOrder
       
    50 #include <gsmerror.h>
       
    51 
       
    52 #include <centralrepository.h>    // link against centralrepository.lib
       
    53 #include <messaginginternalcrkeys.h> // for Central Repository keys
       
    54 
       
    55 #include <messagingvariant.hrh>  // Variation
       
    56 
       
    57 #include "MsgErrorWatcher.h"
       
    58 #include "MsgErrorWatcher.hrh"
       
    59 #include "MsgSentItemsObserver.h"
       
    60 #include "MsgErrorCommDbObserver.h"
       
    61 #include "MsgCenRepObserver.h"
       
    62 #include "MsgErrorConnectionObserver.h"
       
    63 #include "MsgErrorDiskSpaceObserver.h"
       
    64 #include "MsgErrorSmsDiskSpaceObserver.h"
       
    65 #include "MsgErrorExtSmsDiskSpaceObserver.h"
       
    66 #include "MsgErrorRoamingObserver.h"
       
    67 #include "MsgErrorGlobalQuery.h"
       
    68 #include "MsgErrorDisconnectDlg.h"
       
    69 #include "MsgErrorStartupObserver.h"
       
    70 #include "MsgLogsObserver.h"
       
    71 #include "MsgGarbageCollection.h"
       
    72 
       
    73 #include "MsgErrorWatcherLogging.h"
       
    74 
       
    75 #include <implementationproxy.h>
       
    76 
       
    77 // LOCAL CONSTANTS AND MACROS
       
    78 _LIT( KMsgErrorWatcherResourceFileName, "msgerrorwatcherdata.rsc" );
       
    79 const TUint KArrayGranularity = 5;
       
    80 const TInt KDelayBetweenNotes = 2000000; //2 seconds
       
    81 const TInt KDelayAfterDisconnect = 3000000; //3 seconds
       
    82 const TInt KConnectionRetries = 3;
       
    83 const TInt KIntMaxLength = 10; //2~32 =~ 4000000000
       
    84 const TUint KInitialDelayBetweenSessionConnectRetries = 5000000; //five seconds
       
    85 const TUint KMaxTimerRetries = 50;
       
    86 //Total delay between first and last retry is
       
    87 //( A * (B^2 + B) ) / 2
       
    88 // - where A is KInitialDelayBetweenSessionConnectRetries
       
    89 // -   and B is KMaxTimerRetries
       
    90 //If A = 5 seconds and B = 50 times last retry is made
       
    91 //after about 106 minutes from the first one.
       
    92 const TMsvId KWatcherInboxFolderId = KMsvGlobalInBoxIndexEntryIdValue;
       
    93 const TMsvId KWatcherOutboxFolderId = KMsvGlobalOutBoxIndexEntryIdValue;
       
    94 const TUid KMessageEntryUid = { KUidMsvMessageEntryValue };
       
    95 // This is more than what we need, but we are cautious
       
    96 const TInt KExtraSpaceForDirectionalityMarkers = 6;
       
    97 // ==================== LOCAL FUNCTIONS ====================
       
    98 
       
    99 
       
   100 const TImplementationProxy ImplementationTable[] = 
       
   101 	{
       
   102     IMPLEMENTATION_PROXY_ENTRY( 0x100059CF, CMsgErrorWatcher::NewL ) //lint !e611
       
   103 	};
       
   104 
       
   105 EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
       
   106 	{
       
   107 	aTableCount = sizeof( ImplementationTable ) / sizeof( TImplementationProxy );
       
   108 	return ImplementationTable;
       
   109 	}
       
   110 
       
   111 // ================= MEMBER FUNCTIONS =======================
       
   112 
       
   113 // ---------------------------------------------------------
       
   114 // CMsgErrorWatcher::CMsgErrorWatcher
       
   115 //
       
   116 // C++ constructor can NOT contain any code, that
       
   117 // might leave.
       
   118 // ---------------------------------------------------------
       
   119 //
       
   120 CMsgErrorWatcher::CMsgErrorWatcher( RFs& aFs )
       
   121     : CActive( EPriorityStandard ),
       
   122     iMmsServiceId( KMsvNullIndexEntryId ),
       
   123     iNotificationFolderId( KMsvNullIndexEntryId ),
       
   124     iCurrentEntryId ( KMsvNullIndexEntryId ),
       
   125     iFs( aFs ) 
       
   126     {
       
   127     CActiveScheduler::Add( this );
       
   128     }
       
   129 
       
   130 // ---------------------------------------------------------
       
   131 // CMsgErrorWatcher::ConstructL
       
   132 //
       
   133 // Symbian OS default constructor can leave.
       
   134 // ---------------------------------------------------------
       
   135 //
       
   136 void CMsgErrorWatcher::ConstructL()
       
   137     {
       
   138 MEWLOGGER_ENTERFN( "ConstructL" );
       
   139     User::LeaveIfError( iTimer.CreateLocal() );
       
   140 
       
   141     TParse fileParse;
       
   142     fileParse.Set( KMsgErrorWatcherResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL );
       
   143     TFileName resource( fileParse.FullName() );
       
   144     iResourceReader = CStringResourceReader::NewL( resource );
       
   145 
       
   146     TInt features = 0;   
       
   147     CRepository* repository = CRepository::NewL( KCRUidMuiuVariation );
       
   148     repository->Get( KMuiuMmsFeatures, features );
       
   149     delete repository;
       
   150     repository = NULL;
       
   151     if ( features & KMmsFeatureIdDelayDisconnectDialog )
       
   152         {
       
   153         iWatcherFlags |= EReceivingDisconnectDelay;
       
   154         }
       
   155 
       
   156     StartWatcherL();
       
   157 MEWLOGGER_LEAVEFN( "ConstructL" );
       
   158     }
       
   159 
       
   160 // ---------------------------------------------------------
       
   161 // CMsgErrorWatcher::NewL
       
   162 //
       
   163 // Two-phased constructor.
       
   164 // ---------------------------------------------------------
       
   165 //
       
   166 CMsgErrorWatcher* CMsgErrorWatcher::NewL( TAny* aWatcherParams )
       
   167     {
       
   168 	TWatcherParams* params = reinterpret_cast<TWatcherParams*>( aWatcherParams );
       
   169     CMsgErrorWatcher* self = new ( ELeave ) CMsgErrorWatcher( params->iFs );
       
   170     
       
   171     CleanupStack::PushL( self );
       
   172     self->ConstructL();
       
   173     CleanupStack::Pop( self );
       
   174 
       
   175     return self;
       
   176     }
       
   177 
       
   178     
       
   179 // ---------------------------------------------------------
       
   180 // CMsgErrorWatcher::~CMsgErrorWatcher
       
   181 //
       
   182 // Destructor
       
   183 // ---------------------------------------------------------
       
   184 //
       
   185 CMsgErrorWatcher::~CMsgErrorWatcher()
       
   186     {
       
   187     StopWatcher();
       
   188     delete iResourceReader;
       
   189     iTimer.Close();
       
   190     }
       
   191 
       
   192 // ---------------------------------------------------------
       
   193 // CMsgErrorWatcher::StartWatcherL
       
   194 //
       
   195 // Does the actual construction of the watcher.
       
   196 // ---------------------------------------------------------
       
   197 //
       
   198 void CMsgErrorWatcher::StartWatcherL()
       
   199     {
       
   200     MEWLOGGER_ENTERFN( "StartWatcherL" );
       
   201     iSession = CMsvSession::OpenSyncL( *this );
       
   202     iMmsReceiveErrorMessages = new ( ELeave ) CMsvEntrySelection;
       
   203     iMmsSendErrorMessages = new ( ELeave ) CMsvEntrySelection;
       
   204     iErrorMessages = new ( ELeave ) CMsvEntrySelection;
       
   205     iErrorMsgNotes = new ( ELeave ) CMsvEntrySelection;
       
   206     iNoteIds = new ( ELeave ) CArrayFixFlat<TInt>( KArrayGranularity );
       
   207 
       
   208     // Get message server session
       
   209     iClientMtmRegistry = CClientMtmRegistry::NewL( *iSession );
       
   210     TRAPD( err,
       
   211         {
       
   212         iMmsClient = static_cast<CMmsClientMtm*>
       
   213             ( iClientMtmRegistry->NewMtmL( KUidMsgTypeMultimedia ) );
       
   214         } );
       
   215     if ( err == KErrNotFound )
       
   216         {
       
   217         MEWLOGGER_WRITE( "MmsClientMtm not found!" );
       
   218         // Make sure iMmsClient is NULL - just in case.
       
   219         delete iMmsClient;
       
   220         iMmsClient = NULL;
       
   221         }
       
   222     else
       
   223         {
       
   224         User::LeaveIfError( err );
       
   225         }
       
   226 
       
   227     if ( iMmsClient )
       
   228         {
       
   229         // We're interested in roaming events only if MMS is enabled.
       
   230         iRoamingObserver = CMsgErrorRoamingObserver::NewL( this ); 
       
   231         }
       
   232     if ( iClientMtmRegistry->IsPresent( KSenduiMtmPushMtmUid ) )
       
   233         {
       
   234         iGarbageCollection = CMsgGarbageCollection::NewL( *iClientMtmRegistry );
       
   235         }
       
   236 
       
   237     iSentItemsObserver = CMsgSentItemsObserver::NewL( this, iSession );
       
   238     iStartupObserver = CMsgErrorStartupObserver::NewL( this );
       
   239     
       
   240     if(!( iWatcherFlags & EWatcherRunning))
       
   241         {
       
   242         //if not yet created
       
   243         iSmsDiskSpaceObserver = CMsgErrorSmsDiskSpaceObserver::NewL( this );
       
   244         iSmsExtDiskSpaceObserver = CMsgErrorExtSmsDiskSpaceObserver::NewL( this );
       
   245         }
       
   246     // If log database is corrupted, logs observer start leaves.
       
   247     // We ignore the leave, we can function otherwise, but we get no log events
       
   248     TRAP_IGNORE( iLogsObserver = CMsgLogsObserver::NewL( this, iFs ) );
       
   249 
       
   250     iWatcherFlags |= EWatcherRunning;
       
   251 
       
   252     if ( GetMmsServiceL() )
       
   253         {
       
   254         CheckMmsReceivingModeL();
       
   255         }
       
   256     
       
   257     InitMessageArraysL();
       
   258     // Startup successful if we got this far. Reset retry counter.
       
   259     iTimerRetries = 0;
       
   260     MEWLOGGER_LEAVEFN( "StartWatcherL" );
       
   261     }
       
   262 
       
   263 // ---------------------------------------------------------
       
   264 // CMsgErrorWatcher::StopWatcher
       
   265 //
       
   266 // Stops (and destructs) the watcher.
       
   267 // ---------------------------------------------------------
       
   268 //
       
   269 void CMsgErrorWatcher::StopWatcher()
       
   270     {
       
   271     MEWLOGGER_ENTERFN( "StopWatcher" );
       
   272     iWatcherFlags &= ~EWatcherRunning;
       
   273     iWatcherFlags &= ~ENoAPErrorPending;
       
   274     iMmsServiceId = KMsvNullIndexEntryId;
       
   275     iNotificationFolderId = KMsvNullIndexEntryId;
       
   276 
       
   277     Cancel();
       
   278     delete iGarbageCollection;
       
   279     iGarbageCollection = NULL;
       
   280     delete iLogsObserver;
       
   281     iLogsObserver = NULL;
       
   282     delete iCommDbObserver;
       
   283     iCommDbObserver = NULL;
       
   284     delete iCenRepObserver;
       
   285     iCenRepObserver = NULL;
       
   286     delete iConnectionObserver;
       
   287     iConnectionObserver = NULL;
       
   288     delete iDiskSpaceObserver;
       
   289     iDiskSpaceObserver = NULL;
       
   290     delete iSmsDiskSpaceObserver;
       
   291     iSmsDiskSpaceObserver = NULL;
       
   292     delete iSmsExtDiskSpaceObserver;
       
   293     iSmsExtDiskSpaceObserver = NULL;    
       
   294     delete iRoamingObserver;
       
   295     iRoamingObserver = NULL;
       
   296     delete iMmsClient;
       
   297     iMmsClient = NULL;
       
   298     delete iClientMtmRegistry;
       
   299     iClientMtmRegistry = NULL;
       
   300     delete iOperation;
       
   301     iOperation = NULL;
       
   302     delete iSentItemsObserver;
       
   303     iSentItemsObserver = NULL;
       
   304     delete iStartupObserver;
       
   305     iStartupObserver = NULL;
       
   306     delete iSession;
       
   307     iSession = NULL;
       
   308     delete iMmsReceiveErrorMessages;
       
   309     iMmsReceiveErrorMessages = NULL;
       
   310     delete iMmsSendErrorMessages;
       
   311     iMmsSendErrorMessages = NULL;
       
   312     delete iNoteIds;
       
   313     iNoteIds = NULL;
       
   314 
       
   315     delete iErrorMsgText;
       
   316     iErrorMsgText = NULL;
       
   317     delete iErrorMsgDetails;
       
   318     iErrorMsgDetails = NULL;
       
   319     delete iErrorQuery;
       
   320     iErrorQuery = NULL;
       
   321     delete iDisconnectQuery;
       
   322     iDisconnectQuery = NULL;
       
   323     delete iDisconnectDlg;
       
   324     iDisconnectDlg = NULL;
       
   325     delete iErrorMsgNotes;
       
   326     iErrorMsgNotes = NULL;
       
   327 
       
   328     delete iErrorMessages;
       
   329     iErrorMessages = NULL;
       
   330     
       
   331     MEWLOGGER_LEAVEFN( "StopWatcher" );
       
   332     }
       
   333 
       
   334 // ---------------------------------------------------------
       
   335 // CMsgErrorWatcher::StartRestartTimer
       
   336 //
       
   337 // Start session reconnect timer.
       
   338 // ---------------------------------------------------------
       
   339 //
       
   340 void CMsgErrorWatcher::StartRestartTimer()
       
   341     {
       
   342     if ( !IsActive() ) 
       
   343         {
       
   344     MEWLOGGER_WRITE( "Starting timer" );
       
   345         iStatus = KRequestPending;
       
   346         iRequestType = EMsgRequestStartingUp;
       
   347         iTimerRetries++;
       
   348         //The interval between retries comes longer every time
       
   349         iTimer.After( iStatus,
       
   350             iTimerRetries * KInitialDelayBetweenSessionConnectRetries );
       
   351         SetActive();
       
   352         }
       
   353     }
       
   354 
       
   355 // ---------------------------------------------------------
       
   356 // CMsgErrorWatcher::InitMessageArraysL
       
   357 //
       
   358 // Initialise arrays
       
   359 // ---------------------------------------------------------
       
   360 //
       
   361 void CMsgErrorWatcher::InitMessageArraysL()
       
   362     {
       
   363     MEWLOGGER_ENTERFN( "InitMessageArraysL" );
       
   364     CMsvEntry* outbox = iSession->GetEntryL( KWatcherOutboxFolderId );
       
   365     CleanupStack::PushL( outbox );
       
   366     CMsvEntrySelection* outboxMessages =
       
   367         outbox->ChildrenWithTypeL( KMessageEntryUid );
       
   368     CleanupStack::PushL( outboxMessages );
       
   369     TInt count = outboxMessages->Count();
       
   370     while ( count-- )
       
   371         {
       
   372         TMsvId dummy;
       
   373         TMsvEntry entry;
       
   374         TInt error = iSession->GetEntry(
       
   375             outboxMessages->At( count ), dummy, entry );
       
   376 
       
   377         TUid mtm = entry.iMtm;
       
   378         if ( !error &&
       
   379             ( mtm == KSenduiMtmSmsUid ||
       
   380             mtm == KSenduiMtmMmsUid  ||
       
   381             mtm == KSenduiMtmSmtpUid ||
       
   382             mtm == KUidMsgMMSNotification ) )
       
   383             {
       
   384             iErrorMessages->AppendL( entry.Id() );
       
   385             MEWLOGGER_ENTERFN( "Send msg added" );
       
   386             }
       
   387         }
       
   388     CleanupStack::PopAndDestroy( outboxMessages );  
       
   389     CleanupStack::PopAndDestroy( outbox );
       
   390     }
       
   391 
       
   392 // ---------------------------------------------------------
       
   393 // CMsgErrorWatcher::ResetWatcher
       
   394 //
       
   395 // Resets watcher.
       
   396 // ---------------------------------------------------------
       
   397 //
       
   398 void CMsgErrorWatcher::ResetWatcher()
       
   399     {
       
   400     MEWLOGGER_ENTERFN( "ResetWatcher" );
       
   401 
       
   402     iWatcherFlags &= ~ENoAPErrorPending;
       
   403     
       
   404     //Drop all observers
       
   405     delete iCommDbObserver;
       
   406     iCommDbObserver = NULL;
       
   407     delete iCenRepObserver;
       
   408     iCenRepObserver = NULL;
       
   409     delete iConnectionObserver;
       
   410     iConnectionObserver = NULL;
       
   411     delete iDiskSpaceObserver;
       
   412     iDiskSpaceObserver = NULL;
       
   413 	delete iSmsDiskSpaceObserver;
       
   414     iSmsDiskSpaceObserver = NULL;
       
   415     delete iSmsExtDiskSpaceObserver;
       
   416     iSmsExtDiskSpaceObserver = NULL;    
       
   417     //Reset disk space errors
       
   418     iDiskSpaceErrors = 0;
       
   419     }
       
   420 
       
   421 // ---------------------------------------------------------
       
   422 // CMsgErrorWatcher::GetMmsServiceL
       
   423 //
       
   424 // Retrieves MMS service id from MsgStore
       
   425 // ---------------------------------------------------------
       
   426 //
       
   427 TBool CMsgErrorWatcher::GetMmsServiceL()
       
   428     {
       
   429     if ( !iMmsClient )
       
   430         {
       
   431         return EFalse;
       
   432         }
       
   433     if ( iMmsServiceId == KMsvNullIndexEntryId )
       
   434         {
       
   435         MEWLOGGER_WRITE( "Looking for MMS service" );
       
   436         iMmsClient->RestoreSettingsL();
       
   437         iMmsServiceId = iMmsClient->MmsSettings().Service();
       
   438         iNotificationFolderId = iMmsClient->MmsSettings().NotificationFolder();
       
   439         iMaxReceiveSize = iMmsClient->MmsSettings().MaximumReceiveSize();
       
   440         }
       
   441     return ( iMmsServiceId != KMsvNullIndexEntryId );
       
   442     }
       
   443 
       
   444 // ---------------------------------------------------------
       
   445 // CMsgErrorWatcher::StartMmsFetchL
       
   446 //
       
   447 // Initiates MMS fetch
       
   448 // ---------------------------------------------------------
       
   449 //
       
   450 void CMsgErrorWatcher::StartMmsFetchL()
       
   451     {
       
   452     MEWLOGGER_ENTERFN( "StartMmsFetchL" );
       
   453     if ( !IsActive() && iMmsReceiveErrorMessages->Count() )
       
   454         {
       
   455         MEWLOGGER_WRITEF( _L("Fetching %d message(s)"),
       
   456             iMmsReceiveErrorMessages->Count() );
       
   457         CancelNotesL();
       
   458         TCommandParameters parameters; // initialized to zero
       
   459         TCommandParametersBuf paramPack( parameters );
       
   460 
       
   461         //Add service entry as the first entry in the array
       
   462         iMmsReceiveErrorMessages->InsertL( 0, iMmsServiceId );
       
   463 
       
   464         // First remove existing schedules:
       
   465         MEWLOGGER_WRITE( "Deleting old schedules" );
       
   466         // Calling synchronous TransferCommandL method
       
   467         const TInt KBufSize = 256;
       
   468         TBuf8<KBufSize> dummy;
       
   469         iSession->TransferCommandL( *iMmsReceiveErrorMessages,
       
   470             EMmsDeleteSchedule,
       
   471             paramPack,
       
   472             dummy );
       
   473         MEWLOGGER_WRITE( "Old schedules deleted!" );
       
   474 
       
   475         // Then reschedule:
       
   476         iStatus = KRequestPending;
       
   477         iRequestType = EMsgRequestFetching;
       
   478         delete iOperation;
       
   479         iOperation = NULL;
       
   480         MEWLOGGER_WRITE( "Request fetch" );
       
   481         iOperation = iSession->TransferCommandL( *iMmsReceiveErrorMessages,
       
   482             EMmsScheduledReceive,
       
   483             paramPack,
       
   484             iStatus );
       
   485         SetActive();
       
   486         MEWLOGGER_WRITE( "Reset array" );
       
   487         iMmsReceiveErrorMessages->Reset();
       
   488         }
       
   489     }
       
   490 
       
   491 // ---------------------------------------------------------
       
   492 // CMsgErrorWatcher::StartMmsSendL
       
   493 //
       
   494 // Initiates MMS fetch
       
   495 // ---------------------------------------------------------
       
   496 //
       
   497 void CMsgErrorWatcher::StartMmsSendL()
       
   498     {
       
   499     MEWLOGGER_ENTERFN( "StartMmsSendL" );
       
   500     if ( !IsActive() && iMmsSendErrorMessages->Count() )
       
   501         {
       
   502         MEWLOGGER_WRITEF( _L("Sending %d message(s)"),
       
   503             iMmsSendErrorMessages->Count() );
       
   504         CancelNotesL();
       
   505         TCommandParameters parameters; // initialized to zero
       
   506         TCommandParametersBuf paramPack( parameters );
       
   507 
       
   508         //Add service entry as the first entry in the array
       
   509         iMmsSendErrorMessages->InsertL( 0, iMmsServiceId );
       
   510 
       
   511         iStatus = KRequestPending;
       
   512         iRequestType = EMsgRequestSending;
       
   513         delete iOperation;
       
   514         iOperation = NULL;
       
   515         MEWLOGGER_WRITE( "Request send" );
       
   516         iOperation = iSession->TransferCommandL( *iMmsSendErrorMessages,
       
   517             EMmsScheduledSend,
       
   518             paramPack,
       
   519             iStatus );
       
   520         SetActive();
       
   521         MEWLOGGER_WRITE( "Reset array" );
       
   522         iMmsSendErrorMessages->Reset();
       
   523         }
       
   524     }
       
   525 
       
   526 // ---------------------------------------------------------
       
   527 // CMsgErrorWatcher::CheckMmsReceivingModeL
       
   528 //
       
   529 // Checks MMS receiving mode
       
   530 // ---------------------------------------------------------
       
   531 //
       
   532 void CMsgErrorWatcher::CheckMmsReceivingModeL()
       
   533     {
       
   534     if ( !( iWatcherFlags & EStartupReady ) || !GetMmsServiceL() )
       
   535         {
       
   536         return;
       
   537         }
       
   538     TBool validAP = ValidateMmsServiceL(); //Refreshes MMS settings
       
   539     MEWLOGGER_WRITEF( _L("ReceivingModeHome: %d"), iMmsClient->MmsSettings().ReceivingModeHome() );
       
   540     MEWLOGGER_WRITEF( _L("ReceivingModeForeign: %d"), iMmsClient->MmsSettings().ReceivingModeForeign() );
       
   541 
       
   542     TInt fetchHome = iMmsClient->MmsSettings().ReceivingModeHome();
       
   543     TInt fetchRoam = iMmsClient->MmsSettings().ReceivingModeForeign();
       
   544 
       
   545     if ( validAP &&
       
   546         fetchRoam == EMmsReceivingReject &&
       
   547         fetchHome != EMmsReceivingReject )
       
   548         {
       
   549         MEWLOGGER_WRITE( "CheckMmsReceivingModeL, ShowNote flag enabled" );
       
   550         iWatcherFlags |= EShowRoamingNote;
       
   551         }
       
   552     else
       
   553         {
       
   554         //Reset roaming note flag
       
   555         MEWLOGGER_WRITE( "CheckMmsReceivingModeL, ShowNote flag disabled" );
       
   556         iWatcherFlags &= ~EShowRoamingNote;
       
   557         iWatcherFlags &= ~ERoamingNoteShown;
       
   558         }
       
   559     }
       
   560 
       
   561 // ---------------------------------------------------------
       
   562 // CMsgErrorWatcher::ValidateMmsServiceL
       
   563 //
       
   564 // Validates MMS service
       
   565 // ---------------------------------------------------------
       
   566 //
       
   567 TBool CMsgErrorWatcher::ValidateMmsServiceL()
       
   568     {
       
   569     if ( !GetMmsServiceL() )
       
   570         {
       
   571         return EFalse;
       
   572         }
       
   573     iMmsClient->RestoreSettingsL(); //Refreshes MMS settings
       
   574     MEWLOGGER_WRITEF( _L("ValidateService: %d"), iMmsClient->ValidateService( iMmsServiceId ) );
       
   575 
       
   576     TInt errorCode = iMmsClient->ValidateService( iMmsServiceId );
       
   577     
       
   578     //TODO: check if the following is needed at all.
       
   579     //Is ENoAPErrorPending needed and is it att all
       
   580     //possible to go into there?
       
   581     if ( iWatcherFlags & ENoAPErrorPending &&
       
   582         ( errorCode == KMmsErrorNoURI1 ||
       
   583           errorCode == KMmsErrorAP1Invalid ) )
       
   584         {
       
   585         iWatcherFlags &= ~ENoAPErrorPending;
       
   586         ShowGlobalNoteL( EInvalidAccessPointNote );
       
   587         }
       
   588     return ( errorCode == KErrNone );
       
   589     }
       
   590 
       
   591 // ---------------------------------------------------------
       
   592 // CMsgErrorWatcher::ShowGlobalNoteL
       
   593 //
       
   594 // Shows AVKON global note
       
   595 // ---------------------------------------------------------
       
   596 //
       
   597 void CMsgErrorWatcher::ShowGlobalNoteL( TMsgErrorNoteIds aNoteId )
       
   598     {
       
   599     if ( !( iWatcherFlags & EStartupReady ) )
       
   600         {
       
   601         return;
       
   602         }
       
   603     MEWLOGGER_WRITEF( _L("ShowGlobalNoteL, id: %d"), aNoteId );
       
   604 
       
   605     TPtrC string;
       
   606     HBufC* text = NULL;
       
   607     TAknGlobalNoteType noteType = EAknGlobalErrorNote;
       
   608     TInt softkeys = R_AVKON_SOFTKEYS_OK_EMPTY;
       
   609 
       
   610     switch ( aNoteId )
       
   611         {
       
   612         case ENoAccesPointsNote:
       
   613             {
       
   614             string.Set( iResourceReader->ReadResourceString( R_MSG_ERRH_NO_AP ) );
       
   615             }
       
   616             break;
       
   617         case EInvalidAccessPointNote:
       
   618             {
       
   619             string.Set( iResourceReader->ReadResourceString( R_MSG_ERRH_INVALID_AP ) );            
       
   620             }
       
   621             break;
       
   622         case EDiskLowNote1:
       
   623             {
       
   624             string.Set( iResourceReader->ReadResourceString( R_MSG_ERRH_DISK_LOW_1 ) );           
       
   625             }
       
   626             break;
       
   627         case EDiskLowNoteN:
       
   628             {
       
   629             string.Set( iResourceReader->ReadResourceString( R_MSG_ERRH_DISK_LOW_N ) );          
       
   630             text = HBufC::NewLC( string.Length() + KIntMaxLength );
       
   631             TPtr tempPtr = text->Des();
       
   632             StringLoader::Format( tempPtr, string, -1, iDiskSpaceErrors );
       
   633             }
       
   634             break;
       
   635         case ESMSIncomingLowDiskSpace:
       
   636             {
       
   637             string.Set( iResourceReader->ReadResourceString( R_MEMLO_MEMORY_LOW_MESSAGES ) );    
       
   638             }
       
   639             break;
       
   640         case EMemoryLowNote:
       
   641             {
       
   642             string.Set( iResourceReader->ReadResourceString( R_MSG_ERRH_MEMORY_LOW ) );          
       
   643             }
       
   644             break;
       
   645         case ERoamingNote:
       
   646             {
       
   647             string.Set( iResourceReader->ReadResourceString( R_MSG_ERRH_ROAMING_REMINDER ) );            
       
   648             noteType = EAknGlobalConfirmationNote;
       
   649             }
       
   650             break;
       
   651         case ESendingMessageNote:
       
   652             {
       
   653             string.Set( iResourceReader->ReadResourceString( R_MSG_ERRH_SENDING_MESSAGE ) );           
       
   654             noteType = EAknGlobalInformationNote;
       
   655             softkeys = 0;
       
   656             break;
       
   657             }
       
   658         default:
       
   659             //Show nothing... 
       
   660             return;
       
   661         }
       
   662     if ( !text )
       
   663         {
       
   664         text = string.AllocLC();
       
   665         }
       
   666 
       
   667     CAknGlobalNote* note = CAknGlobalNote::NewLC();
       
   668     if ( softkeys )
       
   669         {
       
   670         // If softkeys are set the global note will be "waiting".
       
   671         // If softkeys are NOT set the global note will be "non-waiting".
       
   672         note->SetSoftkeys( softkeys );
       
   673         }
       
   674     TInt id = note->ShowNoteL( noteType, *text );
       
   675     CleanupStack::PopAndDestroy( note  );
       
   676     CleanupStack::PopAndDestroy( text );
       
   677 
       
   678     iNoteIds->AppendL( id );
       
   679     }
       
   680 
       
   681 // ---------------------------------------------------------
       
   682 // CMsgErrorWatcher::CancelNotesL
       
   683 //
       
   684 // Cancels all AVKON global notes. 
       
   685 // ---------------------------------------------------------
       
   686 //
       
   687 void CMsgErrorWatcher::CancelNotesL()
       
   688     {
       
   689     TInt count = iNoteIds->Count();
       
   690     if ( count )
       
   691         {
       
   692         CAknGlobalNote* note = CAknGlobalNote::NewLC();
       
   693         while ( count-- )
       
   694             {
       
   695             //Does nothing if note is already dismissed.
       
   696             note->CancelNoteL( iNoteIds->At( count ) );
       
   697             }
       
   698         CleanupStack::PopAndDestroy( note ); // note
       
   699         iNoteIds->Reset();
       
   700         }
       
   701     }
       
   702 
       
   703 // ---------------------------------------------------------
       
   704 // CMsgErrorWatcher::ShowErrorMessageQueryL
       
   705 //
       
   706 // Shows AVKON global query
       
   707 // ---------------------------------------------------------
       
   708 //
       
   709 void CMsgErrorWatcher::ShowErrorMessageQueryL()
       
   710     {
       
   711     MEWLOGGER_ENTERFN( "ShowErrorMessageQueryL" );
       
   712     delete iErrorQuery;
       
   713     iErrorQuery = NULL;
       
   714 
       
   715     TMsvEntry entry;
       
   716     if ( GetNextErrorMsg( entry ) == KErrNone )
       
   717         {
       
   718         ResolveErrorTextL( entry );
       
   719         ResolveErrorDetailsL( entry );
       
   720         TInt softkeys = ( iErrorMsgDetails != 0 ) ?
       
   721             R_AVKON_SOFTKEYS_OK_DETAILS : 
       
   722             R_AVKON_SOFTKEYS_OK_EMPTY;
       
   723     
       
   724         MEWLOGGER_ENTERFN( "Displaying global query" );
       
   725         iErrorQuery = CMsgErrorGlobalQuery::NewL( this );
       
   726         iErrorQuery->ShowQueryL(
       
   727             *iErrorMsgText,
       
   728             softkeys,
       
   729             ESendFailureNote );
       
   730         }
       
   731     }
       
   732 
       
   733 // ---------------------------------------------------------
       
   734 // CMsgErrorWatcher::GetNextErrorMsg
       
   735 // ---------------------------------------------------------
       
   736 //
       
   737 TInt CMsgErrorWatcher::GetNextErrorMsg( TMsvEntry& aEntry )
       
   738     {
       
   739     if ( iErrorMsgNotes->Count() &&
       
   740         iWatcherFlags & EStartupReady )
       
   741         {
       
   742         TMsvId dummy;
       
   743         TInt error = iSession->GetEntry( iErrorMsgNotes->At( 0 ), dummy, aEntry );
       
   744         iErrorMsgNotes->Delete( 0 );
       
   745         return error;
       
   746         }
       
   747     else
       
   748         {
       
   749         return KErrNotFound;
       
   750         }
       
   751     }
       
   752 
       
   753 // ---------------------------------------------------------
       
   754 // CMsgErrorWatcher::ResolveErrorTextL
       
   755 // ---------------------------------------------------------
       
   756 //
       
   757 void CMsgErrorWatcher::ResolveErrorTextL( TMsvEntry& aEntry )
       
   758     {
       
   759     MEWLOGGER_ENTERFN( "ResolveErrorTextL" );
       
   760     delete iErrorMsgText;
       
   761     iErrorMsgText = NULL;
       
   762 
       
   763     HBufC* info = NULL;
       
   764     if ( aEntry.iDetails.Length() )
       
   765         {
       
   766         // Sender or recipient info
       
   767         info = CAknPhoneNumberGrouping::CreateGroupedPhoneNumberL( aEntry.iDetails ); 
       
   768         CleanupStack::PushL( info ); 
       
   769         }
       
   770     
       
   771     TPtrC string;
       
   772     if ( aEntry.iMtm == KUidMsgMMSNotification )
       
   773         {
       
   774         if ( aEntry.Parent() == KWatcherInboxFolderId )
       
   775             {
       
   776             MEWLOGGER_ENTERFN( "Retrieval failure." );
       
   777             string.Set( iResourceReader->ReadResourceString( info
       
   778                 ? R_MSG_ERRH_RETRIEVAL_ERROR_INFO
       
   779                 : R_MSG_ERRH_RETRIEVAL_ERROR ) );
       
   780             }
       
   781         else
       
   782             {
       
   783             MEWLOGGER_ENTERFN( "Forward failure." );
       
   784             string.Set( iResourceReader->ReadResourceString( info
       
   785                 ? R_MSG_ERRH_FORWARD_ERROR_INFO
       
   786                 : R_MSG_ERRH_FORWARD_ERROR ) );
       
   787             }
       
   788         }
       
   789     else
       
   790         {
       
   791         MEWLOGGER_ENTERFN( "Send failure." );
       
   792         string.Set( iResourceReader->ReadResourceString( info
       
   793             ? R_MSG_ERRH_SEND_ERROR_INFO
       
   794             : R_MSG_ERRH_SEND_ERROR ) );
       
   795         }
       
   796 
       
   797     if ( info )
       
   798         {
       
   799         iErrorMsgText = HBufC::NewL( string.Length() + info->Length() ); 
       
   800         TPtr tempPtr = iErrorMsgText->Des(); 
       
   801 
       
   802         StringLoader::Format( tempPtr, string, -1, *info ); 
       
   803         CleanupStack::PopAndDestroy( info );
       
   804         }
       
   805     else
       
   806         {
       
   807         iErrorMsgText = string.AllocL();
       
   808         }
       
   809     MEWLOGGER_LEAVEFN( "ResolveErrorTextL" );
       
   810     }
       
   811 
       
   812 // ---------------------------------------------------------
       
   813 // CMsgErrorWatcher::ResolveErrorDetailsL
       
   814 // ---------------------------------------------------------
       
   815 //
       
   816 void CMsgErrorWatcher::ResolveErrorDetailsL( TMsvEntry& aEntry )
       
   817     {
       
   818     MEWLOGGER_ENTERFN( "ResolveErrorDetailsL" );
       
   819     delete iErrorMsgDetails;
       
   820     iErrorMsgDetails = NULL;
       
   821 
       
   822     TBool useResolver = EFalse;
       
   823     TInt errorId = aEntry.iError;
       
   824 
       
   825     if ( iMmsClient &&
       
   826         ( aEntry.iMtm == KSenduiMtmMmsUid || aEntry.iMtm == KUidMsgMMSNotification ) )
       
   827         {
       
   828         switch ( errorId )
       
   829             {
       
   830             case KMmsErrorStatusMessageAddressUnresolved:
       
   831             case KMmsErrorStatusTransientAddressUnresolved:
       
   832             case KMmsErrorStatusMessageNotFound:
       
   833             case KMmsErrorStatusTransientMessageNotFound:
       
   834             case KMmsErrorStatusNetworkProblem:
       
   835             case KMmsErrorStatusServiceDenied:
       
   836             case KMmsErrorStatusMessageFormatCorrupt:
       
   837             case KMmsErrorStatusContentNotAccepted:
       
   838             case KMmsErrorStatusReplyChargingLimitationsNotMet:
       
   839             case KMmsErrorStatusReplyChargingRequestNotAccepted:
       
   840             case KMmsErrorStatusReplyChargingForwardingDenied:
       
   841             case KMmsErrorStatusReplyChargingNotSupported:
       
   842             case KMmsErrorStatusTransientFailure:
       
   843             case KMmsErrorStatusUnspecified:
       
   844             case KMmsErrorStatusPermanentFailure:
       
   845             case KMmsErrorStatusUnsupportedMessage:
       
   846                 {
       
   847                 //See whether MMSC has delivered some
       
   848                 //response text and use it if found.
       
   849                 //Else use normal text resolver.
       
   850                 iMmsClient->SwitchCurrentEntryL( aEntry.Id() );
       
   851                 iMmsClient->LoadMessageL();
       
   852                 TPtrC responseText = iMmsClient->ResponseText();
       
   853                 if ( responseText.Length() )
       
   854                     {
       
   855                     MEWLOGGER_WRITEF( _L("Response text found: %d"), errorId );
       
   856                     iErrorMsgDetails = responseText.AllocL();
       
   857                     useResolver = EFalse;
       
   858                     }
       
   859                 else
       
   860                     {
       
   861                     useResolver = ETrue;
       
   862                     }
       
   863                 }
       
   864                 break;
       
   865             case KErrCouldNotConnect:
       
   866                 errorId = KMmsErrorCouldNotConnect;
       
   867                 //lint -fallthrough
       
   868             default:
       
   869                 useResolver = ETrue;
       
   870                 break;
       
   871             }
       
   872         }
       
   873     else if ( aEntry.iMtm == KSenduiMtmSmsUid )
       
   874         {
       
   875         useResolver = ETrue;
       
   876         }
       
   877     else
       
   878         {
       
   879         useResolver = EFalse;
       
   880         }
       
   881 
       
   882     if ( useResolver )
       
   883         {
       
   884         TInt textId;
       
   885         TUint textFlags;
       
   886         MEWLOGGER_WRITEF( _L("Resolving error: %d"), errorId );
       
   887         CTextResolver* resolver = CTextResolver::NewLC();
       
   888         const TDesC& error = resolver->ResolveErrorString( errorId, textId, textFlags );
       
   889        
       
   890         if ( !( textFlags & EErrorResBlankErrorFlag ||
       
   891             textFlags & ETextResolverUnknownErrorFlag ) )
       
   892             {
       
   893             iErrorMsgDetails = error.AllocL();
       
   894             }
       
   895         CleanupStack::PopAndDestroy( resolver ); 
       
   896         }
       
   897     MEWLOGGER_LEAVEFN( "ResolveErrorDetailsL" );
       
   898     }
       
   899 
       
   900 // ---------------------------------------------------------
       
   901 // CMsgErrorWatcher::HandleNoAPErrorL
       
   902 //
       
   903 // Handles "no access point defined" error
       
   904 // ---------------------------------------------------------
       
   905 //
       
   906 void CMsgErrorWatcher::HandleNoAPErrorL( TMsvEntry& aEntry )
       
   907     { 
       
   908     MEWLOGGER_ENTERFN( "HandleNoAPErrorL" );
       
   909     iMmsReceiveErrorMessages->AppendL( aEntry.Id() );
       
   910 
       
   911     iWatcherFlags |= ENoAPErrorPending;
       
   912 
       
   913     ShowGlobalNoteL( ENoAccesPointsNote );
       
   914     if ( !iCenRepObserver )
       
   915         {
       
   916         MEWLOGGER_WRITE( "HandleNoAPErrorL, Creating CenRep observer" );
       
   917         iCenRepObserver = CMsgCenRepObserver::NewL( this );
       
   918         iCenRepObserver->SubscribeNotification();
       
   919         }
       
   920     //Let's reset the TMsvEntry::iError to get rig of excess warning note
       
   921     ResetErrorFieldL( aEntry );
       
   922     }
       
   923 
       
   924 // ---------------------------------------------------------
       
   925 // CMsgErrorWatcher::HandleInvalidAPErrorL
       
   926 //
       
   927 // Handles "invalid access point" error
       
   928 // ---------------------------------------------------------
       
   929 //
       
   930 void CMsgErrorWatcher::HandleInvalidAPErrorL( TMsvEntry& aEntry, TBool aStartObserver )
       
   931     {
       
   932     MEWLOGGER_ENTERFN( "HandleInvalidAPErrorL" );
       
   933     iMmsReceiveErrorMessages->AppendL( aEntry.Id() );
       
   934     ShowGlobalNoteL( EInvalidAccessPointNote );
       
   935     if ( aStartObserver && !iCommDbObserver )
       
   936         {
       
   937         MEWLOGGER_WRITE( "HandleInvalidAPErrorL, Creating CommDB observer" );
       
   938         iCommDbObserver = CMsgErrorCommDbObserver::NewL( this );
       
   939         }
       
   940     if ( aStartObserver && !iCenRepObserver )
       
   941         {
       
   942         //We must also start cenrep observer
       
   943         MEWLOGGER_WRITE( "HandleInvalidAPErrorL, Creating CenRep observer" );
       
   944         iCenRepObserver = CMsgCenRepObserver::NewL( this );
       
   945         iCenRepObserver->SubscribeNotification();
       
   946         }    
       
   947     
       
   948     //Let's reset the TMsvEntry::iError to get rig of excess warning note
       
   949     ResetErrorFieldL( aEntry ); 
       
   950     }
       
   951 
       
   952 // ---------------------------------------------------------
       
   953 // CMsgErrorWatcher::HandleConnectionErrorL
       
   954 //
       
   955 // Handles "connection reserved" error
       
   956 // ---------------------------------------------------------
       
   957 //
       
   958 void CMsgErrorWatcher::HandleConnectionErrorL( TMsvEntry& aEntry, TBool aReceive )
       
   959     {
       
   960     MEWLOGGER_ENTERFN( "HandleConnectionErrorL" );
       
   961     if ( !iConnectionObserver )
       
   962         {
       
   963         MEWLOGGER_WRITE( "HandleConnectionErrorL, Creating connection observer" );
       
   964         iConnectionObserver = CMsgErrorConnectionObserver::NewL( this );
       
   965         }
       
   966     if ( iConnectionObserver->ConnectionsOpen() )
       
   967         {
       
   968         MEWLOGGER_WRITE( "HandleConnectionErrorL, Open connections detected" );
       
   969         if ( aReceive )
       
   970             {
       
   971             iMmsReceiveErrorMessages->AppendL( aEntry.Id() );
       
   972             }
       
   973         else
       
   974             {
       
   975             iMmsSendErrorMessages->AppendL( aEntry.Id() );
       
   976             }
       
   977         //No matter if already started
       
   978         iConnectionObserver->StartL();
       
   979 
       
   980         delete iDisconnectQuery;
       
   981         iDisconnectQuery = NULL;
       
   982     
       
   983         MEWLOGGER_ENTERFN( "Reading disconnect error text" );
       
   984         TPtrC string( iResourceReader->ReadResourceString( aReceive
       
   985             ? R_MSG_ERRH_CONN_IN_USE_RECEIVE
       
   986             : R_MSG_ERRH_CONN_IN_USE_SEND ) );
       
   987 
       
   988         MEWLOGGER_ENTERFN( "Displaying global query" );
       
   989         iDisconnectQuery = CMsgErrorGlobalQuery::NewL( this );
       
   990         iDisconnectQuery->ShowQueryL(
       
   991             string,
       
   992             R_AVKON_SOFTKEYS_YES_NO,
       
   993             EConnectionInUseNote );
       
   994         }
       
   995     else
       
   996         {
       
   997         MEWLOGGER_WRITE( "HandleConnectionErrorL, No open connections" );
       
   998         delete iConnectionObserver;
       
   999         iConnectionObserver = NULL;
       
  1000         }
       
  1001     }
       
  1002 
       
  1003 // ---------------------------------------------------------
       
  1004 // CMsgErrorWatcher::HandleDiskSpaceErrorL
       
  1005 //
       
  1006 // Handles "no disk space" error
       
  1007 // ---------------------------------------------------------
       
  1008 //
       
  1009 void CMsgErrorWatcher::HandleDiskSpaceErrorL( TMsvEntry& aEntry )
       
  1010     {
       
  1011     MEWLOGGER_ENTERFN( "HandleDiskSpaceErrorL" );
       
  1012     iMmsReceiveErrorMessages->AppendL( aEntry.Id() );
       
  1013 
       
  1014     iDiskSpaceErrors++;
       
  1015     if ( iDiskSpaceErrors == 1 )
       
  1016         {
       
  1017         ShowGlobalNoteL( EDiskLowNote1 );
       
  1018         }
       
  1019     else
       
  1020         {
       
  1021         ShowGlobalNoteL( EDiskLowNoteN );
       
  1022         }
       
  1023     TUint triggerLevel = Max( KDefaultTriggerLevel, iMaxReceiveSize );
       
  1024     //Activate DiskSpace observer
       
  1025     if ( !iDiskSpaceObserver )
       
  1026         {
       
  1027         MEWLOGGER_WRITE( "HandleDiskSpaceErrorL, Creating disk space observer" );
       
  1028         iDiskSpaceObserver = CMsgErrorDiskSpaceObserver::NewL( this, *iSession, iFs );
       
  1029         }
       
  1030     MEWLOGGER_WRITEF( _L("Limit set to: %d"),
       
  1031         KCriticalLevel + triggerLevel + KTriggerMargin );
       
  1032     iDiskSpaceObserver->SetLimitAndActivateL( KCriticalLevel +
       
  1033         triggerLevel +
       
  1034         KTriggerMargin );
       
  1035     }
       
  1036 
       
  1037 // ---------------------------------------------------------
       
  1038 // CMsgErrorWatcher::HandleMemoryErrorL
       
  1039 //
       
  1040 // Handles "no memory" error
       
  1041 // ---------------------------------------------------------
       
  1042 //
       
  1043 void CMsgErrorWatcher::HandleMemoryErrorL( TMsvEntry& aEntry )
       
  1044     {
       
  1045     MEWLOGGER_ENTERFN( "HandleMemoryErrorL" );
       
  1046     iMmsReceiveErrorMessages->AppendL( aEntry.Id() );
       
  1047     ShowGlobalNoteL( EMemoryLowNote );
       
  1048     }
       
  1049 
       
  1050 // ---------------------------------------------------------
       
  1051 // CMsgErrorWatcher::HandleRoamingEventL
       
  1052 //
       
  1053 // Handles events from roaming observer
       
  1054 // ---------------------------------------------------------
       
  1055 //
       
  1056 void CMsgErrorWatcher::HandleRoamingEventL( TBool aRoaming )
       
  1057     {
       
  1058     MEWLOGGER_ENTERFN( "HandleRoamingEventL" );
       
  1059     if ( !iMmsClient )
       
  1060         {
       
  1061         // We should never get here if MMS Client MTM is not present
       
  1062         // since roaming observer is not started in that case.
       
  1063         // This return is here just in case...
       
  1064         return;
       
  1065         }
       
  1066 
       
  1067     TInt fetchHome = iMmsClient->MmsSettings().ReceivingModeHome();
       
  1068     TInt fetchRoam = iMmsClient->MmsSettings().ReceivingModeForeign();
       
  1069     TBool fetchAll = EFalse;
       
  1070 
       
  1071     if ( aRoaming )
       
  1072         {
       
  1073         //We are in roaming network
       
  1074         if ( fetchRoam == EMmsReceivingAutomatic &&
       
  1075             fetchHome != EMmsReceivingAutomatic )
       
  1076             {
       
  1077             fetchAll = ETrue;
       
  1078             }
       
  1079         if ( ( iWatcherFlags & EShowRoamingNote ) &&
       
  1080             !( iWatcherFlags & ERoamingNoteShown ) )
       
  1081             {
       
  1082             //Show roaming note if requested
       
  1083             ShowGlobalNoteL( ERoamingNote );
       
  1084             iWatcherFlags |= ERoamingNoteShown;
       
  1085             }
       
  1086         }
       
  1087     else
       
  1088         {
       
  1089         //We are in home network
       
  1090         if ( fetchHome == EMmsReceivingAutomatic &&
       
  1091             fetchRoam != EMmsReceivingAutomatic )
       
  1092             {
       
  1093             fetchAll = ETrue;
       
  1094             }
       
  1095         //Reset roaming note flag
       
  1096         iWatcherFlags &= ~ERoamingNoteShown;
       
  1097         }
       
  1098 
       
  1099     if ( fetchAll && !IsActive() )
       
  1100         {
       
  1101         MEWLOGGER_WRITE( "HandleRoamingEventL, starting fetch all" );
       
  1102         iStatus = KRequestPending;
       
  1103         iRequestType = EMsgRequestFetchingAll;
       
  1104         delete iOperation;
       
  1105         iOperation = NULL;
       
  1106         iOperation = iMmsClient->FetchAllL( iStatus, EFalse );
       
  1107         SetActive();
       
  1108         }
       
  1109     }
       
  1110 
       
  1111 // ---------------------------------------------------------
       
  1112 // CMsgErrorWatcher::HandleCommDbEventL
       
  1113 //
       
  1114 // Handles events from CommDB observer
       
  1115 // ---------------------------------------------------------
       
  1116 //
       
  1117 void CMsgErrorWatcher::HandleCommDbEventL()
       
  1118     {
       
  1119     if ( ValidateMmsServiceL() )
       
  1120         {
       
  1121         MEWLOGGER_WRITE( "HandleCommDbEventL, starting fetch" );
       
  1122         StartMmsFetchL();
       
  1123         }
       
  1124     else
       
  1125         {
       
  1126         //Wait for another event
       
  1127         MEWLOGGER_WRITE( "HandleCommDbEventL, restart CommDB observer" );
       
  1128         iCommDbObserver->Restart();
       
  1129         }
       
  1130     }
       
  1131 
       
  1132 // ---------------------------------------------------------
       
  1133 // CMsgErrorWatcher::HandleConnectionEvent
       
  1134 //
       
  1135 // Handles events from connection observer
       
  1136 // ---------------------------------------------------------
       
  1137 //
       
  1138 void CMsgErrorWatcher::HandleConnectionEvent()
       
  1139     {
       
  1140     if ( !IsActive() )
       
  1141         {
       
  1142         MEWLOGGER_WRITE( "HandleConnectionEvent, Starting delay timer" );
       
  1143         iStatus = KRequestPending;
       
  1144         iRequestType = EMsgRequestWaitingDisconnection;
       
  1145         iTimer.After( iStatus, KDelayAfterDisconnect );
       
  1146         SetActive();
       
  1147         }
       
  1148     }
       
  1149 
       
  1150 // ---------------------------------------------------------
       
  1151 // CMsgErrorWatcher::HandleDiskSpaceEventL
       
  1152 //
       
  1153 // Handles events from disk space observer
       
  1154 // ---------------------------------------------------------
       
  1155 //
       
  1156 void CMsgErrorWatcher::HandleDiskSpaceEventL()
       
  1157     {
       
  1158     MEWLOGGER_WRITE( "HandleDiskSpaceEventL, starting fetch" );
       
  1159     StartMmsFetchL();
       
  1160     }
       
  1161 
       
  1162 
       
  1163 // ---------------------------------------------------------
       
  1164 // CMsgErrorWatcher::HandleDiskSpaceEvent2L
       
  1165 //
       
  1166 // Handles events from disk space observer
       
  1167 // -------k--------------------------------------------------
       
  1168 //
       
  1169 void CMsgErrorWatcher::HandleDiskSpaceEvent2L()
       
  1170     {
       
  1171     MEWLOGGER_WRITE( "HandleDiskSpaceEvent2L, show note" );
       
  1172     ShowGlobalNoteL( ESMSIncomingLowDiskSpace );
       
  1173     
       
  1174     }
       
  1175 // ---------------------------------------------------------
       
  1176 // CMsgErrorWatcher::HandleGlobalQueryEventL
       
  1177 //
       
  1178 // Handles events from global query observer
       
  1179 // ---------------------------------------------------------
       
  1180 //
       
  1181 void CMsgErrorWatcher::HandleGlobalQueryEventL( TInt aQueryId, TInt aStatus )
       
  1182     {
       
  1183     switch ( aQueryId )
       
  1184         {
       
  1185         case ESendFailureNote:
       
  1186             {
       
  1187             if ( aStatus == EAknSoftkeyDetails && iErrorMsgDetails )
       
  1188                 {
       
  1189                 CAknGlobalNote* note = CAknGlobalNote::NewLC();
       
  1190                 note->SetSoftkeys( R_AVKON_SOFTKEYS_OK_EMPTY );
       
  1191                 TInt id = note->ShowNoteL( EAknGlobalInformationNote,
       
  1192                     *iErrorMsgDetails );
       
  1193                 CleanupStack::PopAndDestroy( note ); 
       
  1194                 iNoteIds->AppendL( id );
       
  1195                 }
       
  1196             if ( iErrorMsgNotes->Count() && !IsActive() )
       
  1197                 {
       
  1198                 iStatus = KRequestPending;
       
  1199                 iRequestType = EMsgRequestWaitingErrorNote;
       
  1200                 if ( !IsActive() ) 
       
  1201                     {
       
  1202                     iTimer.After( iStatus, KDelayBetweenNotes );
       
  1203                     SetActive();
       
  1204                     }
       
  1205                 // Don't delete error query yet. If iErrorQuery
       
  1206                 // exists other error notes are queued instead
       
  1207                 // of shown.
       
  1208                 }
       
  1209             else
       
  1210                 {
       
  1211                 delete iErrorQuery;
       
  1212                 iErrorQuery = NULL;
       
  1213                 }
       
  1214             }
       
  1215             break;
       
  1216         case EConnectionInUseNote:
       
  1217             {
       
  1218         MEWLOGGER_WRITEF( _L("ConnectionInUseNote return status: %d"), aStatus );
       
  1219             if ( aStatus == EAknSoftkeyYes ||
       
  1220                 aStatus == EAknSoftkeyOk )
       
  1221                 {
       
  1222                 delete iDisconnectDlg;
       
  1223                 iDisconnectDlg = NULL;
       
  1224                 MEWLOGGER_WRITE( "HandleGlobalQueryEventL, Starting disconnect dialog" );
       
  1225                 iDisconnectDlg = CMsgErrorDisconnectDlg::NewL();
       
  1226                 iDisconnectDlg->Start();
       
  1227                 }
       
  1228             delete iDisconnectQuery;
       
  1229             iDisconnectQuery = NULL;
       
  1230             }
       
  1231             break;
       
  1232         default:
       
  1233             break;
       
  1234         }
       
  1235     }
       
  1236 
       
  1237 // ---------------------------------------------------------
       
  1238 // CMsgErrorWatcher::HandleStartupReadyL
       
  1239 //
       
  1240 // Handles events from startup state observer (currently 
       
  1241 // CMsgSentItemsObserver)
       
  1242 // ---------------------------------------------------------
       
  1243 //
       
  1244 void CMsgErrorWatcher::HandleStartupReadyL()
       
  1245     {
       
  1246     MEWLOGGER_WRITE( "Startup ready!" );
       
  1247     iWatcherFlags |= EStartupReady;
       
  1248     CheckMmsReceivingModeL();
       
  1249     }
       
  1250 
       
  1251 
       
  1252 // ---------------------------------------------------------
       
  1253 // CMsgErrorWatcher::HandleCenRepNotificationL
       
  1254 //
       
  1255 // Handles events from Central Repository observer
       
  1256 // ---------------------------------------------------------
       
  1257 //
       
  1258 void CMsgErrorWatcher::HandleCenRepNotificationL()
       
  1259     {
       
  1260     if ( ValidateMmsServiceL() )
       
  1261         {
       
  1262         MEWLOGGER_WRITE( "HandleCenRepNotificationL, starting fetch" );
       
  1263         StartMmsFetchL();
       
  1264         }
       
  1265     else
       
  1266         {
       
  1267         //Wait for another event
       
  1268         MEWLOGGER_WRITE( "HandleCenRepNotificationL, restart CenRep observer" );
       
  1269         iCenRepObserver->SubscribeNotification();
       
  1270         }
       
  1271     }
       
  1272 
       
  1273 
       
  1274 // ---------------------------------------------------------
       
  1275 // CMsgErrorWatcher::ShowDeliveredNote
       
  1276 //
       
  1277 // Handles events from Logs observer
       
  1278 // ---------------------------------------------------------
       
  1279 //
       
  1280 void CMsgErrorWatcher::ShowDeliveredNoteL( const TDesC& aRemoteParty )
       
  1281 	{
       
  1282 	ShowReadOrDeliveredNoteL( aRemoteParty, R_MMS_DELIVERED );
       
  1283 	}
       
  1284 
       
  1285 
       
  1286 // ---------------------------------------------------------
       
  1287 // CMsgErrorWatcher::ShowReadNoteL
       
  1288 //
       
  1289 // Handles events from Logs observer
       
  1290 // ---------------------------------------------------------
       
  1291 //
       
  1292 void CMsgErrorWatcher::ShowReadNoteL( const TDesC& aRemoteParty )
       
  1293 	{
       
  1294 	ShowReadOrDeliveredNoteL( aRemoteParty, R_MMS_READ );
       
  1295 	}
       
  1296 
       
  1297 // ---------------------------------------------------------
       
  1298 // CMsgErrorWatcher::ShowReadNoteL
       
  1299 //
       
  1300 // Handles events from Logs observer
       
  1301 // ---------------------------------------------------------
       
  1302 //
       
  1303 void CMsgErrorWatcher::ShowReadOrDeliveredNoteL( const TDesC& aRemoteParty, TInt aResourceId )
       
  1304 	{
       
  1305     TPtrC original;
       
  1306     original.Set( iResourceReader->ReadResourceString( aResourceId ) );
       
  1307     
       
  1308     HBufC* wholeTextBuf = HBufC::NewLC( original.Length() + aRemoteParty.Length() 
       
  1309         + KExtraSpaceForDirectionalityMarkers  );
       
  1310             
       
  1311     TPtr wholeText = wholeTextBuf->Des();
       
  1312     StringLoader::Format ( wholeText, original, -1, aRemoteParty );
       
  1313     AknTextUtils::LanguageSpecificNumberConversion( wholeText );
       
  1314     CAknGlobalNote* note = CAknGlobalNote::NewLC();
       
  1315     note->ShowNoteL( EAknGlobalInformationNote, wholeText );
       
  1316     CleanupStack::PopAndDestroy( note );
       
  1317     CleanupStack::PopAndDestroy( wholeTextBuf );
       
  1318 	}
       
  1319 
       
  1320 
       
  1321 // ---------------------------------------------------------
       
  1322 // CMsgErrorWatcher::HandleSessionEventL
       
  1323 //
       
  1324 // Handles events from MsgServer observer
       
  1325 // ---------------------------------------------------------
       
  1326 //
       
  1327 void CMsgErrorWatcher::HandleSessionEventL( TMsvSessionEvent aEvent,
       
  1328                                            TAny* aArg1,
       
  1329                                            TAny* aArg2,
       
  1330                                            TAny* aArg3 )
       
  1331     {
       
  1332 #ifdef USE_LOGGER
       
  1333     if ( aEvent == EMsvServerReady )
       
  1334         {
       
  1335         MEWLOGGER_WRITE( "Message Server Ready event." );
       
  1336         }
       
  1337 #endif
       
  1338     if ( ( aEvent == EMsvCloseSession ||
       
  1339         aEvent == EMsvServerTerminated ||
       
  1340         aEvent == EMsvMediaUnavailable ||
       
  1341         aEvent == EMsvMediaChanged ) &&
       
  1342         iWatcherFlags & EWatcherRunning )
       
  1343         {
       
  1344         MEWLOGGER_WRITEF( _L("StopWatcher event: %d"), aEvent );
       
  1345         StopWatcher();
       
  1346         //Start retry timer
       
  1347         StartRestartTimer();
       
  1348         return;
       
  1349         }
       
  1350     if ( aEvent == EMsvServerReady &&
       
  1351         !( iWatcherFlags & EWatcherRunning ) )
       
  1352         {
       
  1353         TRAPD ( err, StartWatcherL() );
       
  1354         if ( err ) //make sure watcher is not left in obscure state
       
  1355             {
       
  1356             StopWatcher();
       
  1357             }
       
  1358         return;
       
  1359         }
       
  1360     if ( aArg1 == 0 || aArg2 == 0 || !( iWatcherFlags & EWatcherRunning ) )
       
  1361         {
       
  1362         return;
       
  1363         }
       
  1364     // If for some reason MMS service is not yet found,
       
  1365     // we try to find it now...
       
  1366     GetMmsServiceL();
       
  1367 
       
  1368     CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>( aArg1 );
       
  1369     TInt count = entries->Count();
       
  1370     
       
  1371     // Mark the _original_ folder as parent for "entries moved" events (in "aArg3").
       
  1372     // For other events the parent is in "aArg2".
       
  1373     TMsvId parentId = ( aEvent == EMsvEntriesMoved )
       
  1374         ? *( static_cast<TMsvId*>( aArg3 ) )
       
  1375         : *( static_cast<TMsvId*>( aArg2 ) );
       
  1376     
       
  1377     
       
  1378     if ( count < 1 )
       
  1379         {
       
  1380         return;
       
  1381         }
       
  1382     if ( parentId == KMsvRootIndexEntryIdValue &&
       
  1383         iMmsServiceId != KMsvNullIndexEntryId )
       
  1384         {
       
  1385         // We're not interested in these events if MMS Service is not present.
       
  1386         HandleRootEventL( aEvent, entries );
       
  1387         }
       
  1388     else if ( parentId == KMsvLocalServiceIndexEntryIdValue )
       
  1389         {
       
  1390         HandleLocalServiceEventL( aEvent, entries );
       
  1391         }
       
  1392     else if ( parentId == KWatcherInboxFolderId )
       
  1393         {
       
  1394         HandleInboxEventL( aEvent, entries );
       
  1395         }
       
  1396     else if ( parentId == KWatcherOutboxFolderId )
       
  1397         {
       
  1398         HandleOutboxEventL( aEvent, entries );
       
  1399         }
       
  1400     else if ( ( iMmsServiceId != KMsvNullIndexEntryId && parentId == iMmsServiceId ) ||
       
  1401         ( iNotificationFolderId != KMsvNullIndexEntryId && parentId == iNotificationFolderId ) )
       
  1402         {
       
  1403         HandleMmsServiceEventL( aEvent, entries );
       
  1404         }
       
  1405     else
       
  1406         {
       
  1407         //do nothing
       
  1408         }    
       
  1409     }
       
  1410 
       
  1411 // ---------------------------------------------------------
       
  1412 // CMsgErrorWatcher::HandleRootEventL
       
  1413 //
       
  1414 // Handles root events from MsgServer observer
       
  1415 // ---------------------------------------------------------
       
  1416 //
       
  1417 void CMsgErrorWatcher::HandleRootEventL( TMsvSessionEvent aEvent,
       
  1418                                         CMsvEntrySelection* aEntries )
       
  1419     {
       
  1420     switch ( aEvent )
       
  1421         {
       
  1422         case EMsvEntriesChanged:
       
  1423             {
       
  1424             TInt count = aEntries->Count();
       
  1425             TInt i = 0;
       
  1426             while ( i < count )
       
  1427                 {
       
  1428                 TMsvId dummy;
       
  1429                 TMsvEntry entry;
       
  1430                 TInt error = iSession->GetEntry(
       
  1431                     aEntries->At( i ), dummy, entry );
       
  1432 
       
  1433                 //We're only interested in MMS service
       
  1434                 if ( !error && 
       
  1435                     iMmsServiceId != KMsvNullIndexEntryId &&
       
  1436                     entry.Id() == iMmsServiceId )
       
  1437                     {
       
  1438                     MEWLOGGER_WRITE( "HandleSessionEventL, MMS service changed" );
       
  1439                     //Check whether the roaming setting has changed
       
  1440                     CheckMmsReceivingModeL();
       
  1441 
       
  1442                     //We're waiting for the the user to change access points
       
  1443                     //if iCommDbObserver exists
       
  1444                     if ( iCommDbObserver && ValidateMmsServiceL() )
       
  1445                         {
       
  1446                         MEWLOGGER_WRITE( "HandleSessionEventL, deleting CommDB observer" );
       
  1447                         StartMmsFetchL();
       
  1448                         }
       
  1449                     }
       
  1450                 i++;
       
  1451                 }
       
  1452             break;
       
  1453             }
       
  1454         default:
       
  1455             break;
       
  1456         }
       
  1457     }
       
  1458 
       
  1459 // ---------------------------------------------------------
       
  1460 // CMsgErrorWatcher::HandleLocalServiceEventL
       
  1461 //
       
  1462 // Handles local service events from MsgServer observer
       
  1463 // ---------------------------------------------------------
       
  1464 //
       
  1465 void CMsgErrorWatcher::HandleLocalServiceEventL( TMsvSessionEvent aEvent,
       
  1466                                                 CMsvEntrySelection* aEntries )
       
  1467     {
       
  1468     if ( iNotificationFolderId == KMsvNullIndexEntryId &&
       
  1469         aEvent == EMsvEntriesCreated )
       
  1470         {
       
  1471         TInt count = aEntries->Count();
       
  1472         TInt i = 0;
       
  1473         while ( i < count )
       
  1474             {
       
  1475             TMsvId dummy;
       
  1476             TMsvEntry entry;
       
  1477             TInt error = iSession->GetEntry(
       
  1478                 aEntries->At( i ), dummy, entry );
       
  1479             if ( !error &&
       
  1480                 entry.iDetails.Compare( KMMSNotificationFolder ) == 0 )
       
  1481                 {
       
  1482                 iNotificationFolderId = aEntries->At( i );
       
  1483                 MEWLOGGER_WRITEF( _L("Notification folder created: %d"), iNotificationFolderId );
       
  1484                 }
       
  1485             i++;
       
  1486             }
       
  1487         }
       
  1488     }
       
  1489 
       
  1490 // ---------------------------------------------------------
       
  1491 // CMsgErrorWatcher::HandleInboxEventL
       
  1492 //
       
  1493 // Handles outbox events from MsgServer observer
       
  1494 // ---------------------------------------------------------
       
  1495 //
       
  1496 void CMsgErrorWatcher::HandleInboxEventL( TMsvSessionEvent aEvent,
       
  1497                                          CMsvEntrySelection* aEntries )
       
  1498     {
       
  1499     switch (aEvent)
       
  1500         {
       
  1501         case EMsvEntriesChanged:
       
  1502             {
       
  1503             TInt count = aEntries->Count();
       
  1504             TInt i = 0;
       
  1505             while ( i < count )
       
  1506                 {
       
  1507                 TMsvId dummy;
       
  1508                 TMsvEntry entry;
       
  1509                 TInt error = iSession->GetEntry(
       
  1510                     aEntries->At( i ), dummy, entry );
       
  1511                 TUid mtm = entry.iMtm;
       
  1512                 //We're only interested in MMS notifications
       
  1513                 if ( !error && 
       
  1514                     ( mtm == KUidMsgMMSNotification ) &&
       
  1515                     entry.iType == KMessageEntryUid )
       
  1516                     {
       
  1517                     TUint sendingState = entry.SendingState();
       
  1518                     MEWLOGGER_WRITEF( _L("Sendstate: %d"), sendingState );
       
  1519                     MEWLOGGER_WRITEF( _L("Failed: %d"), (TInt)entry.Failed() );
       
  1520                     MEWLOGGER_WRITEF( _L("Error: %d"), entry.iError );
       
  1521                     TInt selectionId = iErrorMessages->Find( entry.Id() );
       
  1522 
       
  1523                     if ( sendingState == KMsvSendStateFailed &&
       
  1524                         selectionId == KErrNotFound )
       
  1525                         {
       
  1526                         MEWLOGGER_WRITE( "Send msg added" );
       
  1527                         iErrorMessages->AppendL( entry.Id() );
       
  1528                         iErrorMsgNotes->AppendL( entry.Id() );
       
  1529                         if ( !iErrorQuery )
       
  1530                             {
       
  1531                             ShowErrorMessageQueryL();
       
  1532                             }
       
  1533                         }
       
  1534                     else if ( sendingState != KMsvSendStateFailed &&
       
  1535                         selectionId != KErrNotFound )
       
  1536                         {
       
  1537                         MEWLOGGER_WRITE( "Send msg removed" );
       
  1538                         iErrorMessages->Delete( selectionId );
       
  1539                         }
       
  1540                     else
       
  1541                         {
       
  1542                         //Do nothing
       
  1543                         }
       
  1544                     }
       
  1545                 i++;
       
  1546                 }
       
  1547             break;
       
  1548             }
       
  1549         default:
       
  1550             break;
       
  1551         }
       
  1552     }
       
  1553 
       
  1554 // ---------------------------------------------------------
       
  1555 // CMsgErrorWatcher::HandleOutboxEventL
       
  1556 //
       
  1557 // Handles outbox events from MsgServer observer
       
  1558 // ---------------------------------------------------------
       
  1559 //
       
  1560 void CMsgErrorWatcher::HandleOutboxEventL( TMsvSessionEvent aEvent,
       
  1561                                           CMsvEntrySelection* aEntries )
       
  1562     {
       
  1563     TInt count = aEntries->Count();
       
  1564     switch (aEvent)
       
  1565         {
       
  1566         case EMsvEntriesChanged:
       
  1567             {
       
  1568             TInt i = 0;
       
  1569             while ( i < count )
       
  1570                 {
       
  1571                 TMsvId dummy;
       
  1572                 TMsvEntry entry;
       
  1573                 TInt error = iSession->GetEntry(
       
  1574                     aEntries->At( i ), dummy, entry );
       
  1575                 TUid mtm = entry.iMtm;
       
  1576 
       
  1577                 if ( mtm == KSenduiMtmMmsUid &&
       
  1578                     iMmsSendErrorMessages->Find( entry.Id() ) == KErrNotFound )
       
  1579                     {
       
  1580                     if ( // the first error is activated again to synchronize
       
  1581                         // with connection manager (MPM) 
       
  1582                         entry.iError == KErrPacketDataTsyMaxPdpContextsReached ||
       
  1583                         entry.iError == KErrUmtsMaxNumOfContextExceededByPhone ||
       
  1584                         entry.iError == KErrUmtsMaxNumOfContextExceededByNetwork ||
       
  1585                         // add the following error to the list to synchronize with 
       
  1586                         // connection manager (MPM)
       
  1587                         entry.iError == KErrGprsInsufficientResources )
       
  1588                         {
       
  1589                         MEWLOGGER_WRITE( "MMS send - connection active" );
       
  1590                         
       
  1591                         //Let's now save the id. This way we can reset the entrys
       
  1592                         //error field just before the fetch start. This prevents
       
  1593                         //duplicate error notes because this case branch is reached many times.
       
  1594                         iCurrentEntryId = entry.Id();
       
  1595                         
       
  1596                         HandleConnectionErrorL( entry, EFalse );
       
  1597                         }
       
  1598                     }
       
  1599 
       
  1600                 //We're only interested in Mail, SMS & MMS messages
       
  1601                 if ( !error && 
       
  1602                     ( mtm == KSenduiMtmSmsUid ||
       
  1603                     mtm == KSenduiMtmMmsUid  ||
       
  1604                     mtm == KSenduiMtmSmtpUid ||
       
  1605                     mtm == KUidMsgMMSNotification ) &&
       
  1606                     entry.iType == KMessageEntryUid )
       
  1607                     {
       
  1608                     TUint sendingState = entry.SendingState();
       
  1609                     MEWLOGGER_WRITEF( _L("Sendstate: %d"), sendingState );
       
  1610                     MEWLOGGER_WRITEF( _L("Failed: %d"), (TInt)entry.Failed() );
       
  1611                     MEWLOGGER_WRITEF( _L("Error: %d"), entry.iError );
       
  1612                     if ( mtm == KSenduiMtmSmtpUid && entry.Failed() )
       
  1613                         {
       
  1614                         // special Failed flag handling for e-mail
       
  1615                         sendingState = KMsvSendStateFailed;
       
  1616                         }
       
  1617                     TInt selectionId = iErrorMessages->Find( entry.Id() );
       
  1618 
       
  1619                     if ( sendingState == KMsvSendStateFailed &&
       
  1620                         selectionId == KErrNotFound )
       
  1621                         {
       
  1622                         MEWLOGGER_WRITE( "Send msg added" );
       
  1623                         iErrorMessages->AppendL( entry.Id() );
       
  1624                         iErrorMsgNotes->AppendL( entry.Id() );
       
  1625                         if ( !iErrorQuery )
       
  1626                             {
       
  1627                             ShowErrorMessageQueryL();
       
  1628                             }
       
  1629                         }
       
  1630                     else if ( sendingState != KMsvSendStateFailed &&
       
  1631                         selectionId != KErrNotFound )
       
  1632                         {
       
  1633                         MEWLOGGER_WRITE( "Send msg removed" );
       
  1634                         iErrorMessages->Delete( selectionId );
       
  1635                         }
       
  1636                     else
       
  1637                         {
       
  1638                         
       
  1639                         }    
       
  1640                     }
       
  1641                 i++;
       
  1642                 }
       
  1643             }
       
  1644             break;
       
  1645         case EMsvEntriesMoved: // Messages are moved _from_ this folder.
       
  1646         case EMsvEntriesDeleted:
       
  1647             {
       
  1648             TInt i = 0;
       
  1649             MEWLOGGER_WRITEF( _L("Entries deleted: %d"), count );
       
  1650             while ( i < count )
       
  1651                 {
       
  1652                 TInt selectionId = iMmsSendErrorMessages->Find( aEntries->At( i ) );
       
  1653                 if ( selectionId != KErrNotFound )
       
  1654                     {
       
  1655                     MEWLOGGER_WRITE( "MMS Send msg removed" );
       
  1656                     iMmsSendErrorMessages->Delete( selectionId );
       
  1657                     }
       
  1658                 i++;
       
  1659                 }
       
  1660             }
       
  1661             break;
       
  1662         default:
       
  1663             break;
       
  1664         }
       
  1665     }
       
  1666 
       
  1667 // ---------------------------------------------------------
       
  1668 // CMsgErrorWatcher::HandleMmsServiceEventL
       
  1669 //
       
  1670 // Handles MMS service events from MsgServer observer
       
  1671 // ---------------------------------------------------------
       
  1672 //
       
  1673 void CMsgErrorWatcher::HandleMmsServiceEventL( TMsvSessionEvent aEvent,
       
  1674                                               CMsvEntrySelection* aEntries )
       
  1675     {
       
  1676     TInt count = aEntries->Count();
       
  1677     switch (aEvent)
       
  1678         {
       
  1679         case EMsvEntriesChanged:
       
  1680             {
       
  1681             TInt i = 0;
       
  1682             while ( i < count )
       
  1683                 {
       
  1684                 TMsvId dummy;
       
  1685                 TMsvEntry entry;
       
  1686                 TInt error = iSession->GetEntry(
       
  1687                     aEntries->At( i ), dummy, entry );
       
  1688 #ifdef USE_LOGGER
       
  1689                 if ( !error )
       
  1690                     {
       
  1691                     MEWLOGGER_WRITEF( _L("FetchState: %d"), entry.SendingState() );
       
  1692                     MEWLOGGER_WRITEF( _L("Error: %d"), entry.iError );
       
  1693                     MEWLOGGER_WRITEF( _L("Retries: %d"), entry.iMtmData3 );
       
  1694                     MEWLOGGER_WRITEF( _L("Failed: %d"), (TInt)entry.Failed() );
       
  1695                     MEWLOGGER_WRITEF( _L("ArrayId: %d"), iMmsReceiveErrorMessages->Find( entry.Id() ) );
       
  1696                     }
       
  1697 #endif
       
  1698                 //Check that reception has failed and that the entry is not
       
  1699                 //already in iMmsReceiveErrorMessages
       
  1700                 if ( !error &&
       
  1701                     iMmsReceiveErrorMessages->Find( entry.Id() ) == KErrNotFound )
       
  1702                     {
       
  1703                     TInt entryErr = entry.iError;
       
  1704                     if ( entryErr == KErrGprsMissingorUnknownAPN )
       
  1705                         {
       
  1706                         // Map to "invalid ap" error.
       
  1707                         entryErr = KMmsErrorAP1Invalid;
       
  1708                         }
       
  1709                     switch ( entryErr )
       
  1710                         {
       
  1711                         case KErrDiskFull:
       
  1712                             {
       
  1713                             MEWLOGGER_WRITE( "MMS fetch - disk full" );
       
  1714                             HandleDiskSpaceErrorL( entry );
       
  1715                             }
       
  1716                             break;
       
  1717                         case KErrNoMemory:
       
  1718                             {
       
  1719                             MEWLOGGER_WRITE( "MMS fetch - out of memory" );
       
  1720                             HandleMemoryErrorL( entry );
       
  1721                             }
       
  1722                             break;
       
  1723                         // the first error is activated again to synchronize
       
  1724                         // with connection manager (MPM)
       
  1725                         case KErrPacketDataTsyMaxPdpContextsReached:
       
  1726                         case KErrUmtsMaxNumOfContextExceededByPhone:
       
  1727                         case KErrUmtsMaxNumOfContextExceededByNetwork:
       
  1728                         // add the following error to the list to synchronize with 
       
  1729                         // connection manager (MPM)
       
  1730                         case KErrGprsInsufficientResources:
       
  1731                             {
       
  1732                             //Let's now save the id. This way we can reset the entrys
       
  1733                             //error field just before the fetch start. This prevents
       
  1734                             //duplicate error notes because this case branch is reached many times.
       
  1735                             iCurrentEntryId = entry.Id();
       
  1736                             //Connection already active should be "detected"
       
  1737                             //only after third retry failure if "disconnect
       
  1738                             //delay" feature is activated.
       
  1739                             TInt retries = ( iWatcherFlags & EReceivingDisconnectDelay )
       
  1740                                 ? KConnectionRetries
       
  1741                                 : 0;
       
  1742                             if ( ( entry.iMtmData3 & KMmsRetryCountMask ) >= retries ) //lint !e574
       
  1743                                 {
       
  1744                                 MEWLOGGER_WRITE( "MMS fetch - connection active" );
       
  1745                                 
       
  1746                                 
       
  1747                                 HandleConnectionErrorL( entry, ETrue );
       
  1748                                 }
       
  1749                             }
       
  1750 
       
  1751                             break;
       
  1752 
       
  1753                         
       
  1754                         
       
  1755                         case KMmsErrorNoWAPAccessPoint:
       
  1756                             {
       
  1757                             MEWLOGGER_WRITE( "MMS fetch - no access point" );
       
  1758                             HandleNoAPErrorL( entry );
       
  1759                             }
       
  1760                             break;
       
  1761                         case KMmsErrorAP1Invalid:
       
  1762                         case KMmsErrorNoURI1:
       
  1763                             {
       
  1764                             MEWLOGGER_WRITE( "MMS fetch - invalid access point" );
       
  1765                             HandleInvalidAPErrorL( entry, ETrue );
       
  1766                             }
       
  1767                             break;
       
  1768                         case KErrIfAuthenticationFailure: //username/passwd
       
  1769                             {
       
  1770                             MEWLOGGER_WRITE( "MMS fetch - username/passwd" );
       
  1771                             HandleInvalidAPErrorL( entry, EFalse );
       
  1772                             }
       
  1773                             break;
       
  1774                         default:
       
  1775                             //nothing to do
       
  1776                             break;
       
  1777                         }
       
  1778                     }
       
  1779                 i++;
       
  1780                 }
       
  1781             }
       
  1782             break;
       
  1783         case EMsvEntriesMoved: // Messages are moved _from_ this "folder".
       
  1784         case EMsvEntriesDeleted:
       
  1785             {
       
  1786             TInt i = 0;
       
  1787             TInt originalCount = iMmsReceiveErrorMessages->Count();
       
  1788 
       
  1789 MEWLOGGER_WRITEF( _L("Entries deleted: %d"), count );
       
  1790 
       
  1791             while ( i < count )
       
  1792                 {
       
  1793                 TInt selectionId = iMmsReceiveErrorMessages->Find( aEntries->At( i ) );
       
  1794                 if ( selectionId != KErrNotFound )
       
  1795                     {
       
  1796 MEWLOGGER_WRITE( "Fetch msg removed" );
       
  1797                     iMmsReceiveErrorMessages->Delete( selectionId );
       
  1798                     }
       
  1799                 i++;
       
  1800                 }
       
  1801             if ( originalCount && !iMmsReceiveErrorMessages->Count() )
       
  1802                 {
       
  1803                 // array was emptied
       
  1804                 ResetWatcher();
       
  1805                 }
       
  1806             }
       
  1807             break;
       
  1808         default:
       
  1809             break;
       
  1810         }
       
  1811     }
       
  1812 
       
  1813 
       
  1814 // ---------------------------------------------------------
       
  1815 // CMsgErrorWatcher::ResetErrorFieldL
       
  1816 //
       
  1817 // Reset TMsvEntry::iError of the current notification
       
  1818 // ---------------------------------------------------------
       
  1819 //
       
  1820 void CMsgErrorWatcher::ResetErrorFieldL( )
       
  1821     {
       
  1822     //Makes sure the entry is set
       
  1823     if( iCurrentEntryId != KMsvNullIndexEntryId )
       
  1824         {
       
  1825         CMsvEntry *cEntry( NULL );
       
  1826         TRAPD( err, cEntry = iSession->GetEntryL( iCurrentEntryId ) );
       
  1827         if ( err == KErrNotFound )
       
  1828         	{
       
  1829         	iCurrentEntryId = KMsvNullIndexEntryId;
       
  1830         	return;
       
  1831         	}
       
  1832         CleanupStack::PushL( cEntry );
       
  1833         TMsvEntry tEntry = cEntry->Entry();
       
  1834         tEntry.iError = KErrNone;
       
  1835         cEntry -> ChangeL( tEntry );
       
  1836         CleanupStack::PopAndDestroy( cEntry );
       
  1837         //This prevents getting here to often
       
  1838         iCurrentEntryId = KMsvNullIndexEntryId;
       
  1839         }   
       
  1840     }
       
  1841     
       
  1842 // ---------------------------------------------------------
       
  1843 // CMsgErrorWatcher::ResetErrorFieldL
       
  1844 //
       
  1845 // Reset TMsvEntry::iError 
       
  1846 // ---------------------------------------------------------
       
  1847 //
       
  1848 void CMsgErrorWatcher::ResetErrorFieldL( TMsvEntry& aEntry )
       
  1849     {
       
  1850     CMsvEntry *cEntry = iSession->GetEntryL( aEntry.Id() );  
       
  1851     CleanupStack::PushL( cEntry );
       
  1852     aEntry.iError = KErrNone;
       
  1853     cEntry -> ChangeL( aEntry );
       
  1854     CleanupStack::PopAndDestroy( cEntry ); 
       
  1855     }
       
  1856 
       
  1857 // ---------------------------------------------------------
       
  1858 // CMsgErrorWatcher::DoCancel
       
  1859 //
       
  1860 // From active object framework
       
  1861 // ---------------------------------------------------------
       
  1862 //
       
  1863 void CMsgErrorWatcher::DoCancel()
       
  1864     {
       
  1865     iTimer.Cancel();
       
  1866     if ( iOperation )
       
  1867         {
       
  1868         iOperation->Cancel();
       
  1869         }
       
  1870     }
       
  1871 
       
  1872 // ---------------------------------------------------------
       
  1873 // CMsgErrorWatcher::RunL
       
  1874 //
       
  1875 // From active object framework
       
  1876 // ---------------------------------------------------------
       
  1877 //
       
  1878 void CMsgErrorWatcher::RunL()
       
  1879     {
       
  1880 MEWLOGGER_WRITEF( _L("RunL, iStatus: %d"), iStatus.Int() );
       
  1881 MEWLOGGER_WRITEF( _L("RunL, iRequestType: %d"), iRequestType );
       
  1882     switch ( iRequestType )
       
  1883         {
       
  1884         case EMsgRequestStartingUp:
       
  1885             {
       
  1886             if ( !( iWatcherFlags & EWatcherRunning ) )
       
  1887                 {
       
  1888                 TRAPD ( err, StartWatcherL() );
       
  1889                 if ( err ) //make sure watcher is not left in obscure state
       
  1890                     {
       
  1891 MEWLOGGER_WRITEF( _L("Leave from StartWatcherL: %d"), err );
       
  1892                     StopWatcher();
       
  1893                     if ( iTimerRetries < KMaxTimerRetries )
       
  1894                         {
       
  1895                         StartRestartTimer();
       
  1896                         }
       
  1897                     //else give up
       
  1898                     }
       
  1899                 }
       
  1900             }
       
  1901             break;
       
  1902         case EMsgRequestSending:
       
  1903             if ( iStatus.Int() == KErrNone )
       
  1904                 {
       
  1905                 ShowGlobalNoteL( ESendingMessageNote );
       
  1906                 }
       
  1907             if ( iMmsReceiveErrorMessages->Count() )
       
  1908                 {
       
  1909                 StartMmsFetchL();
       
  1910                 }
       
  1911             else
       
  1912                 {
       
  1913                 MEWLOGGER_WRITE( "RunL, Deleting connection observer" );
       
  1914                 delete iConnectionObserver;
       
  1915                 iConnectionObserver = NULL;
       
  1916                 ResetErrorFieldL();
       
  1917                 }
       
  1918             break;
       
  1919         case EMsgRequestFetching:
       
  1920             ResetErrorFieldL();
       
  1921             ResetWatcher();
       
  1922             break;
       
  1923         case EMsgRequestWaitingErrorNote:
       
  1924             ShowErrorMessageQueryL();
       
  1925             break;
       
  1926         case EMsgRequestWaitingDisconnection:
       
  1927             {
       
  1928             MEWLOGGER_WRITE( "RunL, Disconnect delay passed" );
       
  1929             if ( iMmsSendErrorMessages->Count() )
       
  1930                 {
       
  1931                 StartMmsSendL();
       
  1932                 }
       
  1933             else
       
  1934                 {
       
  1935                 StartMmsFetchL();
       
  1936                 }
       
  1937             //ResetErrorFieldL();     
       
  1938             }
       
  1939             break;
       
  1940         case EMsgRequestFetchingAll:
       
  1941         default:
       
  1942             break;
       
  1943         }
       
  1944     }
       
  1945 
       
  1946 // ================= OTHER EXPORTED FUNCTIONS ==============
       
  1947 
       
  1948 //
       
  1949 // ---------------------------------------------------------
       
  1950 // Panic implements
       
  1951 // panic, for debug version only
       
  1952 // ---------------------------------------------------------
       
  1953 //
       
  1954 GLDEF_C void Panic( TInt aPanic ) // enum for panic codes
       
  1955     {
       
  1956     _LIT( KPanicText, "MsgErrorWatcher" );
       
  1957     User::Panic( KPanicText, aPanic );
       
  1958     }   
       
  1959 
       
  1960 //  End of File  
       
  1961