diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/drmclock/Src/DRMClock.cpp --- /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 + +#include "DRMClock.h" +#include "DRMLog.h" +#include "DRMEventTimeChange.h" +#include "wmdrmfileserverclient.h" + +#include +#include +#include +#include +#include + +#ifdef RD_MULTIPLE_DRIVE +#include +#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(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