diff -r 000000000000 -r 95b198f216e5 commondrm/drmutility/src/drmutilitywmdrmutilities.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commondrm/drmutility/src/drmutilitywmdrmutilities.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,580 @@ +/* +* Copyright (c) 2008 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: WM DRM specific methods for DRM Rights Manager +* +*/ + + +#include +#include + +#include "drmclockclient.h" +#include "drmutilitywmdrmutilities.h" +#include "drmrights.h" + +// CONSTANTS +_LIT( KLicenseType, "licensetype=" ); +_LIT( KTime, "time" ); +_LIT( KCount, "count" ); +_LIT( KDuration, "duration" ); +_LIT( KTimeCount, "time-count" ); +_LIT( KUnlimited, "unlimited" ); + +_LIT( KDurationLeft, "duration=" ); +_LIT( KCountLeft, "countleft=" ); +_LIT( KStartTime, "starttime=" ); +_LIT( KEndTime, "endtime=" ); + +const TUint8 KFoundStartTime = 0x01; +const TUint8 KFoundEndTime = 0x02; + +// masks for constraint existence +const TInt KWmDrmConstraintCount( 1 ); +const TInt KWmDrmConstraintStartTime ( 2 ); +const TInt KWmDrmConstraintEndTime( 4 ); +const TInt KWmDrmConstraintDuration( 8 ); + +#ifdef _DEBUG +// debug panic +_LIT( KWmDrmUtilitiesDebugPanicMessage, "WmDrmUtilitiesDebugPanic" ); +const TInt KWmDrmUtilitiesDebugPanicCode( 2 ); +#endif + +// LOCAL FUNCTION PROTOTYPES +// Parses the given lexicographic representation. Return value indicates +// whether the given end character of the searched substring was found or not. +// Special handling is applied for certain separators (e.g. ';', '-') +LOCAL_C TBool ParseString( TChar aChar, TLex& aLex, TPtrC16& aPtr ); + +// ================= MEMBER FUNCTIONS ======================= + +LOCAL_C TBool ParseString( TChar aChar, TLex& aLex, TPtrC16& aPtr ) + { + TBool found( EFalse ); + aLex.Mark(); + + while ( !aLex.Eos() && found == EFalse ) + { + TChar ch; + ch = aLex.Get(); + if ( ch == aChar ) + { + if ( ch == ';' || ch == '-' || ch == ':' || ch == 'T' || ch == 'Z' ) + { + // Remove char from the token string and read it from the lex. + aLex.UnGet(); + aPtr.Set( aLex.MarkedToken() ); + aLex.Get(); + } + else + { + aPtr.Set( aLex.MarkedToken() ); + } + found = ETrue; + } + } + return found; + } + +// ---------------------------------------------------------------------------- +// DrmUtilityWmDrmUtilities::ParseWmDrmTimeRightsL +// ---------------------------------------------------------------------------- +EXPORT_C void DrmUtilityWmDrmUtilities::ParseWmDrmTimeRightsL( TLex& aLex, + TTime& aStartTime, TTime& aEndTime ) + { + TPtrC16 token( NULL, 0 ); + TUint8 times( 0 ); + TTime localTime( Time::NullTTime() ); + TTime universalTime( Time::NullTTime() ); + TTimeIntervalSeconds timeDifference( 0 ); // local time - secure time + TInt years, months, days, hours, minutes, secs; + TChar ch; + TLex lex; + TTime drmTime; + TInt timeZone; + + DRMClock::ESecurityLevel secLevel = DRMClock::KInsecure; + + // The format of the start and end time strings is the following: + // "starttime=yy-mm-ddThh:mins:ssZ + // "endtime=yy-mm-ddThh:mins:ssZ + // where yy = years, mm = months, dd = days, hh = hours, + // mins = minutes and ss = seconds, "-", "T", ":" and "Z" + // are separators. + while ( !aLex.Eos() && ( aLex.Peek() != 0 ) ) + { + // The next string should be start time, end time or then + // it does not exist. + ParseString( '=', aLex, token ); + + if ( token.CompareF( KStartTime ) == 0 ) + { + times |= KFoundStartTime; + } + else if ( token.CompareF( KEndTime ) == 0 ) + { + times |= KFoundEndTime; + } + else + { + // No start time ("starttime=") or end time ("endtime=") + // string was found -> return + return; + } + + if ( ( times & KFoundStartTime ) || ( times & KFoundEndTime ) ) + { + // Search for years, months, days, hours, minutes, secs + if ( ParseString( '-', aLex, token ) ) + { + TLex lexYear( token ); + User::LeaveIfError( lexYear.Val( years ) ); + } + else + { + User::Leave( KErrNotFound ); + } + + if ( ParseString( '-', aLex, token ) ) + { + TLex lexMonths( token ); + User::LeaveIfError( lexMonths.Val( months ) ); + } + else + { + User::Leave( KErrNotFound ); + } + + if ( ParseString( 'T', aLex, token ) ) + { + TLex lexDays( token ); + User::LeaveIfError( lexDays.Val( days ) ); + } + else + { + User::Leave( KErrNotFound ); + } + + if( ParseString( ':', aLex, token ) ) + { + TLex lexHours( token ); + User::LeaveIfError( lexHours.Val( hours ) ); + } + else + { + User::Leave( KErrNotFound ); + } + + if ( ParseString( ':', aLex, token ) ) + { + TLex lexMinutes( token ); + User::LeaveIfError( lexMinutes.Val( minutes ) ); + } + else + { + User::Leave( KErrNotFound ); + } + + if( ParseString( 'Z', aLex, token ) ) + { + TLex lexSeconds( token ); + User::LeaveIfError( lexSeconds.Val( secs ) ); + } + else + { + User::Leave( KErrNotFound ); + } + + ParseString( ';', aLex, token ); + token.Set( NULL, 0 ); + + TDateTime date( years, (TMonth)( months - 1 ), days - 1, hours, + minutes, secs, 0 ); + TTime dateTime( date ); + + // Get secure time from DRM clock + RDRMClockClient client; + + User::LeaveIfError( client.Connect() ); + client.GetSecureTime( drmTime, timeZone, secLevel ); + client.Close(); + + localTime.HomeTime(); + + if ( secLevel == DRMClock::KSecure ) + { + // Calculate the difference between local time and secure time + localTime.SecondsFrom( drmTime, timeDifference ); + } + else + { + // Calculate the difference between local and universal time + universalTime.UniversalTime(); + localTime.SecondsFrom( universalTime, timeDifference ); + } + + dateTime += timeDifference; + + if ( times & KFoundStartTime ) + { + aStartTime = dateTime; + times &= ~KFoundStartTime; + } + else if ( times & KFoundEndTime ) + { + aEndTime = dateTime; + times &= ~KFoundEndTime; + } + } + } + } + +// ---------------------------------------------------------------------------- +// DrmUtilityWmDrmUtilities::ParseWmDrmCountRightsL +// ---------------------------------------------------------------------------- +// +EXPORT_C TBool DrmUtilityWmDrmUtilities::ParseWmDrmCountRightsL( TLex& aLex, + TUint32& aCounts ) + { + TPtrC16 token( NULL, 0 ); + TInt counts( 0 ); + TChar ch; + TLex lex; + + ParseString( '=', aLex, token ); + + if ( token.CompareF( KCountLeft ) == 0 ) + { + ParseString( ';', aLex, token ); + TLex lexCount( token ); + User::LeaveIfError( lexCount.Val( counts ) ); + aCounts = counts; + return ETrue; + } + else + { + // No counts left ("countleft=") string was found. + // -> No count information was found, return EFalse + return EFalse; + } + } + +// ---------------------------------------------------------------------------- +// DrmUtilityWmDrmUtilities::ParseWmDrmDurationRightsL +// ---------------------------------------------------------------------------- +// +EXPORT_C TBool DrmUtilityWmDrmUtilities::ParseWmDrmDurationRightsL( TLex& aLex, + TTimeIntervalSeconds& aDuration ) + { + TPtrC16 token( NULL, 0 ); + TChar ch; + TInt duration( 0 ); + + ParseString( '=', aLex, token ); + + if ( token.CompareF( KDurationLeft ) == 0 ) + { + ParseString( ';', aLex, token ); + TLex lexDuration( token ); + User::LeaveIfError( lexDuration.Val( duration ) ); + aDuration = duration; + return ETrue; + } + else + { + // No duration left ("durationleft=") string was found. + // -> No duration information was found, return EFalse + return EFalse; + } + } + +// ---------------------------------------------------------------------------- +// DrmUtilityWmDrmUtilities::ParseWmDrmStringL +// ---------------------------------------------------------------------------- +// +EXPORT_C void DrmUtilityWmDrmUtilities::ParseWmDrmStringL( + ContentAccess::CRightsInfo& aRights, + CDRMRightsConstraints*& aRightsConstraint ) + { + + __ASSERT_DEBUG( !aRightsConstraint, + User::Panic( KWmDrmUtilitiesDebugPanicMessage, + KWmDrmUtilitiesDebugPanicCode ) ); + + TChar ch; + TTime startTime( Time::NullTTime() ); + TTime endTime( Time::NullTTime() ); + TTimeIntervalSeconds duration( 0 ); + TUint32 counter( 0 ); + + TPtrC16 token( NULL, 0 ); + + // Parse the WM DRM rights string + TLex lex( aRights.Description() ); + + // First, find the license type format string ("licensetype=") + ParseString( '=', lex, token ); + + if ( token.CompareF( KLicenseType ) != 0 ) + { + // License type format string was not found + User::Leave( KErrArgument ); + } + + // Peek for the end of string (eos) in case of (licensetype="") + ch = lex.Peek(); + if ( ch == 0 ) + { + return; + } + + // Check the license type + ParseString( ';', lex, token ); + + aRightsConstraint = CDRMRightsConstraints::NewL(); + CleanupStack::PushL( aRightsConstraint ); + + // Check what kind of rights are in question by parsing the string + // onward. The possible rights are date time (start time and/or end time), + // count, duration, time count (count and/or date time) and unlimited + // rights. The substrings for certain rights are further parsed in + // specific methods. + if ( token.CompareF( KTime ) == 0 ) + { + ParseWmDrmTimeRightsL( lex, startTime, endTime ); + if ( Time::NullTTime() != startTime ) + { + aRightsConstraint->SetStartTime( startTime ); + } + if ( Time::NullTTime() != endTime ) + { + aRightsConstraint->SetEndTime( endTime ); + } + } + else if ( token.CompareF( KCount ) == 0 ) + { + if ( ParseWmDrmCountRightsL( lex, counter ) ) + { + aRightsConstraint->SetCounters( counter, counter ); + } + } + else if ( token.CompareF( KDuration ) == 0 ) + { + if ( ParseWmDrmDurationRightsL( lex, duration ) ) + { + aRightsConstraint->SetInterval( duration ); + } + } + else if ( token.CompareF( KTimeCount ) == 0 ) + { + counter = 0; + if ( ParseWmDrmCountRightsL( lex, counter ) ) + { + aRightsConstraint->SetCounters( counter, counter ); + } + ParseWmDrmTimeRightsL( lex, startTime, endTime ); + if ( Time::NullTTime() != startTime ) + { + aRightsConstraint->SetStartTime( startTime ); + } + if ( Time::NullTTime() != endTime ) + { + aRightsConstraint->SetEndTime( endTime ); + } + } + else if ( token.CompareF( KUnlimited ) != 0 ) + { + // Unknown license type + User::Leave( KErrArgument ); + } + + CleanupStack::Pop( aRightsConstraint ); + + } + +// ----------------------------------------------------------------------------- +// DrmUtilityWmDrmUtilities::CheckWmDrmRightsL +// ----------------------------------------------------------------------------- +// +EXPORT_C void DrmUtilityWmDrmUtilities::CheckWmDrmRightsL( TBool& aUnconstrained, + TTimeIntervalSeconds& aTime, + TInt& aCounts, + ContentAccess::CRightsInfo& aRights ) + { + + TChar ch; + TPtrC16 token( NULL, 0 ); + TInt constraints( 0 ); + TInt error( KErrNone ); + TTime startTime( Time::NullTTime() ); + TTime endTime( Time::NullTTime() ); + TUint32 counter( 0 ); + TTime now( Time::NullTTime() ); // current time + // End time of rights when duration is taken into account. + TTime durationEndTime( Time::NullTTime() ); + TTimeIntervalSeconds secondsLeft( 0 ); // seconds to end of time based rights + + // Parse WM DRM rights string + TLex lex( aRights.Description() ); + + // First, find the license type format string ("licensetype=") + ParseString( '=', lex, token ); + + if ( token.CompareF( KLicenseType ) != 0 ) + { + // License type format string was not found + User::Leave( KErrArgument ); + } + + // Peek for the end of string (Eos) in case of (licensetype="") + ch = lex.Peek(); + if ( ch == 0 ) + { + return; + } + + // Check the license type + ParseString( ';', lex, token ); + + // Check what kind of rights are in question by parsing the string + // onward. The possible rights are date time (start time and/or end time), + // count, duration, time count (count and/or date time) and unlimited + // rights. The substrings for certain rights are further parsed in + // specific methods. + if ( token.CompareF( KTime ) == 0 ) + { + ParseWmDrmTimeRightsL( lex, startTime, endTime ); + if ( Time::NullTTime() != startTime ) + { + constraints |= KWmDrmConstraintStartTime; + } + if ( Time::NullTTime() != endTime ) + { + constraints |= KWmDrmConstraintEndTime; + } + } + else if ( token.CompareF( KCount ) == 0 ) + { + if ( ParseWmDrmCountRightsL( lex, counter ) ) + { + aCounts = counter; + constraints |= KWmDrmConstraintCount; + } + } + else if ( token.CompareF( KDuration ) == 0 ) + { + if ( ParseWmDrmDurationRightsL( lex, aTime ) ) + { + if ( aTime < (TTimeIntervalSeconds)0 ) + { + aTime = 0; + } + constraints |= KWmDrmConstraintDuration; + } + } + else if ( token.CompareF( KTimeCount ) == 0 ) + { + if ( ParseWmDrmCountRightsL( lex, counter ) ) + { + aCounts = counter; + constraints |= KWmDrmConstraintCount; + } + ParseWmDrmTimeRightsL( lex, startTime, endTime ); + if ( Time::NullTTime() != startTime ) + { + constraints |= KWmDrmConstraintStartTime; + } + if ( Time::NullTTime() != endTime ) + { + constraints |= KWmDrmConstraintEndTime; + } + } + else if ( token.CompareF( KUnlimited ) == 0 ) + { + aUnconstrained = ETrue; + return; + } + else + { + // Unknown license type + User::Leave( KErrArgument ); + } + + // Get current time + now.HomeTime(); + + // The rights are not constrained + if ( !constraints ) + { + aUnconstrained = ETrue; + } + + if ( constraints & KWmDrmConstraintStartTime ) + { + // The start time is in the past or the current time + if ( ( now >= startTime ) && + !( constraints & KWmDrmConstraintEndTime ) && + !( constraints & KWmDrmConstraintCount ) ) + { + aUnconstrained = ETrue; + } + + // This use case is unclear and should be specified later. + // There are counts for the content, but the start time has + // not been reached. + if ( ( constraints & KWmDrmConstraintCount ) && + ( now < startTime ) ) + { + aCounts = 0; + } + } + + // Find out the amount of time that the rights have left in + // case the rights have end time constraint. + if ( constraints & KWmDrmConstraintEndTime ) + { + error = endTime.SecondsFrom( now, secondsLeft ); + + // The difference between current time and the end time does not + // fit to 32-bit number, the start time has been reached and there + // are no count constraints defined. + if ( ( error == KErrOverflow ) && + ( !( constraints & KWmDrmConstraintStartTime ) || + ( now >= startTime ) ) && !( constraints & KWmDrmConstraintCount ) ) + { + aUnconstrained = ETrue; + } + + // End time has not been reached and start time has been reached + if ( ( secondsLeft > (TTimeIntervalSeconds)0 ) && ( now >= startTime ) ) + { + aTime = secondsLeft; + } + + // This use case is unclear and should be specified later. + // There are counts for the content, but the end time has + // been reached. + if ( ( constraints & KWmDrmConstraintCount ) && + ( now > endTime ) ) + { + aCounts = 0; + } + } + + return; + + } + +// End of File + \ No newline at end of file