mmsengine/mmsserver/src/mmsmmboxlist.cpp
changeset 31 ebfee66fde93
child 47 5b14749788d7
equal deleted inserted replaced
30:6a20128ce557 31:ebfee66fde93
       
     1 /*
       
     2 * Copyright (c) 2004-2007 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 *     State machine for mmbox list
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include    <logcli.h>
       
    23 #include    <msvids.h>
       
    24 #include    <msventry.h>
       
    25 #include    <msvstd.h>
       
    26 #include    <e32std.h> // TTime
       
    27 
       
    28 // the rest are local includes
       
    29 #include    "mmsmmboxlist.h"
       
    30 #include    "mmsconst.h"
       
    31 #include    "mmsencode.h"
       
    32 #include    "mmsdecode.h"
       
    33 #include    "mmsheaders.h"
       
    34 #include    "mmsmmboxviewheaders.h"
       
    35 #include    "mmsserverentry.h"
       
    36 #include    "mmssettings.h"
       
    37 #include    "mmssession.h"
       
    38 #include    "mmserrors.h"
       
    39 #include    "MmsServerDebugLogging.h"
       
    40 
       
    41 // EXTERNAL DATA STRUCTURES
       
    42 
       
    43 // EXTERNAL FUNCTION PROTOTYPES  
       
    44 
       
    45 
       
    46 // CONSTANTS
       
    47 _LIT( K1970, "19700000:000000.000000" );    // 1-Jan 1970 0:00:00
       
    48 // MACROS
       
    49 
       
    50 // LOCAL CONSTANTS AND MACROS
       
    51 
       
    52 // MODULE DATA STRUCTURES
       
    53 
       
    54 // LOCAL FUNCTION PROTOTYPES
       
    55 
       
    56 // ==================== LOCAL FUNCTIONS ====================
       
    57 
       
    58 // ================= MEMBER FUNCTIONS =======================
       
    59 
       
    60 // ---------------------------------------------------------
       
    61 // CMmsMmboxList::CMmsMmboxList
       
    62 //
       
    63 // ---------------------------------------------------------
       
    64 //
       
    65 CMmsMmboxList::CMmsMmboxList( RFs& aFs ):
       
    66     CMmsBaseOperation( aFs )
       
    67     {
       
    68     }
       
    69 
       
    70 // ---------------------------------------------------------
       
    71 // CMmsMmboxList::ConstructL
       
    72 //
       
    73 // ---------------------------------------------------------
       
    74 //
       
    75 void CMmsMmboxList::ConstructL( CMmsSettings* aMmsSettings )
       
    76     {
       
    77     CMmsBaseOperation::ConstructL( aMmsSettings );
       
    78     iMmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
       
    79     iOldNotifications = new ( ELeave ) CMsvEntrySelection;
       
    80     CActiveScheduler::Add( this );
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------
       
    84 // CMmsMmboxList::NewL
       
    85 //
       
    86 // ---------------------------------------------------------
       
    87 //
       
    88 CMmsMmboxList* CMmsMmboxList::NewL( RFs& aFs, CMmsSettings* aMmsSettings  )
       
    89     {
       
    90     CMmsMmboxList* self = new ( ELeave ) CMmsMmboxList( aFs );
       
    91     CleanupStack::PushL( self );
       
    92     self->ConstructL( aMmsSettings );
       
    93     CleanupStack::Pop( self );
       
    94     return self;
       
    95     }
       
    96 
       
    97 // ---------------------------------------------------------
       
    98 // CMmsMmboxList::~CMmsMmboxList
       
    99 //
       
   100 // ---------------------------------------------------------
       
   101 //
       
   102 CMmsMmboxList::~CMmsMmboxList()
       
   103     {
       
   104     Cancel(); // has to be called first
       
   105     delete iOldNotifications;
       
   106     delete iMmsHeaders;
       
   107     }
       
   108 
       
   109 // ---------------------------------------------------------
       
   110 // CMmsMmboxList::StartL
       
   111 //
       
   112 // ---------------------------------------------------------
       
   113 //
       
   114 void CMmsMmboxList::StartL(
       
   115             CMsvEntrySelection& aSelection,
       
   116             CMsvServerEntry& aServerEntry,
       
   117             TMsvId aService,
       
   118             TRequestStatus& aStatus )
       
   119     {
       
   120     LOG( _L("CMmsMmboxList::StartL") );
       
   121 
       
   122     // Make sure that the aSelection is empty
       
   123     aSelection.Reset();
       
   124     CMmsBaseOperation::InitializeL( aSelection, aServerEntry, aService );
       
   125     iMmsHeaders->Reset();
       
   126 
       
   127     iOldNotifications->Reset();
       
   128     // get current notifications from mmbox folder 
       
   129     iMmboxFolder = iMmsSettings->MMBoxFolder();
       
   130     if ( iError == KErrNone )
       
   131         {
       
   132         iError = iServerEntry->SetEntry( iMmboxFolder );
       
   133         }
       
   134     // If cannot access MMBoxFolder, we are in trouble
       
   135     // When iError not equal to KErrNone, the operation will complete after running through RunL
       
   136     if ( iError == KErrNone )
       
   137         {
       
   138         TInt err;
       
   139         err = iServerEntry->GetChildrenWithMtm( KUidMsgMMSNotification, *iOldNotifications );
       
   140         if (err != KErrNone)
       
   141             {
       
   142             return;
       
   143             }
       
   144 			iOldQuotaEntryId = OldQuotaEntryL();
       
   145         }
       
   146     else
       
   147         {
       
   148         iOldQuotaEntryId = KMsvNullIndexEntryId;
       
   149         }
       
   150     iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   151 
       
   152     Queue( aStatus );
       
   153     FallThrough();   
       
   154     }
       
   155 
       
   156 // ---------------------------------------------------------
       
   157 // CMmsMmboxList::DoCancel
       
   158 //
       
   159 // ---------------------------------------------------------
       
   160 //
       
   161 void CMmsMmboxList::DoCancel()
       
   162     {
       
   163     LOG( _L("CMmsMmboxList::DoCancel") );
       
   164     CMmsBaseOperation::DoCancel();
       
   165     }
       
   166 
       
   167 // ---------------------------------------------------------
       
   168 // CMmsMmboxList::EncodePDUL
       
   169 //
       
   170 // ---------------------------------------------------------
       
   171 //
       
   172 void CMmsMmboxList::EncodePDUL()
       
   173     {
       
   174     LOG( _L("CMmsMmboxList::EncodePDU") );
       
   175 
       
   176     // As no entry exists to be encoded, mmsheaders are not restored and stored.
       
   177 
       
   178     //  Set message type
       
   179     iMmsHeaders->SetMessageType( KMmsMessageTypeMboxViewReq );
       
   180 
       
   181     // Request mmbox total and quota information 
       
   182     CMmsMMBoxViewHeaders& viewHeaders = iMmsHeaders->MMBoxViewHeadersL();
       
   183     viewHeaders.SetMmsTotals( KMmsYes );
       
   184     viewHeaders.SetMmsQuotas( KMmsYes );
       
   185 
       
   186     // Set TransactionId
       
   187     TBufC8<KMMSMAXTIDLENGTH> tid;
       
   188     tid.Des().NumUC( AllocateTID(), EHex );
       
   189     iMmsHeaders->SetTidL( tid );
       
   190 
       
   191     // Encode the mmboxview request
       
   192     iEncoder->EncodeHeadersL( *iMmsHeaders, *iEncodeBuffer );
       
   193 
       
   194     FallThrough();
       
   195     }
       
   196 
       
   197 // ---------------------------------------------------------
       
   198 // CMmsMmboxList::SubmitTransactionL
       
   199 //
       
   200 // ---------------------------------------------------------
       
   201 //
       
   202 void CMmsMmboxList::SubmitTransactionL()
       
   203     {
       
   204     LOG( _L("CMmsMmboxList::SubmitTransaction"));
       
   205 
       
   206     if ( !iConnected )
       
   207         {
       
   208         if ( iError == KErrNone )
       
   209             {
       
   210             iError = KErrCouldNotConnect;
       
   211             }
       
   212         }
       
   213       
       
   214     // This check is needed only when running tests in global mode
       
   215     // if length of URI is 0, Symbian code will panic    
       
   216     if ( !iUri )
       
   217         {
       
   218         if ( !iMmsSettings->LocalMode() )
       
   219             {
       
   220             iError = KMmsErrorNoURI1;
       
   221             }
       
   222         }
       
   223     else if ( iUri->Des().Length() == 0 && !iMmsSettings->LocalMode() )
       
   224         {
       
   225         iError = KMmsErrorNoURI1;
       
   226         }
       
   227 
       
   228     if ( iError != KErrNone )
       
   229         {
       
   230         FallThrough();
       
   231         return;
       
   232         }
       
   233 
       
   234     if ( !iMmsSettings->LocalMode() )
       
   235         {
       
   236         // Send
       
   237         iMmsSession->SendMessageL(
       
   238             iUri->Des(),
       
   239             *iEncodeBuffer,
       
   240             *iEncoder,
       
   241             *iDecoder,
       
   242             iStatus );
       
   243         SetActive();
       
   244         }
       
   245     else
       
   246         {
       
   247         LocalModeFetchL();
       
   248         }
       
   249     }
       
   250 
       
   251 // ---------------------------------------------------------
       
   252 // CMmsMmboxList::CreateEntryL
       
   253 //
       
   254 // ---------------------------------------------------------
       
   255 //
       
   256 void CMmsMmboxList::CreateEntryL()
       
   257     {
       
   258     LOG( _L("CMmsMmboxList CreateEntry"));
       
   259     // Create an mms entry under mmbox folder
       
   260     if ( iOldQuotaEntryId != KMsvNullIndexEntryId )
       
   261         {
       
   262         // Reuse old quota
       
   263         iEntryUnderConstruction = iOldQuotaEntryId;
       
   264         }
       
   265     else
       
   266         {
       
   267         // If no old quota entry exists, we create a new one
       
   268         iError = iServerEntry->SetEntry( iMmboxFolder );
       
   269         if ( iError == KErrNone )
       
   270             {
       
   271             // set all relevant flags in tMsvEntry
       
   272             TMsvEntry tEntry;
       
   273             tEntry.iMtm = KUidMsgTypeMultimedia;
       
   274             tEntry.iDate.UniversalTime();
       
   275             SetFirstFlagsToNewEntry( tEntry );
       
   276 
       
   277             iError = iServerEntry->CreateEntry( tEntry );
       
   278             if ( iError == KErrNone )
       
   279                 {
       
   280                 iEntryUnderConstruction = tEntry.Id();
       
   281                 }
       
   282             }
       
   283         iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   284         }
       
   285     FallThrough();
       
   286     }
       
   287 
       
   288 // ---------------------------------------------------------
       
   289 // CMmsMmboxList::DecodeResponseL
       
   290 //
       
   291 // ---------------------------------------------------------
       
   292 //
       
   293 void CMmsMmboxList::DecodeResponseL()
       
   294     {
       
   295     LOG( _L("CMmsMmboxList::DecodeResponseL"));
       
   296     if( iEncodeBuffer->Size() < 1 )
       
   297         {
       
   298         iError  = KErrCorrupt; 
       
   299         } 
       
   300     if( iError != KErrNone ) 
       
   301         {
       
   302         FallThrough();
       
   303         return;
       
   304         }
       
   305 
       
   306     iMmsHeaders->Reset();    
       
   307     // Decode mmbox view confirmation
       
   308     TInt numAtt = 0;
       
   309     TInt dataStart = 0;
       
   310     TInt startInBuffer = 0;
       
   311     TInt length = iEncodeBuffer->Size();
       
   312     iDecoder->DecodeHeadersL( *iEntryWrapper,
       
   313         *iMmsHeaders, 
       
   314         *iEncodeBuffer,
       
   315         startInBuffer,
       
   316         length,
       
   317         &numAtt,
       
   318         &dataStart );
       
   319 
       
   320     // The content type have to be mmbox view conf. 
       
   321     if ( iMmsHeaders->MessageType() != KMmsMessageTypeMboxViewConf )
       
   322         {
       
   323         // the content type is not correct. Don't save the headers
       
   324         if ( iMmsHeaders->MessageType() == KMmsMessageTypeMSendConf &&
       
   325              iMmsHeaders->ResponseStatus() == KMmsErrorUnsupportedMessage ) 
       
   326             {
       
   327             iError = KErrNotSupported;
       
   328             }
       
   329         else
       
   330             {
       
   331             iError = KErrCorrupt;
       
   332             }
       
   333         }
       
   334         
       
   335     if ( iError == KErrNone )
       
   336         {
       
   337         if ( iOldQuotaEntryId != KMsvNullIndexEntryId )
       
   338             {
       
   339             // We must make the entry read only again
       
   340             iError = iServerEntry->SetEntry( iOldQuotaEntryId );
       
   341             if ( iError == KErrNone )
       
   342                 {
       
   343                 TMsvEntry tEntry = iServerEntry->Entry();
       
   344                 tEntry.SetReadOnly( EFalse );
       
   345                 iServerEntry->ChangeEntry( tEntry );
       
   346                 }
       
   347             iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   348             }
       
   349         iError = iEntryWrapper->SetCurrentEntry( iEntryUnderConstruction );
       
   350         }
       
   351     
       
   352     // save the mmbox view confirmation headers, 
       
   353     // as the decode does not save them
       
   354     if ( iError == KErrNone )
       
   355         {
       
   356         iError = iEntryWrapper->StoreMmsHeadersL( *iMmsHeaders, NULL );
       
   357         }
       
   358        
       
   359     // decode rest of the PDUs if we have any.
       
   360     TInt start = dataStart; // start of multipart data.
       
   361     for ( TInt i = 0; i < numAtt && iError == KErrNone; i++ )
       
   362         {
       
   363         length = iEncodeBuffer->Size() - start;
       
   364         // We extract next data part, but we don't use the mime headers that would be returned
       
   365         iDecoder->ExtractNextDataPartL( *iEncodeBuffer,
       
   366             start, // start of next data part
       
   367             dataStart, // start of actual data
       
   368             length ); // length of data
       
   369 
       
   370         // Create a new entry for the mmbox description PDU
       
   371         iError = iServerEntry->SetEntry( iMmboxFolder );
       
   372         TMsvEntry descEntry;
       
   373         if ( iError == KErrNone )
       
   374             {
       
   375             // set all relevant flags in tMsvEntry
       
   376             descEntry.iMtm = KUidMsgMMSNotification;
       
   377             SetFirstFlagsToNewEntry( descEntry );
       
   378             iError = iServerEntry->CreateEntry( descEntry );
       
   379             }
       
   380 
       
   381         if ( iError == KErrNone )
       
   382             {                         
       
   383             // Decode description PDU
       
   384             iMmsHeaders->Reset();
       
   385             TInt attaNum = 0;
       
   386             TInt attaDataStart = 0;
       
   387             iDecoder->DecodeHeadersL( *iEntryWrapper,
       
   388                 *iMmsHeaders, 
       
   389                 *iEncodeBuffer,
       
   390                 dataStart,
       
   391                 length,
       
   392                 &attaNum,
       
   393                 &attaDataStart );
       
   394 
       
   395             iError = iEntryWrapper->SetCurrentEntry( descEntry.Id() );
       
   396             }
       
   397             
       
   398         // Checking the content type
       
   399     	if( iError == KErrNone )
       
   400 	        {
       
   401 	        // The content type has to be mmbox view description.
       
   402     	    if( iMmsHeaders->MessageType() != KMmsMessageTypeMBoxDescr )
       
   403     	        {
       
   404                 // Content type is not correct.
       
   405                 iError = KErrCorrupt;
       
   406                 LOG( _L("ERROR: Wrong content type"));
       
   407             	}
       
   408             else 
       
   409          	    {
       
   410                 // Mark mmbox notification specific flags
       
   411     	        // Mark as notification. This information is important for UI.
       
   412                 descEntry.iMtmData1 = KMmsMessageMNotificationInd; 
       
   413                 descEntry.iMtmData2 = KMmsStoredInMMBox;
       
   414                 descEntry.iMtmData2 |= KMmsNotifyResponseSent;
       
   415     	        }
       
   416 	        }
       
   417         if( iError == KErrNone )
       
   418             {
       
   419             // Set subject etc. to the notification entry
       
   420             iError = StoreContentToNotificationEntryL( descEntry );
       
   421             }
       
   422         if ( iError == KErrNone )
       
   423             {
       
   424             // Save the headers as the decoder does not save them
       
   425             iError = iEntryWrapper->StoreMmsHeadersL( *iMmsHeaders, NULL );
       
   426             }
       
   427         if ( iError == KErrNone )
       
   428             {
       
   429             // add new notification to iSelection list
       
   430             iSelection->AppendL( descEntry.Id() );
       
   431             }
       
   432         } // for loop
       
   433   
       
   434     iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   435     FallThrough();
       
   436     }
       
   437 
       
   438 // ---------------------------------------------------------
       
   439 // CMmsMmboxList::MoveEntryL
       
   440 //
       
   441 // ---------------------------------------------------------
       
   442 //
       
   443 void CMmsMmboxList::MoveEntryL()
       
   444     {
       
   445     LOG( _L("CMmsMmboxList::MoveEntryL"));
       
   446     if ( iError != KErrNone )
       
   447         {
       
   448         FallThrough();
       
   449         return;
       
   450         }
       
   451 
       
   452     // Delete old notifications  
       
   453     iError = RemoveOldNotifications();
       
   454 
       
   455     // make new notifications visible
       
   456     if ( iError == KErrNone )
       
   457         {
       
   458         iError = MakeNewNotificationsVisible();
       
   459         }
       
   460         
       
   461     // Finalize the new quota entry - if we created a new one and did not
       
   462     // just reuse the old entry
       
   463     
       
   464     TMsvEntry tEntry;
       
   465     
       
   466     if ( iError == KErrNone || iOldQuotaEntryId == KMsvNullIndexEntryId )
       
   467         {
       
   468         iError = iServerEntry->SetEntry( iEntryUnderConstruction );
       
   469         if ( iError == KErrNone )
       
   470             {
       
   471             tEntry = iServerEntry->Entry();
       
   472             SetFlagsToEntryBeingFinalized( tEntry );
       
   473             // update the time the quota entry was updated
       
   474             tEntry.iDate.UniversalTime();
       
   475             tEntry.iError = KErrNone; // clear possible old error
       
   476             
       
   477             // Quota entry must not be visible.
       
   478             // Otherwise the shows the number of notifications in mmboxfolder wrong.
       
   479             tEntry.SetVisible( EFalse );
       
   480             iError = iServerEntry->ChangeEntry( tEntry );
       
   481             if ( iError == KErrNone )
       
   482                 {
       
   483                 iEntryUnderConstruction = KMsvNullIndexEntryId;
       
   484                 }
       
   485             }
       
   486         iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   487         }
       
   488         
       
   489     FallThrough();
       
   490     }
       
   491 
       
   492 // ---------------------------------------------------------
       
   493 // CMmsMmboxList::FinalizeL()
       
   494 //
       
   495 // ---------------------------------------------------------
       
   496 //
       
   497 void CMmsMmboxList::FinalizeL()
       
   498     {
       
   499     LOG( _L("CMmsMmboxList::FinalizeL"));
       
   500     
       
   501     TInt error;
       
   502     
       
   503     // In case something has failed. Delete the new quota entry
       
   504     // - but only in case it was just created
       
   505     if ( iError != KErrNone )
       
   506         {
       
   507         error = iServerEntry->SetEntry( iMmboxFolder );
       
   508         if ( error == KErrNone )
       
   509             {
       
   510             // we can only delete, if we can set context to parent
       
   511             if ( iOldQuotaEntryId == KMsvNullIndexEntryId )
       
   512                 {
       
   513                 iServerEntry->DeleteEntry( iEntryUnderConstruction );
       
   514                 }
       
   515             
       
   516             // if iSelection contains now notifications, the notifications
       
   517             // are not ready yet. They can be destroyed.
       
   518             if ( iSelection->Count() > 0 )
       
   519                 {
       
   520                 iServerEntry->DeleteEntries( *iSelection );
       
   521                 }
       
   522             }
       
   523         iEntryUnderConstruction = KMsvNullIndexEntryId;
       
   524         
       
   525         iSelection->Reset();
       
   526 
       
   527         // we don't care if the iOldNotifications is empty or not. 
       
   528         // If the old notifications are not deleted, they can stay
       
   529         // in the mmbox folder. The array is reseted anyway.
       
   530         iOldNotifications->Reset();
       
   531         
       
   532         // set iError to old quota entry, if the entry exists
       
   533         if ( iOldQuotaEntryId != KMsvNullIndexEntryId )
       
   534             {
       
   535 
       
   536             LOG( _L("- old quota entry exists"));
       
   537 
       
   538             error = iServerEntry->SetEntry( iOldQuotaEntryId );
       
   539             if ( error == KErrNone )
       
   540                 {
       
   541                 TMsvEntry tEntry = iServerEntry->Entry();
       
   542                 tEntry.iError = iError;
       
   543             
       
   544                 error = iServerEntry->ChangeEntry( tEntry );
       
   545                 if ( error == KErrNone )
       
   546                     {
       
   547                     LOG( _L("- iError saved to old quota entry."));                
       
   548                     }
       
   549                 }
       
   550             }
       
   551 
       
   552         iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   553         }
       
   554 
       
   555     CMmsBaseOperation::FinalizeL();
       
   556     }
       
   557 
       
   558 // ---------------------------------------------------------
       
   559 // CMmsMmboxList::SetFirstFlagsToNewEntry
       
   560 //
       
   561 // ---------------------------------------------------------
       
   562 //
       
   563 void CMmsMmboxList::SetFirstFlagsToNewEntry( TMsvEntry& aEntry )
       
   564     {
       
   565     aEntry.iType = KUidMsvMessageEntry;
       
   566     aEntry.iServiceId = iService;
       
   567     aEntry.SetVisible( EFalse );
       
   568     aEntry.SetComplete( EFalse );
       
   569     aEntry.SetInPreparation( ETrue );
       
   570     aEntry.SetReadOnly( EFalse );
       
   571     aEntry.SetNew( ETrue );
       
   572     aEntry.SetUnread( ETrue );
       
   573     }
       
   574 
       
   575 // ---------------------------------------------------------
       
   576 // CMmsMmboxList::SetFlagsToEntryBeingFinalized
       
   577 //
       
   578 // ---------------------------------------------------------
       
   579 //
       
   580 void CMmsMmboxList::SetFlagsToEntryBeingFinalized( TMsvEntry& aEntry )
       
   581     {
       
   582     aEntry.iMtmData1 |= KMmsMessageMobileTerminated;
       
   583     aEntry.SetReadOnly( ETrue );
       
   584     aEntry.SetVisible( ETrue ); 
       
   585     aEntry.SetInPreparation( EFalse );
       
   586     aEntry.SetComplete( ETrue );
       
   587     }
       
   588 
       
   589 // ---------------------------------------------------------
       
   590 // CMmsMmboxList::RemoveOldNotifications
       
   591 //
       
   592 // ---------------------------------------------------------
       
   593 //
       
   594 TInt CMmsMmboxList::RemoveOldNotifications()
       
   595     {
       
   596     LOG( _L("CMmsMmboxList::RemoveOldNotifications"));
       
   597 
       
   598     TInt error = iServerEntry->SetEntry( iMmboxFolder );
       
   599     if ( error == KErrNone && iOldNotifications->Count() > 0 )
       
   600         {
       
   601         error = iServerEntry->DeleteEntries( *iOldNotifications );
       
   602         if ( error == KErrNone )
       
   603             {
       
   604             iOldNotifications->Reset();
       
   605             }
       
   606         }
       
   607 
       
   608     iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   609     return error;
       
   610     }
       
   611 
       
   612 // ---------------------------------------------------------
       
   613 // CMmsMmboxList::MakeNewNotificationsVisible
       
   614 //
       
   615 // ---------------------------------------------------------
       
   616 //
       
   617 TInt CMmsMmboxList::MakeNewNotificationsVisible()
       
   618     {
       
   619     LOG( _L("CMmsMmboxList::MakeNewNotificationsVisible"));
       
   620     TInt count = iSelection->Count();
       
   621     TInt error = KErrNone;
       
   622     for ( TInt i = count - 1; i >=0 && error == KErrNone; i-- )
       
   623         {
       
   624         error = iServerEntry->SetEntry( iSelection->At( i ) );
       
   625         if ( error == KErrNone )
       
   626             {                
       
   627             TMsvEntry tEntry = iServerEntry->Entry();
       
   628             SetFlagsToEntryBeingFinalized( tEntry );
       
   629             error = iServerEntry->ChangeEntry( tEntry );
       
   630             if ( error == KErrNone )
       
   631                 {
       
   632                 iSelection->Delete( i );
       
   633                 }
       
   634             }
       
   635         }
       
   636     iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   637     return error;    
       
   638     }
       
   639 
       
   640 // ---------------------------------------------------------
       
   641 // CMmsMmboxList::StoreContentToNotificationEntryL
       
   642 //
       
   643 // ---------------------------------------------------------
       
   644 //
       
   645 TInt CMmsMmboxList::StoreContentToNotificationEntryL( TMsvEntry aEntry )
       
   646     {
       
   647     LOG( _L("CMmsMmboxList::SetContentToNotificationL"));
       
   648     
       
   649     // Expiry interval must be changed to absolute time,
       
   650     // otherwise it makes no sense.
       
   651     if ( iMmsHeaders->ExpiryDate() == 0 )
       
   652         {
       
   653         TTime time;
       
   654         // handle expiry in universal time
       
   655         time.UniversalTime();
       
   656         time += TTimeIntervalSeconds( iMmsHeaders->ExpiryInterval() );
       
   657         iMmsHeaders->SetExpiryDate(
       
   658             ( time.MicroSecondsFrom( TTime( KMmsYear1970String ) ).Int64() ) / KMmsMillion );
       
   659         }
       
   660         
       
   661     // If the notifications does not contains the date value from the server, 
       
   662     // arrival time is set to notification.
       
   663     // Otherwise the date from the server.
       
   664 
       
   665     LOG( _L("Mark time"));
       
   666 
       
   667     if ( iMmsHeaders->Date() == 0 )
       
   668         {
       
   669         aEntry.iDate.UniversalTime();
       
   670         }
       
   671     else
       
   672         {
       
   673         aEntry.iDate = ServerDate();
       
   674         } 
       
   675     
       
   676     // Mark subject
       
   677     if ( iMmsHeaders->Subject().Length() > 0 )
       
   678         {
       
   679         aEntry.iDescription.Set( iMmsHeaders->Subject() );
       
   680         }
       
   681 
       
   682     // Mark size of the notification
       
   683     aEntry.iSize = iMmsHeaders->Size();
       
   684 
       
   685     // Mark message class. 
       
   686     // Default is personal
       
   687     if ( iMmsHeaders->MessageClass() == EMmsClassAdvertisement )
       
   688         {
       
   689         aEntry.iMtmData1 |= KMmsMessageAdvertisement;
       
   690         }
       
   691     else if (iMmsHeaders->MessageClass() == EMmsClassInformational )
       
   692         {
       
   693         aEntry.iMtmData1 |= KMmsMessageInformational;
       
   694         }
       
   695     else
       
   696         {
       
   697         // keep LINT happy
       
   698         }
       
   699         
       
   700     switch ( iMmsHeaders->MessagePriority() )
       
   701         {
       
   702         case KMmsPriorityNormal:
       
   703             aEntry.SetPriority( EMsvMediumPriority );
       
   704             break;
       
   705         case KMmsPriorityLow:
       
   706             aEntry.SetPriority( EMsvLowPriority );
       
   707             break;
       
   708         case KMmsPriorityHigh:
       
   709             aEntry.SetPriority( EMsvHighPriority );
       
   710             break;
       
   711         default:            
       
   712             // if not defined default is normal
       
   713             aEntry.SetPriority( EMsvMediumPriority );
       
   714             break;
       
   715         }
       
   716         
       
   717     // mark sender
       
   718     // If the sender is a phone number, add alias.
       
   719     HBufC* buffer = HBufC::NewL( KMmsMaxDescription );
       
   720     TPtr pBuffer = buffer->Des();
       
   721     
       
   722     if ( TMmsGenUtils::GenerateDetails( iMmsHeaders->Sender(),
       
   723         pBuffer, KMmsMaxDescription, iFs ) == KErrNone )
       
   724         {
       
   725         aEntry.iDetails.Set( pBuffer );
       
   726         }
       
   727     else
       
   728         {
       
   729         // We come here only if there was an fatal error in GenerateDetails.
       
   730         // Even if we don't find the alias, we have something in the string
       
   731         aEntry.iDetails.Set( iMmsHeaders->Sender() );
       
   732         }
       
   733 
       
   734     TInt error = iServerEntry->ChangeEntry( aEntry );
       
   735     delete buffer;
       
   736     buffer = NULL;
       
   737     // iServerEntry is not set to KMsvNullIndexEntryId, 
       
   738     // as the next function demands that the iServerEntry is set to aEntry.
       
   739     return error;
       
   740     }
       
   741 
       
   742 // ---------------------------------------------------------
       
   743 // CMmsMmboxList::OldQuotaEntryL
       
   744 //
       
   745 // ---------------------------------------------------------
       
   746 //
       
   747 TMsvId CMmsMmboxList::OldQuotaEntryL()
       
   748     {
       
   749     LOG( _L("CMmsMmboxList::OldQuotaEntryL"));
       
   750 
       
   751     // iServerEntry context must be set to iMmboxFolder
       
   752     // before calling this function
       
   753     TMsvId oldQuotaEntryId = KMsvNullIndexEntryId;
       
   754     
       
   755     // show invisible entries.
       
   756     TMsvSelectionOrdering ordering =
       
   757         TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByNone, ETrue );
       
   758     iServerEntry->SetSort( ordering );
       
   759 
       
   760     CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; 
       
   761     CleanupStack::PushL( selection );
       
   762     TInt error = iServerEntry->GetChildrenWithMtm( KUidMsgTypeMultimedia, *selection );
       
   763     TInt count = selection->Count();
       
   764 
       
   765     LOG2( _L("- %d mms entries"), count );
       
   766 
       
   767     if( error == KErrNone && count > 0 )
       
   768         {
       
   769 	    for( TInt i = selection->Count() - 1 ; i >= 0; i-- ) 
       
   770             {
       
   771 
       
   772     	    LOG2( _L("- processing at selection[%d]"), i );
       
   773 
       
   774             TMsvId entryId = selection->At( i );
       
   775             error = iServerEntry->SetEntry( entryId );
       
   776             if ( error == KErrNone )
       
   777                 {
       
   778     	        TMsvEntry entry = iServerEntry->Entry();	
       
   779 	            // old quota entry is complete, but not visible	
       
   780     	        if ( ( !entry.Visible() ) && entry.Complete() )
       
   781                     {
       
   782     	            oldQuotaEntryId = entryId;
       
   783                     i = -1;
       
   784                     
       
   785                     LOG( _L("- Old quota found"));
       
   786                     
       
   787 	                }
       
   788                 }
       
   789             }
       
   790         }
       
   791     CleanupStack::PopAndDestroy( selection );
       
   792         
       
   793     return oldQuotaEntryId;
       
   794     }
       
   795 
       
   796 // ---------------------------------------------------------
       
   797 // CMmsMmboxList::ServerDate
       
   798 //
       
   799 // ---------------------------------------------------------
       
   800 //
       
   801 TTime CMmsMmboxList::ServerDate()
       
   802     {
       
   803     
       
   804     LOG( _L("CMmsMmboxList::ServerDate"));
       
   805 
       
   806     TInt64 inSeconds = iMmsHeaders->Date();
       
   807 
       
   808     TTime y1970( K1970 );
       
   809 
       
   810     // 1970 presented as microseconds after January 1st, 0 AD nominal Gregorian.
       
   811     TInt64 ms1970 = y1970.Int64();
       
   812 
       
   813     // If not defined in message headers return 0
       
   814     if ( inSeconds == 0 )
       
   815         {
       
   816         return TTime(0);
       
   817         }
       
   818 
       
   819     // microseconds after 1.1. 1970
       
   820     TInt64 msAfter1970;
       
   821     msAfter1970 = KMmsMillion * inSeconds;
       
   822 
       
   823     return TTime( ms1970 + msAfter1970 );
       
   824     }
       
   825     
       
   826 // ---------------------------------------------------------
       
   827 //
       
   828 // ---------------------------------------------------------
       
   829 //
       
   830 void CMmsMmboxList::LocalModeFetchL()
       
   831     {
       
   832 // This functionality has no meaning in hardware
       
   833 // It is available in WINS to help module testing
       
   834     
       
   835 #ifdef __WINS__
       
   836     RFs fs; // We need a separate session to be able to set the session path
       
   837     RFile file; // local mode message
       
   838     iError = fs.Connect();
       
   839     if ( iError != KErrNone )
       
   840         {
       
   841         FallThrough();
       
   842         }
       
   843     
       
   844     CleanupClosePushL( fs );
       
   845     
       
   846     CDir* fileList = NULL;
       
   847   
       
   848     TEntry* entry = new( ELeave ) TEntry; // allocated from heap to save stack space
       
   849     CleanupStack::PushL( entry );
       
   850     HBufC* filename = HBufC::NewL( KMaxFileName );
       
   851     CleanupStack::PushL( filename );
       
   852     TPtr fileNamePtr = filename->Des();
       
   853     // use different directory in order to be able to simulate
       
   854     // both mmbox view and fetching the corresponding messages
       
   855     fileNamePtr.Copy( KMmsMMBoxDirectory );
       
   856     TInt err = fs.SetSessionPath( fileNamePtr );
       
   857     err = fs.Entry( fileNamePtr, *entry );
       
   858     TInt count = 0;
       
   859     if ( err == KErrNone )
       
   860         {
       
   861         TFindFile* finder = new( ELeave ) TFindFile( fs ); // allocated from heap to save stack space
       
   862         CleanupStack::PushL( finder );
       
   863         _LIT( KWild, "*" );
       
   864 
       
   865         err = finder->FindWildByPath( KWild, &fileNamePtr, fileList );
       
   866         CleanupStack::PopAndDestroy( finder );
       
   867         
       
   868         if ( fileList )
       
   869             {
       
   870             CleanupStack::PushL( fileList );
       
   871             count = fileList->Count();
       
   872             }
       
   873         }
       
   874         
       
   875         
       
   876     if ( count > 0 )
       
   877         {
       
   878         TParse parse;    
       
   879         parse.Set( ( ( *fileList )[0] ).iName, &fileNamePtr, NULL );
       
   880         fileNamePtr.Copy( parse.FullName() );
       
   881         TInt size = fs.Entry( parse.FullName(), *entry );
       
   882         size = entry->iSize;
       
   883         
       
   884         iError = file.Open( fs, fileNamePtr, EFileShareExclusive );
       
   885         if ( iError == KErrNone )
       
   886             {
       
   887             iEncodeBuffer->Reset();
       
   888             TRAP(iError, iEncodeBuffer->ResizeL( size ));
       
   889             if ( iError == KErrNone )
       
   890                 {
       
   891                 TPtr8 pos = iEncodeBuffer->Ptr( 0 );
       
   892                 file.Read( 0, pos, size );
       
   893                 }
       
   894             file.Close();
       
   895             // delete the file after the view has been fetched
       
   896             fs.Delete( fileNamePtr );
       
   897             }
       
   898         }
       
   899 
       
   900     if ( fileList )
       
   901         {
       
   902         CleanupStack::PopAndDestroy( fileList );
       
   903         }
       
   904             
       
   905     CleanupStack::PopAndDestroy( filename );
       
   906     CleanupStack::PopAndDestroy( entry );
       
   907     CleanupStack::PopAndDestroy( &fs ); // close fs
       
   908 #endif
       
   909 
       
   910     FallThrough();
       
   911     }
       
   912     
       
   913 
       
   914 // ================= OTHER EXPORTED FUNCTIONS ==============
       
   915 
       
   916 //  End of File