--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmsengine/mmsserver/src/mmsmmboxlist.cpp Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,911 @@
+/*
+* Copyright (c) 2004-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* State machine for mmbox list
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <logcli.h>
+#include <msvids.h>
+#include <msventry.h>
+#include <msvstd.h>
+#include <e32std.h> // TTime
+
+// the rest are local includes
+#include "mmsmmboxlist.h"
+#include "mmsconst.h"
+#include "mmsencode.h"
+#include "mmsdecode.h"
+#include "mmsheaders.h"
+#include "mmsmmboxviewheaders.h"
+#include "mmsserverentry.h"
+#include "mmssettings.h"
+#include "mmssession.h"
+#include "mmserrors.h"
+#include "MmsServerDebugLogging.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+
+// CONSTANTS
+_LIT( K1970, "19700000:000000.000000" ); // 1-Jan 1970 0:00:00
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// ==================== LOCAL FUNCTIONS ====================
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CMmsMmboxList::CMmsMmboxList
+//
+// ---------------------------------------------------------
+//
+CMmsMmboxList::CMmsMmboxList( RFs& aFs ):
+ CMmsBaseOperation( aFs )
+ {
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::ConstructL
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::ConstructL( CMmsSettings* aMmsSettings )
+ {
+ CMmsBaseOperation::ConstructL( aMmsSettings );
+ iMmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
+ iOldNotifications = new ( ELeave ) CMsvEntrySelection;
+ CActiveScheduler::Add( this );
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::NewL
+//
+// ---------------------------------------------------------
+//
+CMmsMmboxList* CMmsMmboxList::NewL( RFs& aFs, CMmsSettings* aMmsSettings )
+ {
+ CMmsMmboxList* self = new ( ELeave ) CMmsMmboxList( aFs );
+ CleanupStack::PushL( self );
+ self->ConstructL( aMmsSettings );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::~CMmsMmboxList
+//
+// ---------------------------------------------------------
+//
+CMmsMmboxList::~CMmsMmboxList()
+ {
+ Cancel(); // has to be called first
+ delete iOldNotifications;
+ delete iMmsHeaders;
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::StartL
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::StartL(
+ CMsvEntrySelection& aSelection,
+ CMsvServerEntry& aServerEntry,
+ TMsvId aService,
+ TRequestStatus& aStatus )
+ {
+ LOG( _L("CMmsMmboxList::StartL") );
+
+ // Make sure that the aSelection is empty
+ aSelection.Reset();
+ CMmsBaseOperation::InitializeL( aSelection, aServerEntry, aService );
+ iMmsHeaders->Reset();
+
+ iOldNotifications->Reset();
+ // get current notifications from mmbox folder
+ iMmboxFolder = iMmsSettings->MMBoxFolder();
+ if ( iError == KErrNone )
+ {
+ iError = iServerEntry->SetEntry( iMmboxFolder );
+ }
+ // If cannot access MMBoxFolder, we are in trouble
+ // When iError not equal to KErrNone, the operation will complete after running through RunL
+ if ( iError == KErrNone )
+ {
+ iServerEntry->GetChildrenWithMtm( KUidMsgMMSNotification, *iOldNotifications );
+ iOldQuotaEntryId = OldQuotaEntryL();
+ }
+ else
+ {
+ iOldQuotaEntryId = KMsvNullIndexEntryId;
+ }
+ iServerEntry->SetEntry( KMsvNullIndexEntryId );
+
+ Queue( aStatus );
+ FallThrough();
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::DoCancel
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::DoCancel()
+ {
+ LOG( _L("CMmsMmboxList::DoCancel") );
+ CMmsBaseOperation::DoCancel();
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::EncodePDUL
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::EncodePDUL()
+ {
+ LOG( _L("CMmsMmboxList::EncodePDU") );
+
+ // As no entry exists to be encoded, mmsheaders are not restored and stored.
+
+ // Set message type
+ iMmsHeaders->SetMessageType( KMmsMessageTypeMboxViewReq );
+
+ // Request mmbox total and quota information
+ CMmsMMBoxViewHeaders& viewHeaders = iMmsHeaders->MMBoxViewHeadersL();
+ viewHeaders.SetMmsTotals( KMmsYes );
+ viewHeaders.SetMmsQuotas( KMmsYes );
+
+ // Set TransactionId
+ TBufC8<KMMSMAXTIDLENGTH> tid;
+ tid.Des().NumUC( AllocateTID(), EHex );
+ iMmsHeaders->SetTidL( tid );
+
+ // Encode the mmboxview request
+ iEncoder->EncodeHeadersL( *iMmsHeaders, *iEncodeBuffer );
+
+ FallThrough();
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::SubmitTransactionL
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::SubmitTransactionL()
+ {
+ LOG( _L("CMmsMmboxList::SubmitTransaction"));
+
+ if ( !iConnected )
+ {
+ if ( iError == KErrNone )
+ {
+ iError = KErrCouldNotConnect;
+ }
+ }
+
+ // This check is needed only when running tests in global mode
+ // if length of URI is 0, Symbian code will panic
+ if ( !iUri )
+ {
+ if ( !iMmsSettings->LocalMode() )
+ {
+ iError = KMmsErrorNoURI1;
+ }
+ }
+ else if ( iUri->Des().Length() == 0 && !iMmsSettings->LocalMode() )
+ {
+ iError = KMmsErrorNoURI1;
+ }
+
+ if ( iError != KErrNone )
+ {
+ FallThrough();
+ return;
+ }
+
+ if ( !iMmsSettings->LocalMode() )
+ {
+ // Send
+ iMmsSession->SendMessageL(
+ iUri->Des(),
+ *iEncodeBuffer,
+ *iEncoder,
+ *iDecoder,
+ iStatus );
+ SetActive();
+ }
+ else
+ {
+ LocalModeFetchL();
+ }
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::CreateEntryL
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::CreateEntryL()
+ {
+ LOG( _L("CMmsMmboxList CreateEntry"));
+ // Create an mms entry under mmbox folder
+ if ( iOldQuotaEntryId != KMsvNullIndexEntryId )
+ {
+ // Reuse old quota
+ iEntryUnderConstruction = iOldQuotaEntryId;
+ }
+ else
+ {
+ // If no old quota entry exists, we create a new one
+ iError = iServerEntry->SetEntry( iMmboxFolder );
+ if ( iError == KErrNone )
+ {
+ // set all relevant flags in tMsvEntry
+ TMsvEntry tEntry;
+ tEntry.iMtm = KUidMsgTypeMultimedia;
+ tEntry.iDate.UniversalTime();
+ SetFirstFlagsToNewEntry( tEntry );
+
+ iError = iServerEntry->CreateEntry( tEntry );
+ if ( iError == KErrNone )
+ {
+ iEntryUnderConstruction = tEntry.Id();
+ }
+ }
+ iServerEntry->SetEntry( KMsvNullIndexEntryId );
+ }
+ FallThrough();
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::DecodeResponseL
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::DecodeResponseL()
+ {
+ LOG( _L("CMmsMmboxList::DecodeResponseL"));
+ if( iEncodeBuffer->Size() < 1 )
+ {
+ iError = KErrCorrupt;
+ }
+ if( iError != KErrNone )
+ {
+ FallThrough();
+ return;
+ }
+
+ iMmsHeaders->Reset();
+ // Decode mmbox view confirmation
+ TInt numAtt = 0;
+ TInt dataStart = 0;
+ TInt startInBuffer = 0;
+ TInt length = iEncodeBuffer->Size();
+ iDecoder->DecodeHeadersL( *iEntryWrapper,
+ *iMmsHeaders,
+ *iEncodeBuffer,
+ startInBuffer,
+ length,
+ &numAtt,
+ &dataStart );
+
+ // The content type have to be mmbox view conf.
+ if ( iMmsHeaders->MessageType() != KMmsMessageTypeMboxViewConf )
+ {
+ // the content type is not correct. Don't save the headers
+ if ( iMmsHeaders->MessageType() == KMmsMessageTypeMSendConf &&
+ iMmsHeaders->ResponseStatus() == KMmsErrorUnsupportedMessage )
+ {
+ iError = KErrNotSupported;
+ }
+ else
+ {
+ iError = KErrCorrupt;
+ }
+ }
+
+ if ( iError == KErrNone )
+ {
+ if ( iOldQuotaEntryId != KMsvNullIndexEntryId )
+ {
+ // We must make the entry read only again
+ iError = iServerEntry->SetEntry( iOldQuotaEntryId );
+ if ( iError == KErrNone )
+ {
+ TMsvEntry tEntry = iServerEntry->Entry();
+ tEntry.SetReadOnly( EFalse );
+ iServerEntry->ChangeEntry( tEntry );
+ }
+ iServerEntry->SetEntry( KMsvNullIndexEntryId );
+ }
+ iError = iEntryWrapper->SetCurrentEntry( iEntryUnderConstruction );
+ }
+
+ // save the mmbox view confirmation headers,
+ // as the decode does not save them
+ if ( iError == KErrNone )
+ {
+ iError = iEntryWrapper->StoreMmsHeadersL( *iMmsHeaders, NULL );
+ }
+
+ // decode rest of the PDUs if we have any.
+ TInt start = dataStart; // start of multipart data.
+ for ( TInt i = 0; i < numAtt && iError == KErrNone; i++ )
+ {
+ length = iEncodeBuffer->Size() - start;
+ // We extract next data part, but we don't use the mime headers that would be returned
+ iDecoder->ExtractNextDataPartL( *iEncodeBuffer,
+ start, // start of next data part
+ dataStart, // start of actual data
+ length ); // length of data
+
+ // Create a new entry for the mmbox description PDU
+ iError = iServerEntry->SetEntry( iMmboxFolder );
+ TMsvEntry descEntry;
+ if ( iError == KErrNone )
+ {
+ // set all relevant flags in tMsvEntry
+ descEntry.iMtm = KUidMsgMMSNotification;
+ SetFirstFlagsToNewEntry( descEntry );
+ iError = iServerEntry->CreateEntry( descEntry );
+ }
+
+ if ( iError == KErrNone )
+ {
+ // Decode description PDU
+ iMmsHeaders->Reset();
+ TInt attaNum = 0;
+ TInt attaDataStart = 0;
+ iDecoder->DecodeHeadersL( *iEntryWrapper,
+ *iMmsHeaders,
+ *iEncodeBuffer,
+ dataStart,
+ length,
+ &attaNum,
+ &attaDataStart );
+
+ iError = iEntryWrapper->SetCurrentEntry( descEntry.Id() );
+ }
+
+ // Checking the content type
+ if( iError == KErrNone )
+ {
+ // The content type has to be mmbox view description.
+ if( iMmsHeaders->MessageType() != KMmsMessageTypeMBoxDescr )
+ {
+ // Content type is not correct.
+ iError = KErrCorrupt;
+ LOG( _L("ERROR: Wrong content type"));
+ }
+ else
+ {
+ // Mark mmbox notification specific flags
+ // Mark as notification. This information is important for UI.
+ descEntry.iMtmData1 = KMmsMessageMNotificationInd;
+ descEntry.iMtmData2 = KMmsStoredInMMBox;
+ descEntry.iMtmData2 |= KMmsNotifyResponseSent;
+ }
+ }
+ if( iError == KErrNone )
+ {
+ // Set subject etc. to the notification entry
+ iError = StoreContentToNotificationEntryL( descEntry );
+ }
+ if ( iError == KErrNone )
+ {
+ // Save the headers as the decoder does not save them
+ iError = iEntryWrapper->StoreMmsHeadersL( *iMmsHeaders, NULL );
+ }
+ if ( iError == KErrNone )
+ {
+ // add new notification to iSelection list
+ iSelection->AppendL( descEntry.Id() );
+ }
+ } // for loop
+
+ iServerEntry->SetEntry( KMsvNullIndexEntryId );
+ FallThrough();
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::MoveEntryL
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::MoveEntryL()
+ {
+ LOG( _L("CMmsMmboxList::MoveEntryL"));
+ if ( iError != KErrNone )
+ {
+ FallThrough();
+ return;
+ }
+
+ // Delete old notifications
+ iError = RemoveOldNotifications();
+
+ // make new notifications visible
+ if ( iError == KErrNone )
+ {
+ iError = MakeNewNotificationsVisible();
+ }
+
+ // Finalize the new quota entry - if we created a new one and did not
+ // just reuse the old entry
+
+ TMsvEntry tEntry;
+
+ if ( iError == KErrNone || iOldQuotaEntryId == KMsvNullIndexEntryId )
+ {
+ iError = iServerEntry->SetEntry( iEntryUnderConstruction );
+ if ( iError == KErrNone )
+ {
+ tEntry = iServerEntry->Entry();
+ SetFlagsToEntryBeingFinalized( tEntry );
+ // update the time the quota entry was updated
+ tEntry.iDate.UniversalTime();
+ tEntry.iError = KErrNone; // clear possible old error
+
+ // Quota entry must not be visible.
+ // Otherwise the shows the number of notifications in mmboxfolder wrong.
+ tEntry.SetVisible( EFalse );
+ iError = iServerEntry->ChangeEntry( tEntry );
+ if ( iError == KErrNone )
+ {
+ iEntryUnderConstruction = KMsvNullIndexEntryId;
+ }
+ }
+ iServerEntry->SetEntry( KMsvNullIndexEntryId );
+ }
+
+ FallThrough();
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::FinalizeL()
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::FinalizeL()
+ {
+ LOG( _L("CMmsMmboxList::FinalizeL"));
+
+ TInt error;
+
+ // In case something has failed. Delete the new quota entry
+ // - but only in case it was just created
+ if ( iError != KErrNone )
+ {
+ error = iServerEntry->SetEntry( iMmboxFolder );
+ if ( error == KErrNone )
+ {
+ // we can only delete, if we can set context to parent
+ if ( iOldQuotaEntryId == KMsvNullIndexEntryId )
+ {
+ iServerEntry->DeleteEntry( iEntryUnderConstruction );
+ }
+
+ // if iSelection contains now notifications, the notifications
+ // are not ready yet. They can be destroyed.
+ if ( iSelection->Count() > 0 )
+ {
+ iServerEntry->DeleteEntries( *iSelection );
+ }
+ }
+ iEntryUnderConstruction = KMsvNullIndexEntryId;
+
+ iSelection->Reset();
+
+ // we don't care if the iOldNotifications is empty or not.
+ // If the old notifications are not deleted, they can stay
+ // in the mmbox folder. The array is reseted anyway.
+ iOldNotifications->Reset();
+
+ // set iError to old quota entry, if the entry exists
+ if ( iOldQuotaEntryId != KMsvNullIndexEntryId )
+ {
+
+ LOG( _L("- old quota entry exists"));
+
+ error = iServerEntry->SetEntry( iOldQuotaEntryId );
+ if ( error == KErrNone )
+ {
+ TMsvEntry tEntry = iServerEntry->Entry();
+ tEntry.iError = iError;
+
+ error = iServerEntry->ChangeEntry( tEntry );
+ if ( error == KErrNone )
+ {
+ LOG( _L("- iError saved to old quota entry."));
+ }
+ }
+ }
+
+ iServerEntry->SetEntry( KMsvNullIndexEntryId );
+ }
+
+ CMmsBaseOperation::FinalizeL();
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::SetFirstFlagsToNewEntry
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::SetFirstFlagsToNewEntry( TMsvEntry& aEntry )
+ {
+ aEntry.iType = KUidMsvMessageEntry;
+ aEntry.iServiceId = iService;
+ aEntry.SetVisible( EFalse );
+ aEntry.SetComplete( EFalse );
+ aEntry.SetInPreparation( ETrue );
+ aEntry.SetReadOnly( EFalse );
+ aEntry.SetNew( ETrue );
+ aEntry.SetUnread( ETrue );
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::SetFlagsToEntryBeingFinalized
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::SetFlagsToEntryBeingFinalized( TMsvEntry& aEntry )
+ {
+ aEntry.iMtmData1 |= KMmsMessageMobileTerminated;
+ aEntry.SetReadOnly( ETrue );
+ aEntry.SetVisible( ETrue );
+ aEntry.SetInPreparation( EFalse );
+ aEntry.SetComplete( ETrue );
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::RemoveOldNotifications
+//
+// ---------------------------------------------------------
+//
+TInt CMmsMmboxList::RemoveOldNotifications()
+ {
+ LOG( _L("CMmsMmboxList::RemoveOldNotifications"));
+
+ TInt error = iServerEntry->SetEntry( iMmboxFolder );
+ if ( error == KErrNone && iOldNotifications->Count() > 0 )
+ {
+ error = iServerEntry->DeleteEntries( *iOldNotifications );
+ if ( error == KErrNone )
+ {
+ iOldNotifications->Reset();
+ }
+ }
+
+ iServerEntry->SetEntry( KMsvNullIndexEntryId );
+ return error;
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::MakeNewNotificationsVisible
+//
+// ---------------------------------------------------------
+//
+TInt CMmsMmboxList::MakeNewNotificationsVisible()
+ {
+ LOG( _L("CMmsMmboxList::MakeNewNotificationsVisible"));
+ TInt count = iSelection->Count();
+ TInt error = KErrNone;
+ for ( TInt i = count - 1; i >=0 && error == KErrNone; i-- )
+ {
+ error = iServerEntry->SetEntry( iSelection->At( i ) );
+ if ( error == KErrNone )
+ {
+ TMsvEntry tEntry = iServerEntry->Entry();
+ SetFlagsToEntryBeingFinalized( tEntry );
+ error = iServerEntry->ChangeEntry( tEntry );
+ if ( error == KErrNone )
+ {
+ iSelection->Delete( i );
+ }
+ }
+ }
+ iServerEntry->SetEntry( KMsvNullIndexEntryId );
+ return error;
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::StoreContentToNotificationEntryL
+//
+// ---------------------------------------------------------
+//
+TInt CMmsMmboxList::StoreContentToNotificationEntryL( TMsvEntry aEntry )
+ {
+ LOG( _L("CMmsMmboxList::SetContentToNotificationL"));
+
+ // Expiry interval must be changed to absolute time,
+ // otherwise it makes no sense.
+ if ( iMmsHeaders->ExpiryDate() == 0 )
+ {
+ TTime time;
+ // handle expiry in universal time
+ time.UniversalTime();
+ time += TTimeIntervalSeconds( iMmsHeaders->ExpiryInterval() );
+ iMmsHeaders->SetExpiryDate(
+ ( time.MicroSecondsFrom( TTime( KMmsYear1970String ) ).Int64() ) / KMmsMillion );
+ }
+
+ // If the notifications does not contains the date value from the server,
+ // arrival time is set to notification.
+ // Otherwise the date from the server.
+
+ LOG( _L("Mark time"));
+
+ if ( iMmsHeaders->Date() == 0 )
+ {
+ aEntry.iDate.UniversalTime();
+ }
+ else
+ {
+ aEntry.iDate = ServerDate();
+ }
+
+ // Mark subject
+ if ( iMmsHeaders->Subject().Length() > 0 )
+ {
+ aEntry.iDescription.Set( iMmsHeaders->Subject() );
+ }
+
+ // Mark size of the notification
+ aEntry.iSize = iMmsHeaders->Size();
+
+ // Mark message class.
+ // Default is personal
+ if ( iMmsHeaders->MessageClass() == EMmsClassAdvertisement )
+ {
+ aEntry.iMtmData1 |= KMmsMessageAdvertisement;
+ }
+ else if (iMmsHeaders->MessageClass() == EMmsClassInformational )
+ {
+ aEntry.iMtmData1 |= KMmsMessageInformational;
+ }
+ else
+ {
+ // keep LINT happy
+ }
+
+ switch ( iMmsHeaders->MessagePriority() )
+ {
+ case KMmsPriorityNormal:
+ aEntry.SetPriority( EMsvMediumPriority );
+ break;
+ case KMmsPriorityLow:
+ aEntry.SetPriority( EMsvLowPriority );
+ break;
+ case KMmsPriorityHigh:
+ aEntry.SetPriority( EMsvHighPriority );
+ break;
+ default:
+ // if not defined default is normal
+ aEntry.SetPriority( EMsvMediumPriority );
+ break;
+ }
+
+ // mark sender
+ // If the sender is a phone number, add alias.
+ HBufC* buffer = HBufC::NewL( KMmsMaxDescription );
+ TPtr pBuffer = buffer->Des();
+
+ if ( TMmsGenUtils::GenerateDetails( iMmsHeaders->Sender(),
+ pBuffer, KMmsMaxDescription, iFs ) == KErrNone )
+ {
+ aEntry.iDetails.Set( pBuffer );
+ }
+ else
+ {
+ // We come here only if there was an fatal error in GenerateDetails.
+ // Even if we don't find the alias, we have something in the string
+ aEntry.iDetails.Set( iMmsHeaders->Sender() );
+ }
+
+ TInt error = iServerEntry->ChangeEntry( aEntry );
+ delete buffer;
+ buffer = NULL;
+ // iServerEntry is not set to KMsvNullIndexEntryId,
+ // as the next function demands that the iServerEntry is set to aEntry.
+ return error;
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::OldQuotaEntryL
+//
+// ---------------------------------------------------------
+//
+TMsvId CMmsMmboxList::OldQuotaEntryL()
+ {
+ LOG( _L("CMmsMmboxList::OldQuotaEntryL"));
+
+ // iServerEntry context must be set to iMmboxFolder
+ // before calling this function
+ TMsvId oldQuotaEntryId = KMsvNullIndexEntryId;
+
+ // show invisible entries.
+ TMsvSelectionOrdering ordering =
+ TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByNone, ETrue );
+ iServerEntry->SetSort( ordering );
+
+ CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
+ CleanupStack::PushL( selection );
+ TInt error = iServerEntry->GetChildrenWithMtm( KUidMsgTypeMultimedia, *selection );
+ TInt count = selection->Count();
+
+ LOG2( _L("- %d mms entries"), count );
+
+ if( error == KErrNone && count > 0 )
+ {
+ for( TInt i = selection->Count() - 1 ; i >= 0; i-- )
+ {
+
+ LOG2( _L("- processing at selection[%d]"), i );
+
+ TMsvId entryId = selection->At( i );
+ error = iServerEntry->SetEntry( entryId );
+ if ( error == KErrNone )
+ {
+ TMsvEntry entry = iServerEntry->Entry();
+ // old quota entry is complete, but not visible
+ if ( ( !entry.Visible() ) && entry.Complete() )
+ {
+ oldQuotaEntryId = entryId;
+ i = -1;
+
+ LOG( _L("- Old quota found"));
+
+ }
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( selection );
+
+ return oldQuotaEntryId;
+ }
+
+// ---------------------------------------------------------
+// CMmsMmboxList::ServerDate
+//
+// ---------------------------------------------------------
+//
+TTime CMmsMmboxList::ServerDate()
+ {
+
+ LOG( _L("CMmsMmboxList::ServerDate"));
+
+ TInt64 inSeconds = iMmsHeaders->Date();
+
+ TTime y1970( K1970 );
+
+ // 1970 presented as microseconds after January 1st, 0 AD nominal Gregorian.
+ TInt64 ms1970 = y1970.Int64();
+
+ // If not defined in message headers return 0
+ if ( inSeconds == 0 )
+ {
+ return TTime(0);
+ }
+
+ // microseconds after 1.1. 1970
+ TInt64 msAfter1970;
+ msAfter1970 = KMmsMillion * inSeconds;
+
+ return TTime( ms1970 + msAfter1970 );
+ }
+
+// ---------------------------------------------------------
+//
+// ---------------------------------------------------------
+//
+void CMmsMmboxList::LocalModeFetchL()
+ {
+// This functionality has no meaning in hardware
+// It is available in WINS to help module testing
+
+#ifdef __WINS__
+ RFs fs; // We need a separate session to be able to set the session path
+ RFile file; // local mode message
+ iError = fs.Connect();
+ if ( iError != KErrNone )
+ {
+ FallThrough();
+ }
+
+ CleanupClosePushL( fs );
+
+ CDir* fileList = NULL;
+
+ TEntry* entry = new( ELeave ) TEntry; // allocated from heap to save stack space
+ CleanupStack::PushL( entry );
+ HBufC* filename = HBufC::NewL( KMaxFileName );
+ CleanupStack::PushL( filename );
+ TPtr fileNamePtr = filename->Des();
+ // use different directory in order to be able to simulate
+ // both mmbox view and fetching the corresponding messages
+ fileNamePtr.Copy( KMmsMMBoxDirectory );
+ TInt err = fs.SetSessionPath( fileNamePtr );
+ err = fs.Entry( fileNamePtr, *entry );
+ TInt count = 0;
+ if ( err == KErrNone )
+ {
+ TFindFile* finder = new( ELeave ) TFindFile( fs ); // allocated from heap to save stack space
+ CleanupStack::PushL( finder );
+ _LIT( KWild, "*" );
+
+ err = finder->FindWildByPath( KWild, &fileNamePtr, fileList );
+ CleanupStack::PopAndDestroy( finder );
+
+ if ( fileList )
+ {
+ CleanupStack::PushL( fileList );
+ count = fileList->Count();
+ }
+ }
+
+
+ if ( count > 0 )
+ {
+ TParse parse;
+ parse.Set( ( ( *fileList )[0] ).iName, &fileNamePtr, NULL );
+ fileNamePtr.Copy( parse.FullName() );
+ TInt size = fs.Entry( parse.FullName(), *entry );
+ size = entry->iSize;
+
+ iError = file.Open( fs, fileNamePtr, EFileShareExclusive );
+ if ( iError == KErrNone )
+ {
+ iEncodeBuffer->Reset();
+ TRAP(iError, iEncodeBuffer->ResizeL( size ));
+ if ( iError == KErrNone )
+ {
+ TPtr8 pos = iEncodeBuffer->Ptr( 0 );
+ file.Read( 0, pos, size );
+ }
+ file.Close();
+ // delete the file after the view has been fetched
+ fs.Delete( fileNamePtr );
+ }
+ }
+
+ if ( fileList )
+ {
+ CleanupStack::PopAndDestroy( fileList );
+ }
+
+ CleanupStack::PopAndDestroy( filename );
+ CleanupStack::PopAndDestroy( entry );
+ CleanupStack::PopAndDestroy( &fs ); // close fs
+#endif
+
+ FallThrough();
+ }
+
+
+// ================= OTHER EXPORTED FUNCTIONS ==============
+
+// End of File