omadrm/drmplugins/drmrecognizer/src/RecDRM.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2002-2009 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:  Symbian recognizer for DRM protected files
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <apmrec.h>
       
    21 #include <apmstd.h>
       
    22 #include <ecom/ecom.h>
       
    23 #include <ecom/implementationproxy.h>
       
    24 
       
    25 #include "recdrm.h"
       
    26 
       
    27 #define RECOGNIZE_KEY_CHAIN
       
    28 
       
    29 // CONSTANTS
       
    30 const TUid KUidDRMRecognizer={ 0x101F51F4 };
       
    31 
       
    32 // Version must be 1 so that it conforms to OMA DRM 1.0 specification
       
    33 const TInt KDCFVersionSupported( 1 );
       
    34 
       
    35 // minimum size of supported mime-type
       
    36 const TInt KMinContentTypeLen( 3 );
       
    37 
       
    38 // maximum amount of buffer space we will ever use
       
    39 const TInt KMaxBufferLength=256;
       
    40 
       
    41 const TInt KDCFHeaderLength=3;
       
    42 const TInt KLengthBoxSize = 4;
       
    43 const TInt KLengthBoxType = 4;
       
    44 const TInt KLengthBoxSize64 = 8;
       
    45 const TInt KLengthVersion = 1;
       
    46 const TInt KLengthFlags = 3;
       
    47 
       
    48 _LIT8(KFTypPrefix, "ftyp");
       
    49 _LIT8(KODFPrefix, "odcf");
       
    50 _LIT8(KRoapTriggerElement, "roap-trigger:roapTrigger"); // before OMA spec CR, ROAP Trigger namespace prefix was roap-trigger 
       
    51 _LIT8(KRoapTriggerElement2, "roap:roapTrigger");
       
    52 _LIT8(KRoapTriggerType, "application/vnd.oma.drm.roap-trigger+xml");
       
    53 
       
    54 const TImplementationProxy ImplementationTable[] = 
       
    55 	    {
       
    56 	    IMPLEMENTATION_PROXY_ENTRY(0x101F6DB8, CApaDRMRecognizer::CreateRecognizerL)
       
    57 	    };
       
    58 
       
    59 #ifdef DRM_OMA2_ENABLED
       
    60 TUint32 ReadUint32FromBlock(const TDesC8& aBlock, TInt aOffset)
       
    61     {
       
    62     return (aBlock[aOffset] << 24) +
       
    63         (aBlock[aOffset + 1] << 16) +
       
    64         (aBlock[aOffset + 2] << 8) +
       
    65         aBlock[aOffset + 3];
       
    66     }
       
    67 
       
    68 TInt ReadIntFromBlock(const TDesC8& aBlock, TInt aOffset)
       
    69     {
       
    70     return (aBlock[aOffset] << 24) +
       
    71         (aBlock[aOffset + 1] << 16) +
       
    72         (aBlock[aOffset + 2] << 8) +
       
    73         aBlock[aOffset + 3];
       
    74     }
       
    75 
       
    76 TUint16 ReadUint16FromBlock(const TDesC8& aBlock, TInt aOffset)
       
    77     {
       
    78     return ((aBlock[aOffset] << 8) + aBlock[aOffset + 1]);
       
    79     }
       
    80 #endif
       
    81 
       
    82 CApaDRMRecognizer::CApaDRMRecognizer():
       
    83 	CApaDataRecognizerType( KUidDRMRecognizer,CApaDataRecognizerType::ENormal )
       
    84 {
       
    85 	
       
    86 	iCountDataTypes = 0;
       
    87 	return;
       
    88 }
       
    89 
       
    90 CApaDRMRecognizer::~CApaDRMRecognizer()
       
    91 {
       
    92 }
       
    93 
       
    94 
       
    95 CApaDataRecognizerType* CApaDRMRecognizer::CreateRecognizerL()
       
    96 {
       
    97 	return new (ELeave) CApaDRMRecognizer ();
       
    98 }
       
    99 	
       
   100 
       
   101 TUint CApaDRMRecognizer::PreferredBufSize()
       
   102 {
       
   103 	return KMaxBufferLength;
       
   104 }
       
   105 
       
   106 #ifdef _DEBUG
       
   107 TDataType CApaDRMRecognizer::SupportedDataTypeL( TInt aIndex ) const
       
   108 #else
       
   109 TDataType CApaDRMRecognizer::SupportedDataTypeL( TInt /*aIndex*/ ) const
       
   110 #endif
       
   111 {
       
   112 __ASSERT_DEBUG( aIndex >= 0 && aIndex < iCountDataTypes, User::Invariant() );
       
   113 	return TDataType( _L8("application/vdn.omd.drm.content") ); // this should never be run
       
   114 }
       
   115 
       
   116 void CApaDRMRecognizer::DoRecognizeL( const TDesC& aName, const TDesC8& aBuffer )
       
   117 {
       
   118 	if ( aBuffer.Size() < 3) 
       
   119         {
       
   120         return;
       
   121         }
       
   122 	
       
   123 #ifdef RECOGNIZE_KEY_CHAIN	
       
   124 	// Recognize device key chain
       
   125 	if ( aName.Length() > 3 && aName.Right(4).CompareF(_L(".dkc")) == 0)
       
   126         {
       
   127         iConfidence = ECertain;
       
   128         iDataType = TDataType( _L8("application/x-device-key-chain") );
       
   129         return;
       
   130         }
       
   131 #endif        
       
   132 	
       
   133 #ifdef DRM_OMA2_ENABLED
       
   134 	// Recognize ROAP Trigger
       
   135 	if ( RecognizeRoapTrigger( aBuffer ) )
       
   136         {
       
   137         return;
       
   138         }
       
   139 	
       
   140 	// Recognize DCFv2    
       
   141 	if ( RecognizeODF( aBuffer ) )
       
   142         {
       
   143         return;
       
   144         }   
       
   145 #endif	
       
   146 	// Recognize DCFv1
       
   147 	TUint8 version = aBuffer[0];
       
   148 	TUint8 contentTypeLen = aBuffer[1];
       
   149 	TUint8 contentURILen = aBuffer[2];
       
   150 
       
   151 	if ( contentTypeLen < KMinContentTypeLen || contentURILen == 0 ) 
       
   152 	{
       
   153 		return;
       
   154 	}
       
   155 	if ( version != KDCFVersionSupported ) 
       
   156 	{
       
   157 		return;
       
   158 	}
       
   159 
       
   160 	// Too little data received
       
   161 	if ( aBuffer.Size() < ( contentTypeLen + KDCFHeaderLength ) ) 
       
   162 	{
       
   163 		return;
       
   164 	}
       
   165 
       
   166 	TPtrC8 mimeType = aBuffer.Mid( KDCFHeaderLength, contentTypeLen );
       
   167 	if ( mimeType.Locate( '/' ) != KErrNotFound )
       
   168 	{
       
   169 		iConfidence = ECertain;
       
   170 		iDataType=TDataType( mimeType );	
       
   171 	}
       
   172 	
       
   173 	
       
   174 	return;
       
   175 }
       
   176 
       
   177 #ifdef DRM_OMA2_ENABLED
       
   178 TBool CApaDRMRecognizer::RecognizeRoapTrigger( const TDesC8& aBuffer )
       
   179 {
       
   180         if ( aBuffer.FindF( KRoapTriggerElement() ) != KErrNotFound
       
   181              || aBuffer.FindF( KRoapTriggerElement2() ) != KErrNotFound )
       
   182         {
       
   183             iConfidence = ECertain;
       
   184             iDataType=TDataType( KRoapTriggerType() );
       
   185             return ETrue;
       
   186         }
       
   187 	return EFalse;
       
   188 }
       
   189 
       
   190 TBool CApaDRMRecognizer::RecognizeODF( const TDesC8& aBuffer )
       
   191 {
       
   192 	if ( aBuffer.Size() < 24 ) return EFalse;
       
   193 	TPtrC8 ftypPrefix = aBuffer.Mid( 4, KFTypPrefix().Length() );
       
   194 	if ( KFTypPrefix().CompareF( ftypPrefix ) == KErrNone )
       
   195 	{
       
   196 		TPtrC8 odfPrefix = aBuffer.Mid( 8, KODFPrefix().Length() );
       
   197 		if ( KODFPrefix().CompareF( odfPrefix ) == KErrNone )
       
   198 		{
       
   199 			TBuf8<4> buffer;
       
   200     		TUint32 size;
       
   201     		TPtr8 ptr(NULL, 0);
       
   202     		TUint32 offset(20);
       
   203     
       
   204     		// ODRM box header
       
   205     		buffer.Zero();
       
   206     		buffer.Copy( aBuffer.Mid( offset, 4 ));
       
   207     		size = ReadUint32FromBlock( buffer, 0 );
       
   208     		offset += KLengthBoxSize + KLengthBoxType + KLengthVersion + KLengthFlags;
       
   209     		
       
   210     		if (size == 1)
       
   211         	{
       
   212         		offset += KLengthBoxSize64;
       
   213         	}
       
   214     		if ( aBuffer.Size() < offset+4 ) return EFalse;
       
   215     		
       
   216     		// Discrete headers box header
       
   217     		buffer.Zero();
       
   218     		buffer.Copy( aBuffer.Mid( offset, 4 ));
       
   219     		size = ReadUint32FromBlock( buffer, 0 );
       
   220     		offset += KLengthBoxSize + KLengthBoxType + KLengthVersion + KLengthFlags;
       
   221     		if ( size == 1 )
       
   222         	{
       
   223         		offset += KLengthBoxSize64;
       
   224         	}
       
   225     		if ( aBuffer.Size() < offset+1 ) return EFalse;
       
   226     		
       
   227     		// Content type
       
   228     		buffer.Zero();
       
   229     		buffer.Copy( aBuffer.Mid( offset, 1 ));
       
   230     		if ( aBuffer.Size() < offset + 1 + buffer[0] ) return EFalse;
       
   231     		TPtrC8 mimeType = aBuffer.Mid( offset+1, buffer[0] );
       
   232    			
       
   233    			iConfidence = ECertain;
       
   234 			iDataType=TDataType( mimeType );
       
   235 			return ETrue;
       
   236 		}
       
   237 		
       
   238 	}
       
   239 	return EFalse;
       
   240 }
       
   241 #endif
       
   242 
       
   243 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
       
   244     {
       
   245     aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
   246     return ImplementationTable;
       
   247     }
       
   248