commondrm/drmutility/src/drmutilitywmdrmutilities.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
--- /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 <e32std.h>
+#include <DRMRights.h>
+
+#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