fotaapplication/fotaserver/FotaServer/src/DevEncController.cpp
changeset 0 b497e44ab2fc
child 13 86979fe66c4c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fotaapplication/fotaserver/FotaServer/src/DevEncController.cpp	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,482 @@
+/*
+* Copyright (c) 2009 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:   CDevEncController definitions Part of ES System Application
+*
+*/
+
+#include <apgcli.h> // for RApaLsSession
+#include <apacmdln.h> // for CApaCommandLine
+#include <centralrepository.h>
+#include <featmgr.h> // for checking DE feature
+#include "DevEncController.h"
+#include "FotaServer.h"
+#include "FotaSrvDebug.h"
+#include "DevEncSession.h"
+#include <DevEncEngineConstants.h>
+#include "DevEncProgressObserver.h"
+#include <fotaserver.rsg>
+#include <DevEncProtectedPSKey.h>
+#define __LEAVE_IF_ERROR(x) if(KErrNone!=x) {FLOG(_L("LEAVE in %s: %d"), __FILE__, __LINE__); User::Leave(x); }
+
+// ================= MEMBER FUNCTIONS =======================
+//
+// ----------------------------------------------------------
+// CDevEncController::NewL
+// Instancies CDevEncController object
+// ----------------------------------------------------------
+//
+CDevEncController* CDevEncController::NewL(CFotaServer* aCallback )
+    {
+    FLOG(_L("CDevEncController::NewL >>"));
+
+    CDevEncController* self = CDevEncController::NewLC(aCallback);
+    CleanupStack::Pop();
+
+    FLOG(_L("CDevEncController::NewL <<"));
+    return self;
+    }
+
+
+// ----------------------------------------------------------
+// CDevEncController::NewL
+// Instancies CDevEncController object
+// ----------------------------------------------------------
+//
+CDevEncController* CDevEncController::NewLC(CFotaServer* aCallback )
+    {
+    FLOG(_L("CDevEncController::NewLC >>"));
+
+    CDevEncController* self = new ( ELeave ) CDevEncController(aCallback);
+    CleanupStack::PushL ( self );
+    self->ConstructL();
+
+    FLOG(_L("CDevEncController::NewC <<"));
+    return self;
+    }
+
+// ----------------------------------------------------------
+// CDevEncController::ConstructL()
+// Initializes data objects
+// ----------------------------------------------------------
+//
+void CDevEncController::ConstructL()
+    {
+    FLOG(_L("CDevEncController::ConstructL >>"));
+
+    if (!IsDeviceEncryptionSupportedL())
+        {
+        FLOG(_L("Device doesn't support encryption!!"));
+        User::Leave(KErrNotSupported);
+        }
+    FLOG(_L("CDevEncController::ConstructL <<"));
+    }
+
+
+TBool CDevEncController::IsDeviceEncryptionSupportedL()
+    {
+    FLOG(_L("CDevEncController::IsDeviceEncryptionSupportedL >>"));
+
+    TBool ret(EFalse);
+
+    FeatureManager::InitializeLibL();
+    ret = FeatureManager::FeatureSupported( KFeatureIdFfDeviceEncryptionFeature);
+    FeatureManager::UnInitializeLib();
+
+    FLOG(_L("CDevEncController::IsDeviceEncryptionSupportedL, ret = %d <<"), ret);
+    return ret;
+    }
+// ----------------------------------------------------------
+// CDevEncController::CDevEncController()
+// Constructor
+// ----------------------------------------------------------
+//
+CDevEncController::CDevEncController(CFotaServer* aCallback): iCallback (aCallback),
+iEncMemorySession(NULL),
+iDevEncObserver (NULL),
+iDevEncOperation(EIdle)
+        {
+
+        }
+
+// ----------------------------------------------------------
+// CDevEncController::CDevEncController()
+// Destructor
+// ----------------------------------------------------------
+//
+CDevEncController::~CDevEncController()
+    {
+    FLOG(_L("CDevEncController::~CDevEncController >>"));
+
+    if (iEncMemorySession)
+        {
+        iEncMemorySession->Close();
+        delete iEncMemorySession;
+        iEncMemorySession = NULL;
+        }
+
+    if (iDevEncObserver)
+        {
+        delete iDevEncObserver;
+        iDevEncObserver = NULL;
+        }
+
+    FLOG(_L("CDevEncController::~CDevEncController <<"));
+    }
+
+TBool CDevEncController::NeedToDecryptL(const TDriveNumber &aDrive)
+    {
+    FLOG(_L("CDevEncController::NeedToDecryptL, drive = %d >>"), (TInt) aDrive);
+
+    TBool ret (EFalse);
+    TInt err (KErrNone);
+    TInt status (KErrNone);
+
+    TInt deoperation (EOpIdle);  
+
+    RProperty::Get(KDevEncProtectedUid, KDevEncOperationKey, deoperation );
+
+    if (deoperation != EOpIdle)
+        {
+        FLOG(_L("Some disk operation is ongoing. Hence Fota is not possible."));
+        User::Leave(KErrNotReady);
+        }
+
+    if (!iEncMemorySession)
+        iEncMemorySession = new (ELeave) CDevEncSession( aDrive );
+
+    err = iEncMemorySession->Connect();
+    if (err != KErrNone)
+        {
+        FLOG(_L("Error in connecting to devencdisk session = %d"), err);
+        User::Leave(err);
+        }
+
+    err = iEncMemorySession->DiskStatus(status);
+
+    if (!err && (status == EEncrypted || status == EEncrypting))
+        {
+        FLOG(_L("Drive %d is encrypted"), (TInt) aDrive);
+        ret = ETrue;
+        }
+    else
+        {
+        CRepository *centrep = CRepository::NewL( KCRUidFotaServer );
+        err = centrep->Set(  KDriveToEncrypt, KErrNotFound );
+        delete centrep; centrep = NULL;
+        }
+
+#if defined(__WINS__)
+    ret = ETrue;
+#endif
+
+    iEncMemorySession->Close();
+    delete iEncMemorySession; iEncMemorySession = NULL;
+
+    FLOG(_L("CDevEncController::NeedToDecrypt, ret = %d <<"), ret);
+    return ret;
+    }
+
+void CDevEncController::DoStartDecryptionL(const TDriveNumber &aDrive)
+    {
+    FLOG(_L("CDevEncController::DoStartDecryptionL >>"));
+
+    TInt deoperation (EOpIdle);  
+
+    RProperty::Get(KDevEncProtectedUid, KDevEncOperationKey, deoperation );
+
+    if (deoperation != EOpIdle)
+        {
+        FLOG(_L("Some disk operation is ongoing. Hence Fota is not possible."));
+        User::Leave(KErrNotReady);
+        }
+
+    iDevEncOperation = EDecryption;
+    iStorageDrive = aDrive;
+
+
+    StartDecryptionL();
+
+    FLOG(_L("CDevEncController::DoStartDecryptionL <<"));
+    }
+
+
+void CDevEncController::StartDecryptionL()
+    {
+    FLOG(_L("CDevEncController::StartDecryptionL >>"));
+
+    TInt status (KErrNone);
+
+    if (!iEncMemorySession)
+        iEncMemorySession = new (ELeave) CDevEncSession( iStorageDrive );
+
+    __LEAVE_IF_ERROR(iEncMemorySession->Connect());
+
+    __LEAVE_IF_ERROR(iEncMemorySession->DiskStatus(status));
+
+    FLOG(_L("Status = %d"), status);
+
+    if (status == EEncrypted)
+        {
+        if (CheckBatteryL())
+            {
+            FLOG(_L("Started decryption of drive %d..."), iStorageDrive);
+
+            if (!iDevEncObserver)
+                iDevEncObserver = CDevEncProgressObserver::NewL(this, R_FOTASERVER_DECRYPTION_PROGRESS_DIALOG);
+
+            __LEAVE_IF_ERROR(iEncMemorySession->StartDiskDecrypt());
+
+            FLOG(_L("Monitor for completion of the decryption operation..."));
+
+            iDevEncObserver->StartMonitoringL(iEncMemorySession);
+            }
+        else
+            {
+            FLOG(_L("Battery low for performing decryption!"));
+
+            iDevEncOperation = EIdle;
+            iEncMemorySession->Close();
+            delete iEncMemorySession;  iEncMemorySession = NULL;
+
+            iCallback->HandleDecryptionCompleteL(KErrBadPower, EBatteryLevelLevel4);
+            }
+        }
+    else if(status == EDecrypted)
+        {
+        FLOG(_L("Device is already decrypted"));
+
+        iDevEncOperation = EIdle;
+        iEncMemorySession->Close();
+        delete iEncMemorySession;  iEncMemorySession = NULL;
+
+        iCallback->HandleDecryptionCompleteL(KErrNone);
+        }
+    else
+        {
+        // status is either unmounted, encrypting, decrypting, wiping or corrupted
+        FLOG(_L("Can't proceed as disk status is %d"), status);
+
+        iDevEncOperation = EIdle;
+        iEncMemorySession->Close();
+        delete iEncMemorySession;  iEncMemorySession = NULL;
+
+        iCallback->HandleDecryptionCompleteL(KErrNotReady);
+        }
+
+    FLOG(_L("CDevEncController::StartDecryptionL <<"));
+    }
+
+void CDevEncController::ReportDevEncOpnCompleteL(TInt aResult)
+    {
+    FLOG(_L("CDevEncController::ReportDevEncOpnCompleteL, result = %d >>"), aResult);
+
+    TInt err (KErrNone);
+
+    if (iEncMemorySession)
+        {
+        iEncMemorySession->Close();
+        delete iEncMemorySession;  iEncMemorySession = NULL;
+        }
+
+    CRepository *centrep = CRepository::NewL( KCRUidFotaServer );
+
+    if (iDevEncOperation == EDecryption)
+        {
+        err = centrep->Set(  KDriveToEncrypt, iStorageDrive );
+        if (err != KErrNone)
+            {
+            FLOG(_L("Setting drive to encrypt as %d after firmware update, error = %d"), (TInt) iStorageDrive, err);
+            }
+        }
+    else if (iDevEncOperation == EEncryption)
+        {
+        err = centrep->Set(  KDriveToEncrypt, KErrNotFound );
+        if (err != KErrNone)
+            {
+            FLOG(_L("Setting no drive, error = %d"), err);
+            }
+        }
+    delete centrep; centrep = NULL;
+
+    if (iDevEncOperation == EDecryption)
+        {
+        FLOG(_L("Starting update..."));
+        iCallback->HandleDecryptionCompleteL(KErrNone);
+        iDevEncOperation = EIdle;
+        }
+    else if (iDevEncOperation == EEncryption)
+        {
+        FLOG(_L("Encryption ended"));
+        iCallback->HandleEncryptionCompleteL(KErrNone);
+        iDevEncOperation = EIdle;
+        }
+    else
+        {
+        //should not land here!
+        }
+
+    FLOG(_L("CDevEncController::ReportDevEncOpnCompleteL <<"));
+    }
+
+TBool CDevEncController::NeedToEncryptL(TDriveNumber &aDrive)
+    {
+    FLOG(_L("CDevEncController::NeedToEncryptL >> "));
+    TBool ret (EFalse);
+
+    CRepository *centrep = CRepository::NewL( KCRUidFotaServer );
+    TInt drive (KErrNotFound);
+    TInt err = centrep->Get(  KDriveToEncrypt, drive );
+    if (drive != KErrNotFound)
+        {
+        aDrive = (TDriveNumber) drive;
+        ret = ETrue;
+        }
+
+    delete centrep; centrep = NULL;
+
+    FLOG(_L("CDevEncController::NeedToEncryptL, ret = %d, err = %d << "), ret, err);
+    return ret;
+    }
+
+void CDevEncController::DoStartEncryptionL(const TDriveNumber &aDrive)
+    {
+    FLOG(_L("CDevEncController::DoStartEncryptionL, drive = %d >>"), (TInt) aDrive);
+
+    iDevEncOperation = EEncryption;
+    iStorageDrive = aDrive;
+    StartEncryptionL();
+
+    FLOG(_L("CDevEncController::DoStartEncryptionL <<"));
+    }
+
+void CDevEncController::StartEncryptionL()
+    {
+    FLOG(_L("CDevEncController::StartEncryptionL >>"));
+
+    TInt status (KErrNone);
+
+    if (!iEncMemorySession)
+        iEncMemorySession = new (ELeave) CDevEncSession( iStorageDrive );
+
+    __LEAVE_IF_ERROR(iEncMemorySession->Connect());
+
+    __LEAVE_IF_ERROR(iEncMemorySession->DiskStatus(status));
+
+    FLOG(_L("Status = %d"), status);
+
+    if (status == EDecrypted)
+        {
+        FLOG(_L("Started encryption of drive %d..."), iStorageDrive);
+
+        if (CheckBatteryL())
+            {
+            if (!iDevEncObserver)
+                iDevEncObserver = CDevEncProgressObserver::NewL(this, R_FOTASERVER_ENCRYPTION_PROGRESS_DIALOG);
+
+            __LEAVE_IF_ERROR(iEncMemorySession->StartDiskEncrypt());
+
+            FLOG(_L("Monitor for completion of the decryption operation..."));
+
+            iDevEncObserver->StartMonitoringL(iEncMemorySession);
+            }
+        else
+            {
+            FLOG(_L("Battery low for performing encryption!"));
+
+            iDevEncOperation = EIdle;
+            iEncMemorySession->Close();
+            delete iEncMemorySession;  iEncMemorySession = NULL;
+
+            iCallback->HandleEncryptionCompleteL(KErrBadPower);
+            }
+        }
+    else if (status == EEncrypted)
+        {
+        FLOG(_L("Memory is already encrypted"));
+
+        iDevEncOperation = EIdle;
+        iEncMemorySession->Close();
+        delete iEncMemorySession;  iEncMemorySession = NULL;
+
+        iCallback->HandleEncryptionCompleteL(KErrNone);
+        }
+    else
+        {
+        //status is either encrypting, decrypting, wiping, corrupted
+        FLOG(_L("Can't proceed as disk status is %d"), status);
+
+        iDevEncOperation = EIdle;
+        iEncMemorySession->Close();
+        delete iEncMemorySession;  iEncMemorySession = NULL;
+
+        iCallback->HandleEncryptionCompleteL(KErrNotReady);
+        }
+    FLOG(_L("CDevEncController::StartEncryptionL <<"));
+    }
+
+TBool CDevEncController::CheckBatteryL()
+    {
+    FLOG(_L("CDevEncController::CheckBatteryL >>"));
+#ifdef __WINS__
+
+    // In the emulator, the battery level is always 0 and the charger is never
+    // connected, so just return ETrue.
+    return ETrue;
+
+#else // __WINS__
+
+    // Running on target. Check the real battery and charger status
+
+    TInt chargingstatus( EChargingStatusError );
+    TInt batterylevel( 1 );
+    TBool enoughPower( EFalse );
+
+    // Read battery
+    FLOG( _L("CDevEncUiEncryptionOperator::CheckBatteryL" ));
+    RProperty pw;
+    User::LeaveIfError( pw.Attach( KPSUidHWRMPowerState, KHWRMBatteryLevel ) );
+    User::LeaveIfError( pw.Get( batterylevel ) );
+    pw.Close();
+
+    User::LeaveIfError( pw.Attach( KPSUidHWRMPowerState, KHWRMChargingStatus ) );
+    User::LeaveIfError( pw.Get( chargingstatus ));
+    pw.Close();
+
+    // Too low battery, power insufficient
+    if ( batterylevel >= EBatteryLevelLevel4 )
+        {
+        enoughPower = ETrue;
+        }
+    // But charger is connected, power sufficient
+    if ( ( chargingstatus != EChargingStatusError ) &&
+            ( chargingstatus != EChargingStatusNotConnected ) )
+        {
+        enoughPower = ETrue;
+        }
+
+    FLOG( _L("Battery level: %d  (0..7), chargingstatus %d"),
+            batterylevel, chargingstatus );
+    FLOG( _L("CDevEncController::CheckBatteryL, ret=%d <<"), ( enoughPower ? 1 : 0 ) );
+    return enoughPower;
+
+#endif // __WINS__
+    }
+
+TInt CDevEncController::GetDEOperation()
+    {
+    return iDevEncOperation;
+    }
+
+// End of file
+