Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


How to use Streaming CAF

[Top]


Purpose

This document gives guidance on how the streaming player middleware, for example the DVB-H middleware,n uses Streaming CAF.

[Top]


Contents

For background information on CAF Streaming Agents, see CAF Streaming Agent overview.

[Top]


Introduction

To access a particular broadcast, the CAF framework needs to find a CAF Streaming Agent that supports the standard with which the broadcast's data stream is protected, for example IPSec. The CAF Streaming Agent decrypts the short-term key message and this is used to decrypt the data. To do this, the streaming player middleware can initialise a key stream decoder.

Figure 1: Process and components diagram...


Figure 1: Process and components diagram (for IPSec) showing streaming player middleware

Note that the streaming player middleware is implemented as a separate ECOM plug-in.

Please note that this diagram assumes a separation of application and multimedia processes. This separation is optional and may not be present in all cases. Without this separation, the application process would include components displayed in the multimedia process and would need to be trusted and to have DRM capability.

Important disclaimer: The process boundary between the Multimedia process and the CAF streaming agent server process is not enforced by Symbian. This is strongly recommended, since otherwise no DRM trusted path can be established for protected content.

[Top]


Sesssion set-up and teardown

The following sequence diagram shows set-up of the streaming session.

Figure 2: Session set-up sequence diagra...


Figure 2: Session set-up sequence diagram

Figure 3: Session tear-down sequence dia...


Figure 3: Session tear-down sequence diagram

[Top]


Initialising the key stream decoder

The CKeyStreamDecoder class provides an interface for initialising key stream decoders.

Key stream decoders do the following:

The following code segment shows a key stream decoder being initialised and queries attributes from the server. Note that to process a key stream, the key stream decoder needs to remain active.

/* In this code sample, a key stream decoder is created to decode a key stream which 
   is protected by IPSec. Create a protected stream descriptor for IPSec.
   serverAddr => source connection address (content distributor in real case). 
   This address can be extracted from the SDP (Session Descripton Protocol).
   It is assumed that the client has already received this object.
   clientAddr => target connection address (device in real case).
   For more information about CProtectedStreamDesc, see protectedstreamdesc.h 
   and ipsecprotectedstreamdesc.cpp.
*/
CProtectedStreamDesc *protectedStreamDesc = CIpSecProtectedStreamDesc::NewLC(serverAddr, clientAddr);

/* The relevant media field for the key stream (CSdpMediaField* keyStreamSDPDesc) is 
  extracted from the SDP (CSdpDocument* sdpDocument).
   ......
   Now create the key stream decoder by using the protected stream descriptor, the key stream media 
   field, and the whole SDP object. For more information please look at keystreamdecoder.h and 
   keystreamdecoder.cpp
*/
CKeyStreamDecoder *keyStreamDecoder = CKeyStreamDecoder::NewLC(protectedStreamDesc, keyStreamSDPDesc, 
 sdpDocument);
Cleanupstack::PopAndDestroy(protectedStreamDesc);

If the next section of code is reached, the key stream decoder has been initialized correctly, and if the user has rights to view the stream, it will be decrypted. During the initialization of the key stream decoder, the streaming agent which can handle the requested key stream is resolved and launched. If the user had already subscribed to the service (or program) and the RO has not expired yet, the streaming agent loads this key stream and the key stream decoder object is created successfully. After that, the streaming agent performs the new key processing task in the background to get the protected data stream decrypted. The key processing task for IPSec is to decrypt STKM (Short Term Key Message, being received as the key stream) and to extract the corresponding cryptographic context. This object must be kept alive while receiving the key stream and decrypting the protected streamed data. If the user doesn't have the rights to view the stream (e.g. no rights for a specific pay-per-view program), no cryptographic context will be set.

To get any information about the protected stream content, one can query the streaming agent by using the created key stream decoder object. For example, the playability of the protected content can be queried as follows:

TBool playable = EFalse;
keyStreamDecoder->GetAttributeL(ECanPlay, playable);
// All attributes that can be queried from the streaming agent are defined in streamcaftypes.h.

// When the protected key stream receiving has finished or stopped, the key decoder object is destroyed.
Cleanupstack::PopAndDestroy(keyStreamDecoder);

The following code segment shows an example of recording protected streamed content with post-acquisition rights.

// Generate a protected key stream description for IPSec
CProtectedStreamDesc *protectedStreamDesc = CIpSecProtectedStreamDesc::NewLC(serverAddr, clientAddr);
// Create a key stream decoder 
CKeyStreamDecoder *keyStreamDecoder = CKeyStreamDecoder::NewLC(protectedStreamDesc, keyStreamSDPDesc,
 sdpDocument);
//Check whether the content is recordable
TBool value = EFalse;
keyStreamDecoder->GetAttributeL(ECanExport, value);
if(!value)
    {
    User::Leave(KErrCANotSupported);
    }
/* Get an import handle to record the protected streamed data in 3GPP video format
   By using the import handle, the streamed content will be recorded as protected together
   with its post-acquisition Rights Object. After importing, the recorded content is reached
   according to the restrictions defined in the post-acquisition Rights Object.
*/
CImportFile* import = keyStreamDecoder->CreateImportSessionLC(_L8("video/3gpp")); 

TPtr8 decryptedContent;
 do
    {
    // Decrypt the protected streamed content and assign to decryptedContent pointer.
    import->WriteData(decryptedContent);
    } while (decryptedContent);

 // Import has been completed.
TFileName fileName;
TInt err = import->WriteDataComplete();
while (err == KErrCANewFileHandleRequired)              
     {
     err = ProvideNewOutputFileL(*import, fileName);
     if(err == KErrNone)
       {
       err = import->WriteDataComplete();
       }
     }
User::LeaveIfError(err);

[Top]


Error handling

The streaming player middleware must be aware when a stream cannot be played because of lack of rights. In the regular file DRM standard scenario, this task is relatively easy, since the CAF agent can check during instantiation of ContentAccess::CData that corresponding rights exist.

In the streaming scenario, this task is more complicated:

These limitations imply that CAF cannot report during instantiation of key stream decoder whether the stream can actually be decoded. It can only report that the specific standard is supported, and that there is a key stream decoder which will attempt to decrypt the key stream. Until the actual key messages start arriving, the key stream decoder cannot know whether it will be able to decrypt the short-term keys. If no decrypted information arrives (or, if for ISMACryp, it cannot be decrypted) the controller needs to poll to verify this. The multimedia controller must use the CKeyStreamDecoder::GetAttribute() method with the TAttribute parameter ECanPlay to do this. This way, if the decryption process fails, and the multimedia controller does not have any plaintext data available, it can query the key stream decoder whether it fails to decrypt short-term keys. If key packets cannot be decrypted, the decoder should drop them silently, and thus, it cannot push this information to the multimedia controller.