filemanager/bkupengine/src/CMMCScBkupTransferWriteRequest.cpp
changeset 0 6a9f87576119
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/filemanager/bkupengine/src/CMMCScBkupTransferWriteRequest.cpp	Mon Jan 18 20:09:41 2010 +0200
@@ -0,0 +1,491 @@
+/*
+* Copyright (c) 2005 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: CMMCScBkupWriteDataTransferRequestBase implementation
+*
+*
+*/
+
+#include "CMMCScBkupTransferWriteRequest.h"
+
+// User includes
+#include "MMCScBkupLogger.h"
+#include "MMMCScBkupDriver.h"
+#include "CMMCScBkupArchive.h"
+#include "MMCScBkupSBEUtils.h"
+#include "RMMCScBkupProgressSizer.h"
+#include "MMMCScBkupProgressObserver.h"
+#include "MMMCScBkupArchiveDataInterface.h"
+#include "CMMCScBkupDriveAndOperationTypeManager.h"
+#include <pathinfo.h>
+
+
+
+#ifdef __MMCSCBKUP_DATA_LOGGING_ENABLED__
+
+static void __DebugDump( const TDesC& aFmt, const TUint8* aAddress, const TUint8* aDisplayStartAddress, TInt aLength, TInt aMaxLength)
+    {
+    const TInt maxLen = aMaxLength;
+    TInt len = aLength;
+    const TUint8* pDataAddr = aAddress;
+
+    TBuf<81> out;
+    TBuf<20> ascii;
+    TInt offset = 0;
+    const TUint8* a = pDataAddr;
+    const TUint8* displayAddress = aDisplayStartAddress;
+    //
+    while(len>0)
+        {
+        out.Zero();
+        ascii.Zero();
+        out.AppendNumFixedWidth((TUint) displayAddress, EHex, 8);
+        out.Append(_L(": "));
+
+        TUint b;
+        for (b=0; b<16; b++)
+            {
+            TUint8 c = ' ';
+            if  ((pDataAddr + offset + b) < pDataAddr + maxLen)
+                {
+                c = *(pDataAddr + offset + b);
+                out.AppendNumFixedWidth(c, EHex, 2);
+                }
+            else
+                {
+                out.Append(_L("  "));
+                }
+            out.Append(' ');
+            if (c<=0x20 || c>=0x7f || c=='%')
+                c=0x2e;
+            ascii.Append(TChar(c));
+            }
+        out.Append(ascii);
+        out.ZeroTerminate();
+
+        RDebug::Print(aFmt, &out);
+
+        displayAddress += 16;
+        a += 16;
+        offset += 16;
+        len -= 16;
+        }
+    }
+
+#endif
+
+
+
+
+
+
+// ========================= MEMBER FUNCTIONS ================================
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::CMMCScBkupWriteDataTransferRequestBase()
+// 
+// C++ constructor.
+// ---------------------------------------------------------------------------
+CMMCScBkupWriteDataTransferRequestBase::CMMCScBkupWriteDataTransferRequestBase( 
+                                                MMMCScBkupDriver& aDriver, 
+                                                MMMCScBkupIndexHandler& aIndexHandler,
+                                                TMMCScBkupOwnerDataType aElementType,
+                                                TSBDerivedType aExpectedTransferType,
+                                                TInt aPriority )
+
+:   CMMCScBkupTransferRequestBase( aDriver, aElementType, aPriority ), 
+    iIndexHandler( aIndexHandler ),
+    iExpectedTransferType( aExpectedTransferType )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::~CMMCScBkupWriteDataTransferRequestBase()
+// 
+// Destructor.
+// ---------------------------------------------------------------------------
+CMMCScBkupWriteDataTransferRequestBase::~CMMCScBkupWriteDataTransferRequestBase()
+    {
+    delete iTransferType;
+    if  ( iStreamIsOpen )
+        {
+        iStream.Close();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::RequestL()
+// 
+// 
+// ---------------------------------------------------------------------------
+void CMMCScBkupWriteDataTransferRequestBase::RequestL( CMMCScBkupDataOwnerInfo& aOwner, TRequestStatus& aObserver, const CMMCScBkupDriveAndOperationTypeManager& aDriveAndOperations )
+    {
+#ifdef __MMCSCBKUPLOGGING_ENABLED__
+    if ( ElementType() == EMMCScBkupOwnerDataTypeJavaData )
+        {
+        HBufC* hash = MMCScBkupSBEUtils::JavaHashFromGenericLC( aOwner.Owner().Identifier() );
+        __LOG2("CMMCScBkupWriteDataTransferRequestBase::RequestL() - START - reading data from SBE for JavaHash: %S, ElementType: %S", hash, &MMCScBkupLogger::DataType( ElementType() ));
+        CleanupStack::PopAndDestroy( hash );
+        }
+    else
+        {
+        __LOG2("CMMCScBkupWriteDataTransferRequestBase::RequestL() - START - reading data from SBE for DO: 0x%08x, ElementType: %S", aOwner.SecureId().iId, &MMCScBkupLogger::DataType( ElementType() ));
+        }
+#endif
+
+    iDriveAndOperations = &aDriveAndOperations;
+    CMMCScBkupTransferRequestBase::RequestL( aOwner, aObserver );
+    //
+    iDriveFilter.Reset();
+    iDriveFilter.SetPrimaryDriveFilter( iDriveAndOperations->DriveList() );
+    iDriveFilter.SetSecondaryDriveFilter( aOwner.Owner().DriveList() );
+    
+    // Set us going
+    SetState( ETransferData );
+    CompleteSelf();
+    __LOG("CMMCScBkupWriteDataTransferRequestBase::RequestL() - END");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL()
+// 
+// 
+// ---------------------------------------------------------------------------
+TBool CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL()
+    {
+    MMMCScBkupDriver& driver = Driver();
+    MMMCScBkupArchiveDataInterface& archiveDataInterface = driver.DrvADI();
+
+    // Get a handle to the received data
+    TBool finished = EFalse;
+    CSBGenericTransferType* receivedTransferInfo = NULL;
+    const TPtrC8& pData = driver.DrvSecureBackupClient().TransferDataInfoL( receivedTransferInfo, finished );
+    iAdditionalTransferRequired = !finished;
+    
+    __LOG4("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - received: %d bytes from SBE for SID: 0x%08x, Drive: %c:, ElementType: %S", pData.Length(), DataOwner().SecureId().iId, 'A' + CurrentDrive(), &MMCScBkupLogger::DataType( ElementType() ) );
+
+    // Validate the data
+    CleanupStack::PushL( receivedTransferInfo );
+    ValidateTransferInfoL( receivedTransferInfo );
+    CleanupStack::PopAndDestroy( receivedTransferInfo );
+
+    // If we've never written any registration data before, then we must
+    // request a write stream at the current archive write pos...
+    if  ( pData.Length() && !iStreamIsOpen )
+        {
+        __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - stream isnt open - opening now..." );
+
+        iStream = archiveDataInterface.ADIWriteStreamUncompressedLC();
+        CleanupStack::Pop(); // iWriteStream - gets closed in dtor in case of leave
+        iStreamIsOpen = ETrue;
+        }
+
+    // Write the data - assumes stream already open if this is not the
+    // first time that we've received data for this drive...
+    //
+    // We don't use the externalisation operators, as we want to write
+    // only the data (no leading byte count etc).
+    if  ( pData.Length() )
+        {
+        __LOG1("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - got %d bytes of data...", pData.Length() );
+        
+#ifdef __MMCSCBKUP_DATA_LOGGING_ENABLED__
+        _LIT(KDumpFormat, "SBEData - %S - ");
+        __DebugDump( KDumpFormat, pData.Ptr(), pData.Ptr(), pData.Length(), pData.Length() );
+#endif
+
+        // Write the data to the stream
+        __LOG1("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - writing %d bytes to stream...", pData.Length() );
+        iStream.WriteL(pData);
+        __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - data written OK");
+
+        // Update our stats. We overwrite any earlier estimate from the SBE
+        // with the actual values that we ultimately end up writing to the
+        // archive. This allows us to provide a more accurate restore progress
+        // experience.
+        DataTransferred( pData.Length() );
+
+#ifdef DEBUGGING_DATA_TRANSFER
+        TRAP_IGNORE( DumpTransferDataL( archiveDataInterface.ADIFsSession(), pData ) );
+#endif
+        }
+
+    // If we've received everything we can commit & close the stream
+    if  ( finished )
+        {
+        __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - finished...");
+
+        // Implicitly, if the stream is open then we have written some
+        // data to the archive. Therefore we only add an index record
+        // when the stream is open.
+        if  ( iStreamIsOpen )
+            {
+            __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - Committing stream...");
+            iStream.CommitL();
+
+            __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - Closing stream...");
+            iStream.Close();
+            iStreamIsOpen = EFalse;
+
+            // Must store the position, as we're going to also write an index at
+            // the end of this whole process.
+            __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - Adding index record...");
+            CMMCScBkupArchiveFooter& footer = driver.DrvArchive().Footer();
+            const TMMCScBkupArchiveVector& info = archiveDataInterface.ADICurrentArchiveVectorInfo();
+            
+            // If we actually wrote something to the archive, then add an index record.
+            if  (info.Length())
+                {
+                iIndexHandler.AddIndexRecordL( footer, DataOwner(), info, CurrentDrive() );
+                }
+            }
+        }
+
+    // Not yet supporting chunked transfer
+    __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - END");
+    return EFalse;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL()
+// 
+// 
+// ---------------------------------------------------------------------------
+void CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL()
+    {
+    // If we must make a repeat transfer request, then we don't yet
+    // move to the next drive.
+    if  ( iAdditionalTransferRequired )
+        {
+        // Must ask for more of the same data, so no need
+        // to rebuild transfer info - we just reuse it
+        RequestDataTransferL();
+        }
+    else
+        {
+        // Can move to the next drive
+        TDriveNumber drive = EDriveA;
+        const TBool driveAvailable = iDriveFilter.NextValidDrive( drive );
+        __LOG1("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - current drive: %c", drive + 'A');
+        __LOG1("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - driveAvailable: %d", driveAvailable);
+
+        if  ( driveAvailable )
+            {
+            const TBool dataTransferAllowableForDrive = iDriveAndOperations->IsDataTypeAllowedToAccessDrive( drive, ElementType() );
+            __LOG1("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - dataTransferAllowableForDrive: %d", dataTransferAllowableForDrive);
+
+            if  ( dataTransferAllowableForDrive )
+                {
+                __LOG1("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - making transfer request for drive: %c", drive + 'A');
+
+                // Update the current drive
+                SetCurrentDrive( drive );
+
+                // Make virtual function call to make transfer object
+                const CSBGenericDataType& generic = DataOwner().Owner().Identifier();
+                CSBGenericTransferType* transferType = PrepareTransferTypeL( generic, CurrentDrive(), DataOwner().Version() );
+                delete iTransferType;
+                iTransferType = transferType;
+
+                // We have a transfer packet, so now request data
+                RequestDataTransferL();
+                }
+            else
+                {
+                // Couldn't process this drive, let's try to find another drive.
+                // This means we don't change state this time.
+                __LOG("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - not allowed to back up this drive... trying next one...");
+                CompleteSelf( KErrNone );
+                }
+            }
+        else
+            {
+            // No more drives left, we've finished!
+            __LOG("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - no more drives to process - we're finished!");
+            SetState( EFinished );
+            CompleteSelf();
+            }
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::CurrentDrive()
+// 
+// 
+// ---------------------------------------------------------------------------
+TDriveNumber CMMCScBkupWriteDataTransferRequestBase::CurrentDrive() const
+    {
+    return iCurrentDrive;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::ValidateTransferInfoL()
+// 
+// 
+// ---------------------------------------------------------------------------
+void CMMCScBkupWriteDataTransferRequestBase::ValidateTransferInfoL( CSBGenericTransferType* aInfo )
+    {
+    if  ( !aInfo )
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    // Check the type is as expected
+    const TSBDerivedType type = aInfo->DerivedTypeL();
+    if  ( type != iExpectedTransferType )
+        {
+        __LOG2("CMMCScBkupWriteDataTransferRequestBase::ValidateTransferInfoL() - ERROR - types dont match! type: %d vs expected: %d", type, iExpectedTransferType );
+        User::Leave( KErrNotSupported );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::RequestDataTransferL()
+// 
+// 
+// ---------------------------------------------------------------------------
+void CMMCScBkupWriteDataTransferRequestBase::RequestDataTransferL()
+    {
+    __LOG3("CMMCScBkupWriteDataTransferRequestBase::RequestDataTransferL() - requesting data from SBE for SID: 0x%08x, Drive: %c:, ElementType: %S", DataOwner().SecureId().iId, 'A' + CurrentDrive(), &MMCScBkupLogger::DataType( ElementType() ) );
+
+    CSBEClient& sbeClient = Driver().DrvSecureBackupClient();
+    sbeClient.RequestDataL( *iTransferType, iStatus );
+    SetActive();
+    SetState( EProcessData );
+
+    // Report the progress
+    RMMCScBkupProgressSizer progressSizer( Driver().DrvParamsBase().DriveAndOperations() );
+    progressSizer.BackupReportFixedProgressForOpL( Driver().DrvProgressHandler(), ElementType() );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::RunError()
+// 
+// 
+// ---------------------------------------------------------------------------
+TInt CMMCScBkupWriteDataTransferRequestBase::RunError( TInt aError )
+    {
+#if defined(__MMCSCBKUPLOGGING_ENABLED__)
+    const TSecureId sid = DataOwner().SecureId();
+    __LOGFILE3("CMMCScBkupWriteDataTransferRequestBase::RunError() - **** - aError: %d, sid: 0x%08x, drive: %c", aError, sid.iId, 'A' + CurrentDrive() );
+#endif
+
+    TInt ret = KErrNone;
+    
+    // Make sure we close the stream (if we had it open)
+    if  ( iStreamIsOpen )
+        {
+        iStream.Close();
+        iStreamIsOpen = EFalse;
+        }
+
+    // Now notify the observer or silently try again (depends on type of error)
+    if  ( aError == KErrNotFound )
+        {
+        __LOGFILE1("CMMCScBkupWriteDataTransferRequestBase::RunError() - **** - non fatal error (%d) so trying the next drive...", aError);
+
+        // Try the next drive - if none is available, it will complete the
+        // observer as if nothing went wrong.
+        iAdditionalTransferRequired = EFalse;
+        SetState( ETransferData );
+        CompleteSelf();
+        }
+    else
+        {
+        __LOGFILE1("CMMCScBkupWriteDataTransferRequestBase::RunError() - **** - FATAL ERROR (%d)", aError);
+        ret = CMMCScBkupTransferRequestBase::RunError( aError );
+        }
+    //
+    return ret;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMMCScBkupWriteDataTransferRequestBase::DumpTransferDataL()
+// 
+// 
+// ---------------------------------------------------------------------------
+#ifdef DEBUGGING_DATA_TRANSFER
+void CMMCScBkupWriteDataTransferRequestBase::DumpTransferDataL( RFs& aFsSession, const TDesC8& aData ) const
+    {
+    TPtrC subDirectory( KNullDesC );
+    //
+    switch( ElementType() )
+        {
+    case EMMCScBkupOwnerDataTypeJavaData:
+        subDirectory.Set(KMMCScBkupDataTransferDebuggingPathDataJava);
+        break;
+    case EMMCScBkupOwnerDataTypeSystemData:
+        subDirectory.Set(KMMCScBkupDataTransferDebuggingPathDataSystem);
+        break;
+    case EMMCScBkupOwnerDataTypePassiveData:
+        subDirectory.Set(KMMCScBkupDataTransferDebuggingPathDataPassive);
+        break;
+    case EMMCScBkupOwnerDataTypeActiveData:
+        subDirectory.Set(KMMCScBkupDataTransferDebuggingPathDataActive);
+        break;
+    default:
+        User::Leave( KErrNotSupported );
+        break;
+        }
+    //
+    const TSecureId secureId = DataOwner().SecureId();
+    _LIT(KMMCScBkupFormatDes, "%S%S");
+    TFileName transferDumpFileName;
+    const TDesC& path = PathInfo::MemoryCardRootPath();
+    transferDumpFileName.Format(KMMCScBkupFormatDes, &path, &KMMCScBkupDataTransferDebuggingPathRoot);
+
+    transferDumpFileName.Append( subDirectory );
+    transferDumpFileName.Append( KMMCScBkupDataTransferDebuggingPathDataBackup );
+    transferDumpFileName.AppendFormat( KMMCScBkupDataTransferDebuggingFileName, secureId.iId, 'a' + CurrentDrive() );
+    //
+    RFile64 file;
+    TInt error = KErrNone;
+    TEntry entry;
+    if  ( aFsSession.Entry( transferDumpFileName, entry ) == KErrNone )
+        {
+        // Already exists - append data
+        error = file.Open( aFsSession, transferDumpFileName, EFileWrite | EFileStream | EFileShareExclusive );
+        }
+    else
+        {
+        entry.iSize = 0;
+        error = file.Create( aFsSession, transferDumpFileName, EFileWrite | EFileStream | EFileShareExclusive );
+        }
+    //
+    User::LeaveIfError( error );
+    CleanupClosePushL( file );
+    error = file.Write( entry.iSize, aData );
+    CleanupStack::PopAndDestroy( &file );
+    }
+#endif
+
+
+
+
+
+
+
+
+
+
+
+