commondrm/drmutility/src/drmutilitywmdrmutilities.cpp
changeset 0 95b198f216e5
child 12 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  WM DRM specific methods for DRM Rights Manager
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <DRMRights.h>
       
    21 
       
    22 #include "drmclockclient.h"
       
    23 #include "drmutilitywmdrmutilities.h"
       
    24 #include "drmrights.h"
       
    25 
       
    26 // CONSTANTS
       
    27 _LIT( KLicenseType, "licensetype=" );
       
    28 _LIT( KTime, "time" );
       
    29 _LIT( KCount, "count" );
       
    30 _LIT( KDuration, "duration" );
       
    31 _LIT( KTimeCount, "time-count" );
       
    32 _LIT( KUnlimited, "unlimited" );
       
    33 
       
    34 _LIT( KDurationLeft, "duration=" );
       
    35 _LIT( KCountLeft, "countleft=" );
       
    36 _LIT( KStartTime, "starttime=" );
       
    37 _LIT( KEndTime, "endtime=" );
       
    38 
       
    39 const TUint8 KFoundStartTime = 0x01;
       
    40 const TUint8 KFoundEndTime = 0x02;
       
    41 
       
    42 // masks for constraint existence
       
    43 const TInt KWmDrmConstraintCount( 1 );
       
    44 const TInt KWmDrmConstraintStartTime ( 2 );
       
    45 const TInt KWmDrmConstraintEndTime( 4 );
       
    46 const TInt KWmDrmConstraintDuration( 8 );
       
    47 
       
    48 #ifdef _DEBUG
       
    49 // debug panic
       
    50 _LIT( KWmDrmUtilitiesDebugPanicMessage, "WmDrmUtilitiesDebugPanic" );
       
    51 const TInt KWmDrmUtilitiesDebugPanicCode( 2 );
       
    52 #endif
       
    53 
       
    54 // LOCAL FUNCTION PROTOTYPES
       
    55 // Parses the given lexicographic representation. Return value indicates
       
    56 // whether the given end character of the searched substring was found or not.
       
    57 // Special handling is applied for certain separators (e.g. ';', '-')
       
    58 LOCAL_C TBool ParseString( TChar aChar, TLex& aLex, TPtrC16& aPtr );
       
    59 
       
    60 // ================= MEMBER FUNCTIONS =======================
       
    61 
       
    62 LOCAL_C TBool ParseString( TChar aChar, TLex& aLex, TPtrC16& aPtr )
       
    63     {
       
    64     TBool found( EFalse );
       
    65     aLex.Mark();
       
    66     
       
    67     while ( !aLex.Eos() && found == EFalse )
       
    68         {
       
    69         TChar ch;
       
    70         ch = aLex.Get();
       
    71         if ( ch == aChar )
       
    72             {
       
    73             if ( ch == ';' || ch == '-' || ch == ':' || ch == 'T' || ch == 'Z' )
       
    74                 {
       
    75                 // Remove char from the token string and read it from the lex.
       
    76                 aLex.UnGet();
       
    77                 aPtr.Set( aLex.MarkedToken() );
       
    78                 aLex.Get();
       
    79                 }
       
    80             else 
       
    81                 {
       
    82                 aPtr.Set( aLex.MarkedToken() );
       
    83                 }
       
    84             found = ETrue;
       
    85             }
       
    86         }
       
    87     return found;
       
    88     }
       
    89 
       
    90 // ----------------------------------------------------------------------------
       
    91 // DrmUtilityWmDrmUtilities::ParseWmDrmTimeRightsL
       
    92 // ----------------------------------------------------------------------------
       
    93 EXPORT_C void DrmUtilityWmDrmUtilities::ParseWmDrmTimeRightsL( TLex& aLex,
       
    94     TTime& aStartTime, TTime& aEndTime )
       
    95     {
       
    96     TPtrC16 token( NULL, 0 );
       
    97     TUint8 times( 0 );
       
    98     TTime localTime( Time::NullTTime() );
       
    99     TTime universalTime( Time::NullTTime() );
       
   100     TTimeIntervalSeconds timeDifference( 0 ); // local time - secure time
       
   101     TInt years, months, days, hours, minutes, secs; 
       
   102     TChar ch;
       
   103     TLex lex;
       
   104     TTime drmTime;
       
   105     TInt timeZone;
       
   106     
       
   107     DRMClock::ESecurityLevel secLevel = DRMClock::KInsecure;
       
   108     
       
   109     // The format of the start and end time strings is the following:
       
   110     // "starttime=yy-mm-ddThh:mins:ssZ
       
   111     // "endtime=yy-mm-ddThh:mins:ssZ
       
   112     // where yy = years, mm = months, dd = days, hh = hours, 
       
   113     // mins = minutes and ss = seconds, "-", "T", ":" and "Z" 
       
   114     // are separators.     
       
   115     while ( !aLex.Eos() && ( aLex.Peek() != 0 ) )
       
   116         {
       
   117         // The next string should be start time, end time or then
       
   118         // it does not exist.
       
   119         ParseString( '=', aLex, token );
       
   120         
       
   121         if ( token.CompareF( KStartTime ) == 0 )
       
   122             {
       
   123             times |= KFoundStartTime;
       
   124             } 
       
   125         else if ( token.CompareF( KEndTime ) == 0 )
       
   126             {
       
   127             times |= KFoundEndTime;
       
   128             }
       
   129         else 
       
   130             {
       
   131             // No start time ("starttime=") or end time ("endtime=")  
       
   132             // string was found -> return   
       
   133             return;
       
   134             }
       
   135                
       
   136         if ( ( times & KFoundStartTime ) || ( times & KFoundEndTime ) )
       
   137             {     
       
   138             // Search for years, months, days, hours, minutes, secs     
       
   139             if ( ParseString( '-', aLex, token ) )
       
   140                 {
       
   141                 TLex lexYear( token );
       
   142                 User::LeaveIfError( lexYear.Val( years ) );
       
   143                 }
       
   144             else 
       
   145                 {
       
   146                 User::Leave( KErrNotFound );    
       
   147                 }
       
   148             
       
   149             if ( ParseString( '-', aLex, token ) )
       
   150                 {
       
   151                 TLex lexMonths( token );
       
   152                 User::LeaveIfError( lexMonths.Val( months ) );
       
   153                 }
       
   154             else 
       
   155                 {
       
   156                 User::Leave( KErrNotFound );    
       
   157                 }
       
   158             
       
   159             if ( ParseString( 'T', aLex, token ) )
       
   160                 {
       
   161                 TLex lexDays( token );
       
   162                 User::LeaveIfError( lexDays.Val( days ) );
       
   163                 }
       
   164             else 
       
   165                 {
       
   166                 User::Leave( KErrNotFound );    
       
   167                 }
       
   168             
       
   169             if( ParseString( ':', aLex, token ) )
       
   170                 {
       
   171                 TLex lexHours( token );
       
   172                 User::LeaveIfError( lexHours.Val( hours ) );
       
   173                 }
       
   174             else 
       
   175                 {
       
   176                 User::Leave( KErrNotFound );
       
   177                 }
       
   178             
       
   179             if ( ParseString( ':', aLex, token ) )
       
   180                 {
       
   181                 TLex lexMinutes( token );
       
   182                 User::LeaveIfError( lexMinutes.Val( minutes ) );
       
   183                 }
       
   184             else 
       
   185                 {
       
   186                 User::Leave( KErrNotFound );
       
   187                 }
       
   188             
       
   189             if( ParseString( 'Z', aLex, token ) )
       
   190                 {
       
   191                 TLex lexSeconds( token );
       
   192                 User::LeaveIfError( lexSeconds.Val( secs ) );
       
   193                 }
       
   194             else 
       
   195                 {
       
   196                 User::Leave( KErrNotFound );
       
   197                 }    
       
   198             
       
   199             ParseString( ';', aLex, token );
       
   200             token.Set( NULL, 0 );
       
   201             
       
   202             TDateTime date( years, (TMonth)( months - 1 ), days - 1, hours, 
       
   203                 minutes, secs, 0 );
       
   204             TTime dateTime( date );
       
   205             
       
   206             // Get secure time from DRM clock 
       
   207             RDRMClockClient client;
       
   208             
       
   209             User::LeaveIfError( client.Connect() );
       
   210             client.GetSecureTime( drmTime, timeZone, secLevel );
       
   211             client.Close();
       
   212             
       
   213 			localTime.HomeTime();
       
   214 			        	
       
   215           	if ( secLevel == DRMClock::KSecure ) 
       
   216           		{
       
   217 				// Calculate the difference between local time and secure time
       
   218             	localTime.SecondsFrom( drmTime, timeDifference );
       
   219             	}
       
   220 			else 
       
   221 				{
       
   222 				// Calculate the difference between local and universal time	
       
   223 				universalTime.UniversalTime();	
       
   224 				localTime.SecondsFrom( universalTime, timeDifference ); 	
       
   225 				}
       
   226           	
       
   227 			dateTime += timeDifference;
       
   228 			               
       
   229             if ( times & KFoundStartTime )
       
   230                 {
       
   231                 aStartTime = dateTime;
       
   232                 times &= ~KFoundStartTime;
       
   233                 }
       
   234             else if ( times & KFoundEndTime )
       
   235                 {
       
   236                 aEndTime = dateTime;
       
   237                 times &= ~KFoundEndTime;
       
   238                 }
       
   239             }
       
   240         }
       
   241     }
       
   242 
       
   243 // ----------------------------------------------------------------------------
       
   244 // DrmUtilityWmDrmUtilities::ParseWmDrmCountRightsL
       
   245 // ----------------------------------------------------------------------------
       
   246 //
       
   247 EXPORT_C TBool DrmUtilityWmDrmUtilities::ParseWmDrmCountRightsL( TLex& aLex,
       
   248     TUint32& aCounts )
       
   249     {
       
   250     TPtrC16 token( NULL, 0 );
       
   251     TInt counts( 0 ); 
       
   252     TChar ch;
       
   253     TLex lex;
       
   254         
       
   255     ParseString( '=', aLex, token );
       
   256         
       
   257     if ( token.CompareF( KCountLeft ) == 0 )
       
   258         {
       
   259         ParseString( ';', aLex, token );
       
   260         TLex lexCount( token );
       
   261         User::LeaveIfError( lexCount.Val( counts ) );
       
   262         aCounts = counts;
       
   263         return ETrue;
       
   264         }    
       
   265     else 
       
   266         {
       
   267         // No counts left ("countleft=") string was found.
       
   268         // -> No count information was found, return EFalse
       
   269         return EFalse;
       
   270         }
       
   271     }
       
   272 
       
   273 // ----------------------------------------------------------------------------
       
   274 // DrmUtilityWmDrmUtilities::ParseWmDrmDurationRightsL
       
   275 // ----------------------------------------------------------------------------
       
   276 //
       
   277 EXPORT_C TBool DrmUtilityWmDrmUtilities::ParseWmDrmDurationRightsL( TLex& aLex, 
       
   278     TTimeIntervalSeconds& aDuration )
       
   279     {
       
   280     TPtrC16 token( NULL, 0 );
       
   281     TChar ch;
       
   282     TInt duration( 0 );
       
   283         
       
   284     ParseString( '=', aLex, token );
       
   285         
       
   286     if ( token.CompareF( KDurationLeft ) == 0 )
       
   287         {
       
   288         ParseString( ';', aLex, token );
       
   289         TLex lexDuration( token );
       
   290         User::LeaveIfError( lexDuration.Val( duration ) );
       
   291         aDuration = duration;
       
   292         return ETrue;
       
   293         }
       
   294     else 
       
   295         {
       
   296         // No duration left ("durationleft=") string was found.
       
   297         // -> No duration information was found, return EFalse
       
   298         return EFalse;
       
   299         }         
       
   300     }
       
   301 
       
   302 // ----------------------------------------------------------------------------
       
   303 // DrmUtilityWmDrmUtilities::ParseWmDrmStringL
       
   304 // ----------------------------------------------------------------------------
       
   305 //
       
   306 EXPORT_C void DrmUtilityWmDrmUtilities::ParseWmDrmStringL(
       
   307     ContentAccess::CRightsInfo& aRights,
       
   308     CDRMRightsConstraints*& aRightsConstraint )
       
   309     {
       
   310     
       
   311     __ASSERT_DEBUG( !aRightsConstraint, 
       
   312                     User::Panic( KWmDrmUtilitiesDebugPanicMessage,
       
   313                                  KWmDrmUtilitiesDebugPanicCode ) );
       
   314        
       
   315     TChar ch;
       
   316     TTime startTime( Time::NullTTime() );
       
   317     TTime endTime( Time::NullTTime() );
       
   318     TTimeIntervalSeconds duration( 0 );
       
   319     TUint32 counter( 0 );
       
   320     
       
   321     TPtrC16 token( NULL, 0 );
       
   322     
       
   323     // Parse the WM DRM rights string
       
   324     TLex lex( aRights.Description() );
       
   325     
       
   326     // First, find the license type format string ("licensetype=") 
       
   327     ParseString( '=', lex, token );
       
   328     
       
   329     if ( token.CompareF( KLicenseType ) != 0 )
       
   330         {
       
   331         // License type format string was not found  
       
   332         User::Leave( KErrArgument );
       
   333         }
       
   334  
       
   335     // Peek for the end of string (eos) in case of (licensetype="") 
       
   336     ch = lex.Peek();
       
   337     if ( ch == 0 ) 
       
   338         {
       
   339         return;
       
   340         }
       
   341     
       
   342     // Check the license type
       
   343     ParseString( ';', lex, token );
       
   344     
       
   345     aRightsConstraint = CDRMRightsConstraints::NewL();
       
   346     CleanupStack::PushL( aRightsConstraint );
       
   347     
       
   348     // Check what kind of rights are in question by parsing the string
       
   349     // onward. The possible rights are date time (start time and/or end time),
       
   350     // count, duration, time count (count and/or date time) and unlimited
       
   351     // rights. The substrings for certain rights are further parsed in
       
   352     // specific methods. 
       
   353     if ( token.CompareF( KTime ) == 0 )
       
   354         {
       
   355         ParseWmDrmTimeRightsL( lex, startTime, endTime );
       
   356         if ( Time::NullTTime() != startTime )
       
   357             {
       
   358             aRightsConstraint->SetStartTime( startTime );
       
   359             }
       
   360         if ( Time::NullTTime() != endTime )
       
   361             {
       
   362             aRightsConstraint->SetEndTime( endTime );
       
   363             }
       
   364         }
       
   365     else if ( token.CompareF( KCount ) == 0 )
       
   366         {
       
   367         if ( ParseWmDrmCountRightsL( lex, counter ) )
       
   368             {
       
   369             aRightsConstraint->SetCounters( counter, counter );
       
   370             }
       
   371         }
       
   372     else if ( token.CompareF( KDuration ) == 0 )
       
   373         {
       
   374         if ( ParseWmDrmDurationRightsL( lex, duration ) )
       
   375             {
       
   376             aRightsConstraint->SetInterval( duration );
       
   377             }
       
   378         }
       
   379     else if ( token.CompareF( KTimeCount ) == 0 )
       
   380         {
       
   381         counter = 0;
       
   382         if ( ParseWmDrmCountRightsL( lex, counter ) )
       
   383             {
       
   384             aRightsConstraint->SetCounters( counter, counter );
       
   385             }
       
   386         ParseWmDrmTimeRightsL( lex, startTime, endTime );
       
   387         if ( Time::NullTTime() != startTime )
       
   388             {
       
   389             aRightsConstraint->SetStartTime( startTime );
       
   390             }
       
   391         if ( Time::NullTTime() != endTime )
       
   392             {
       
   393             aRightsConstraint->SetEndTime( endTime );
       
   394             }
       
   395         }
       
   396     else if ( token.CompareF( KUnlimited ) != 0 )
       
   397         {
       
   398         // Unknown license type  
       
   399         User::Leave( KErrArgument );
       
   400         }
       
   401           
       
   402     CleanupStack::Pop( aRightsConstraint );
       
   403         
       
   404     }
       
   405 
       
   406 // -----------------------------------------------------------------------------
       
   407 // DrmUtilityWmDrmUtilities::CheckWmDrmRightsL
       
   408 // -----------------------------------------------------------------------------
       
   409 //
       
   410 EXPORT_C void DrmUtilityWmDrmUtilities::CheckWmDrmRightsL( TBool& aUnconstrained, 
       
   411     TTimeIntervalSeconds& aTime,
       
   412     TInt& aCounts,  
       
   413     ContentAccess::CRightsInfo& aRights )
       
   414     {
       
   415     
       
   416     TChar ch;
       
   417     TPtrC16 token( NULL, 0 );
       
   418     TInt constraints( 0 );
       
   419     TInt error( KErrNone );
       
   420     TTime startTime( Time::NullTTime() );
       
   421     TTime endTime( Time::NullTTime() );
       
   422     TUint32 counter( 0 );
       
   423     TTime now( Time::NullTTime() ); // current time
       
   424     // End time of rights when duration is taken into account.
       
   425     TTime durationEndTime( Time::NullTTime() );
       
   426     TTimeIntervalSeconds secondsLeft( 0 ); // seconds to end of time based rights
       
   427     
       
   428     // Parse WM DRM rights string  
       
   429     TLex lex( aRights.Description() );
       
   430     
       
   431     // First, find the license type format string ("licensetype=") 
       
   432     ParseString( '=', lex, token );
       
   433     
       
   434     if ( token.CompareF( KLicenseType ) != 0 )
       
   435         {
       
   436         // License type format string was not found  
       
   437         User::Leave( KErrArgument );
       
   438         }
       
   439     
       
   440     // Peek for the end of string (Eos) in case of (licensetype="") 
       
   441     ch = lex.Peek();
       
   442     if ( ch == 0 ) 
       
   443         {
       
   444         return;
       
   445         }
       
   446     
       
   447     // Check the license type
       
   448     ParseString( ';', lex, token );
       
   449     
       
   450     // Check what kind of rights are in question by parsing the string
       
   451     // onward. The possible rights are date time (start time and/or end time),
       
   452     // count, duration, time count (count and/or date time) and unlimited
       
   453     // rights. The substrings for certain rights are further parsed in
       
   454     // specific methods. 
       
   455     if ( token.CompareF( KTime ) == 0 )
       
   456         {
       
   457         ParseWmDrmTimeRightsL( lex, startTime, endTime );
       
   458         if ( Time::NullTTime() != startTime )
       
   459             {
       
   460             constraints |= KWmDrmConstraintStartTime;
       
   461             }
       
   462         if ( Time::NullTTime() != endTime )
       
   463             {
       
   464             constraints |= KWmDrmConstraintEndTime;
       
   465             }
       
   466         }
       
   467     else if ( token.CompareF( KCount ) == 0 )
       
   468         {
       
   469         if ( ParseWmDrmCountRightsL( lex, counter ) )
       
   470             {
       
   471             aCounts = counter;
       
   472             constraints |= KWmDrmConstraintCount;
       
   473             }    
       
   474         }
       
   475     else if ( token.CompareF( KDuration ) == 0 )
       
   476         {
       
   477         if ( ParseWmDrmDurationRightsL( lex, aTime ) )
       
   478             {
       
   479             if ( aTime < (TTimeIntervalSeconds)0 )
       
   480                 {
       
   481                 aTime = 0;
       
   482                 }
       
   483             constraints |= KWmDrmConstraintDuration;
       
   484             }
       
   485         }
       
   486     else if ( token.CompareF( KTimeCount ) == 0 )
       
   487         {
       
   488         if ( ParseWmDrmCountRightsL( lex, counter ) )
       
   489             {
       
   490             aCounts = counter;
       
   491             constraints |= KWmDrmConstraintCount;
       
   492             }
       
   493         ParseWmDrmTimeRightsL( lex, startTime, endTime );
       
   494         if ( Time::NullTTime() != startTime )
       
   495             {
       
   496             constraints |= KWmDrmConstraintStartTime;
       
   497             }
       
   498         if ( Time::NullTTime() != endTime )
       
   499             {
       
   500             constraints |= KWmDrmConstraintEndTime;
       
   501             }
       
   502         }        
       
   503     else if ( token.CompareF( KUnlimited ) == 0 ) 
       
   504         {
       
   505         aUnconstrained = ETrue;
       
   506         return;
       
   507         }
       
   508     else 
       
   509         {
       
   510         // Unknown license type
       
   511         User::Leave( KErrArgument );
       
   512         }
       
   513     
       
   514     // Get current time
       
   515     now.HomeTime();
       
   516         
       
   517     // The rights are not constrained
       
   518     if ( !constraints )
       
   519         {
       
   520         aUnconstrained = ETrue;
       
   521         }
       
   522     
       
   523     if ( constraints & KWmDrmConstraintStartTime )
       
   524         {
       
   525         // The start time is in the past or the current time
       
   526         if ( ( now >= startTime ) && 
       
   527             !( constraints & KWmDrmConstraintEndTime ) &&
       
   528             !( constraints & KWmDrmConstraintCount ) )
       
   529             {
       
   530             aUnconstrained = ETrue;
       
   531             }
       
   532         
       
   533         // This use case is unclear and should be specified later.
       
   534         // There are counts for the content, but the start time has
       
   535         // not been reached.    
       
   536         if ( ( constraints & KWmDrmConstraintCount ) &&
       
   537             ( now < startTime ) ) 
       
   538             {
       
   539             aCounts = 0;
       
   540             }               
       
   541         }
       
   542     
       
   543     // Find out the amount of time that the rights have left in
       
   544     // case the rights have end time constraint.
       
   545     if ( constraints & KWmDrmConstraintEndTime )
       
   546         {
       
   547         error = endTime.SecondsFrom( now, secondsLeft );
       
   548         
       
   549         // The difference between current time and the end time does not
       
   550         // fit to 32-bit number, the start time has been reached and there
       
   551         // are no count constraints defined.
       
   552         if ( ( error == KErrOverflow ) && 
       
   553             ( !( constraints & KWmDrmConstraintStartTime ) || 
       
   554             ( now >= startTime ) ) && !( constraints & KWmDrmConstraintCount ) )
       
   555             {
       
   556             aUnconstrained = ETrue;
       
   557             }
       
   558         
       
   559         // End time has not been reached and start time has been reached
       
   560         if ( ( secondsLeft > (TTimeIntervalSeconds)0 ) && ( now >= startTime ) )
       
   561             {
       
   562             aTime = secondsLeft;
       
   563             }
       
   564        
       
   565         // This use case is unclear and should be specified later.
       
   566         // There are counts for the content, but the end time has
       
   567         // been reached.
       
   568         if ( ( constraints & KWmDrmConstraintCount ) &&
       
   569             ( now > endTime ) )
       
   570             {
       
   571             aCounts = 0;
       
   572             }
       
   573         }
       
   574         
       
   575     return;
       
   576     
       
   577     }
       
   578     
       
   579 // End of File
       
   580