omadrm/drmengine/drmclock/Src/DRMClock.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omadrm/drmengine/drmclock/Src/DRMClock.cpp	Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,366 @@
+/*
+* Copyright (c) 2003-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:  Implementation of the DRM Clock
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <mmtsy_names.h>
+
+#include "DRMClock.h"
+#include "DRMLog.h"
+#include "DRMEventTimeChange.h"
+#include "wmdrmfileserverclient.h"
+
+#include <DRMNotifier.h>
+#include <s32strm.h>
+#include <s32file.h>
+#include <e32property.h>
+#include <e32keys.h>
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <DriveInfo.h>
+#endif
+
+#include "DRMNitzObserver.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES  
+
+// CONSTANTS
+const TInt KMinuteInMicroseconds = 60000000;
+const TInt KTimeZoneIncrement = 15;
+ 
+// The time zones sanity check values, not sure if -13 hours exists
+// But atleast +13 does in: Nuku'Alofa
+const TInt KTimeZoneLow = -52; // -13 hours
+const TInt KTimeZoneHigh = 55; // +13 hours 45 minutes Some NZ owned island
+
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CDRMRightsDB::CDRMRightsDB
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//    
+CDRMClock::CDRMClock()
+    {      
+    };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsDB::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CDRMClock::ConstructL()
+    {
+    DRMLOG( _L( "DRM Clock Starting: " ) );
+
+    // Create a notifier instance
+    iNotifier = CDRMNotifier::NewL();
+        
+#ifndef __WINS__
+    ConnectToPhoneL();            
+            
+    iObserver = CDRMNitzObserver::NewL( iPhone, const_cast<CDRMClock*>(this));
+
+    iObserver->Start();
+#endif
+
+
+    DRMLOG( _L( "DRM Clock started" ) );		    
+    };
+
+// -----------------------------------------------------------------------------
+// CDRMClock::NewLC
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+//
+CDRMClock* CDRMClock::NewLC()
+    {
+    DRMLOG( _L( "CDRMClock::NewLC" ) );
+    
+    CDRMClock* self = new(ELeave) CDRMClock;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    
+    DRMLOG( _L( "CDRMClock::NewLC ok" ) );
+    
+    return self;
+    };
+
+// -----------------------------------------------------------------------------
+// CDRMClock::NewL
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+//
+CDRMClock* CDRMClock::NewL()
+    {
+    DRMLOG( _L( "CDRMClock::NewL" ) );
+    
+    CDRMClock* self = NewLC();
+    CleanupStack::Pop();
+
+    DRMLOG( _L( "CDRMClock::NewL ok" ) );
+    
+    return self;
+    };
+  
+// ---------------------------------------------------------
+// CDRMClock::~CDRMClock
+// Destructor
+// ---------------------------------------------------------
+//
+CDRMClock::~CDRMClock()
+    { 
+    DRMLOG( _L( "CDRMClock::~CDRMClock" ) );
+       
+    if( iNotifier )
+        {
+        delete iNotifier;
+        iNotifier = 0;
+        }
+        
+#ifndef __WINS__
+    if(iObserver)            
+        {
+        iObserver->Cancel();
+        delete iObserver;
+        iObserver = 0;
+        }  
+#endif // __WINS__        
+    };
+
+// -----------------------------------------------------------------------------
+// CDRMClock::GetSecureTime
+// returns time and security level
+// -----------------------------------------------------------------------------
+//
+void CDRMClock::GetSecureTime(TTime& aTime, TInt& aTimeZone, 
+                              DRMClock::ESecurityLevel& aSecurityLevel)
+    {
+    DRMLOG( _L( "CDRMClock::GetSecureTime" ) );
+    
+    TTime currentUniversal;
+    TTime currentHome;
+    TInt error = KErrNone;
+    
+    // if there is an error it's not initialized
+    error = aTime.UniversalTimeSecure();
+    
+    if( error == KErrNoSecureTime )
+        {
+        currentHome.HomeTime();               
+        currentUniversal.UniversalTime();         
+        
+        aTimeZone = ( currentHome.Int64() - currentUniversal.Int64() ) / 
+                   ( KMinuteInMicroseconds* KTimeZoneIncrement );
+        
+        
+        aTime.UniversalTime();
+
+        aSecurityLevel = DRMClock::KInsecure;
+       
+        DRMLOG( _L( "CDRMClock::GetSecureTime: DRMClock is Insecure" ) );        
+        }
+    else 
+        {
+        currentHome.HomeTimeSecure();        
+        currentUniversal.UniversalTimeSecure();
+        
+        aTimeZone = ( currentHome.Int64() - currentUniversal.Int64() ) / 
+                   ( KMinuteInMicroseconds* KTimeZoneIncrement );
+        
+        aSecurityLevel = DRMClock::KSecure;     
+        DRMLOG( _L( "CDRMClock::GetSecureTime: DRMClock is Secure" ) );  
+        }    
+
+    DRMLOG( _L( "CDRMClock::GetSecureTime ok" ) );
+    };
+
+
+// -----------------------------------------------------------------------------
+// CDRMClock::ResetSecureTimeL
+// resets the secure time and recalculates the offsets
+// should not reset to 0
+// -----------------------------------------------------------------------------
+//
+// Do not reset the timezone, use whatever has been set or retrieved from the UI time
+// However check that the timezone is a valid one just in case
+void CDRMClock::ResetSecureTimeL( const TTime& aTime, const TInt& aTimeZone )
+    {
+    DRMLOG( _L( "CDRMClock::ResetSecureTimeL" ) );
+   
+    TRequestStatus status;  
+    TInt error = KErrNone;  
+    CDRMEventTimeChange* change = CDRMEventTimeChange::NewLC();
+	TTime previousTime;
+	TTime previousTimeLocal;
+	TTime newTime;
+	TInt timezone = 0;
+	TDateTime temppi; // Only for logging
+
+    // check for param that the time is even reasonably valid:
+    if( aTime.Int64() == 0 )
+        {
+        DRMLOG( _L("Trying to reset to zero time") );             
+    	User::Leave( KErrArgument );
+        }
+    
+    // Sanity check: Time zone has to be +/- certail hours
+    // for this check -13h to +13.75h
+    if( aTimeZone < KTimeZoneLow || aTimeZone > KTimeZoneHigh )
+        {
+        DRMLOG2( _L("TimeZone invalid, time may be as well, aborting change: %d"), aTimeZone  );
+        User::Leave( KErrArgument );
+        }
+    
+    
+    // Get the current secure time with timezone
+    // Ask the hometime first so that rounding of any divider goes correctly
+    error = previousTimeLocal.HomeTimeSecure(); 
+    
+    // If there is an error, the secure hometime has not been set
+    // Which means that the UI clock has the valid data
+    if( error )
+        {
+        previousTimeLocal.HomeTime();
+        previousTime.UniversalTime();
+        timezone = ( previousTimeLocal.Int64() - previousTime.Int64() ) / 
+                   ( KMinuteInMicroseconds* KTimeZoneIncrement );
+		change->SetOldSecurityLevel( DRMClock::KInsecure );
+		}
+	else
+		{
+		previousTime.UniversalTimeSecure();		                   
+        
+        timezone = ( previousTimeLocal.Int64() - previousTime.Int64() ) / 
+                   ( KMinuteInMicroseconds* KTimeZoneIncrement );
+
+		change->SetOldSecurityLevel( DRMClock::KSecure );
+		change->SetNewSecurityLevel( DRMClock::KSecure );
+		}
+    
+    // Since it's not important to get the timezone we keep what is set or reset it:
+    previousTimeLocal = aTime.Int64() + ( timezone * ( KMinuteInMicroseconds* KTimeZoneIncrement ) );
+
+    // Do the actual updating:
+    // Update using the wmdrm fileserver since it has TCB capability
+    RWmDrmFileServerClient resetclient;
+    User::LeaveIfError( resetclient.Connect() );
+    CleanupClosePushL( resetclient );
+    
+    newTime = aTime;
+    User::LeaveIfError( resetclient.UpdateSecureTime( previousTimeLocal, newTime ) );
+       
+    CleanupStack::PopAndDestroy();
+
+
+    DRMLOG( _L( "CDRMClock::ResetSecureTimeL: AFTER RESET." ));	
+
+    // DRM Notifier data:
+    // send info about the change:
+
+    change->SetNewSecurityLevel( DRMClock::KSecure );
+    
+    change->SetOldTime( previousTime );
+    change->SetOldTimeZone( timezone );
+
+    change->SetNewTime( aTime );
+    change->SetNewTimeZone( timezone );
+    
+    // Notify clients
+
+    iNotifier->SendEventL(*change,status);
+    User::WaitForRequest(status);
+    CleanupStack::PopAndDestroy();    
+    
+    DRMLOG( _L( "CDRMClock::ResetSecureTimeL ok" ) );
+    };
+
+
+// ---------------------------------------------------------
+// CDRMClock::ConnectToPhoneL(const TDateTime& aDateTime)
+// Gets the nitz time from iNitzInfo
+// ---------------------------------------------------------
+//
+void CDRMClock::ConnectToPhoneL()
+    {
+    DRMLOG( _L( "CDRMClock::ConnectToPhoneL" ) );
+    
+    const TInt KTriesToConnectServer(10);
+    const TInt KTimeBeforeRetryingServerConnection(100000);
+    TInt thisTry(0);
+    TInt err(KErrNone);
+    TInt numPhone;
+    TName tsyName;
+    RTelServer::TPhoneInfo phoneInfo;
+    RMobilePhone::TMobilePhoneSubscriberId imsi;
+    TRequestStatus status;
+    
+
+    while ((err = iEtelServer.Connect()) != KErrNone &&
+                            (thisTry++) <= KTriesToConnectServer)
+        {
+        User::After(KTimeBeforeRetryingServerConnection);
+        }
+    User::LeaveIfError(err);
+
+    User::LeaveIfError(iEtelServer.LoadPhoneModule(KMmTsyModuleName));
+    User::LeaveIfError(iEtelServer.EnumeratePhones(numPhone));
+
+    for (TInt i(0); i < numPhone; i++)
+        {
+        User::LeaveIfError(iEtelServer.GetPhoneInfo(i, phoneInfo));
+        User::LeaveIfError(iEtelServer.GetTsyName(i,tsyName));
+
+        if (tsyName.CompareF(KMmTsyModuleName) == 0)
+            {
+            break;
+            }
+        }
+
+    User::LeaveIfError(iPhone.Open(iEtelServer, phoneInfo.iName));   
+    
+    iPhone.GetSubscriberId( status, imsi );
+    User::WaitForRequest( status );
+    
+    DRMLOG( imsi );    
+    DRMLOG( _L( "CDRMClock::ConnectToPhoneL ok" ) );
+    };
+
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+
+//  End of File