Framework CAS

Il framework Media CAS (Media Conditional Access Systems) fornisce API standard per abilitare i servizi di accesso condizionato (CA) su una serie di hardware TV digitali, tra cui sistemi terrestri, via cavo e satellitari digitali e sistemi IPTV. Il framework funziona con il framework di input Android TV e il framework di sintonizzatore Android TV, fornendo API Java richiamate dall'app TV Input Service (TIS).

Gli obiettivi principali di Media CAS sono i seguenti.

  • Fornire un'API Java pubblica e un framework di plug-in nativo che possa essere utilizzato da OEM e sviluppatori di terze parti per supportare il CAS per la TV broadcast su Android.
  • Fornire un framework CAS in Android che consenta agli OEM di ATV di interagire con una serie di fornitori CAS in modo coerente.
  • Supporta più fornitori di CAS di terze parti utilizzando plug-in nativi. I plug-in CAS potrebbero utilizzare protocolli di rete specifici del fornitore, formati di messaggi di gestione dei diritti (EMM)/di controllo dei diritti (ECM) e decodificatori.
  • Supporta la sicurezza hardware, ad esempio le strutture a chiavi.
  • Supporta ambienti di esecuzione attendibili (TEE) come TrustZone.

Configurazioni supportate

Configurazione del sintonizzatore hardware

Se l'hardware è responsabile del demultiplexing e del decrittografia dello stream di trasporto MPEG, il framework Tuner fornisce all'app TIS i dati PSI (Informazioni sui programmi con accesso condizionale) per interfacciarsi con i sintonizzatori TV basati su hardware.

I dati PSI dell'accesso condizionale includono descrittori CA, ECM ed EMM. Queste strutture consentono al plug-in CAS di ottenere le chiavi necessarie per decriptare gli stream di contenuti.

Diagramma della configurazione del sintonizzatore hardware.

Figura 1. Configurazione del sintonizzatore hardware

La configurazione hardware potrebbe avere un livello TEE, come TrustZone, come illustrato nella Figura 1. Se non è presente un livello TEE, un plug-in client CAS può comunicare con i servizi di struttura a chiavi hardware forniti dalla piattaforma. A causa delle variazioni specifiche del fornitore di queste interfacce, Media CAS non le standardizza.

Configurazione del software

Prima di Android 11, il framework Media CAS poteva essere ancora utilizzato per elaborare contenuti basati su software, come l'IPTV da IP multicast/unicast. L'app TIS è responsabile dell'inizializzazione e del provisioning corretto dell'oggetto Java Media CAS.

L'app potrebbe utilizzare MediaExtractor o altri analizzatori MPEG2-TS per estrarre dati PSI relativi alle CA, come descrittori CA, ECM ed EMM. Se l'app utilizza il framework MediaExtractor, può delegare la gestione della sessione CAS, ad esempio l'apertura di una sessione e l'elaborazione di EMM/ECM, al framework MediaExtractor. MediaExtractor configura quindi la sessione CAS utilizzando direttamente l'API nativa.

In caso contrario, è responsabilità dell'app estrarre i dati PSI relativi alla CA e configurare la sessione CAS utilizzando le API Java Media CAS (ad esempio, quando l'app utilizza il proprio parser MPEG2-TS).

Diagramma della configurazione del sintonizzatore.

Figura 2. Configurazione di input IPTV, CAS e decodificatore utilizzando il framework MediaExtractor

Nello scenario dell'estrattore di software, l'estrattore richiede un oggetto decodificatore basato su software o hardware per ogni traccia criptata, indipendentemente dal fatto che la traccia richieda decodificatori sicuri. Questo è dovuto ai seguenti motivi.

  • Se la traccia non richiede la decodifica sicura, l'estrattore decodifica l'unità di accesso per svuotare i buffer ed estrarre i sample come se provenissero da un stream chiaro. In questo modo, MediaCodec non deve essere coinvolto nel decrittografia.
  • Se la traccia richiede una decodifica sicura, l'estrattore potrebbe comunque necessitare di un decodificatore. Questo accade quando lo stream di trasporto viene scrambling a livello di pacchetto di trasporto, dove l'intestazione del stream elementare impacchettato (PES) viene scrambling. L'estrattore deve accedere all'intestazione PES per trasmettere determinate informazioni a valle (ad esempio il timestamp della presentazione).

    Il decodificatore non viene utilizzato dall'estrattore se lo stream di trasporto è scrambled a livello di pacchetto PES, dove l'intestazione PES viene lasciata vuota. Tuttavia, non è possibile confermare quando si verifica la crittografia fino all'arrivo del pacchetto effettivamente criptato. Per semplicità, supponiamo che venga utilizzato un decodificatore se la traccia viene considerata criptata in base alla tabella di mappatura dei programmi (PMT).

Limitazioni della configurazione del software

Quando il canale richiede una decodifica sicura, lo scodificatore deve essere attento quando consente un'operazione di decodifica in buffer chiari. Poiché è necessaria la decodifica audio non sicura, se la decodifica video richiede decodificatori sicuri, l'audio deve essere criptato in una sessione diversa. L'ECM per la sessione deve segnalare al plug-in che è necessario un decodificatore sicuro.

In alternativa, il plug-in deve essere in grado di associare in modo affidabile una chiave al proprio criterio di sicurezza. In caso contrario, l'app può facilmente ottenere frame video con il decodificatore audio.

Anche quando la sessione richiede un decodificatore sicuro, all'estrattore potrebbe essere chiesto di produrre una piccola quantità di dati per svuotare i buffer al fine di elaborare l'intestazione PES. Per impedire a un'app dannosa di fare in modo che il plug-in recuperi l'intera unità di accesso, il plug-in deve analizzare il payload di trasporto per assicurarsi che inizi con un'intestazione PES del tipo di stream appropriato. In caso contrario, il plug-in deve rifiutare la richiesta.

Sequenza di ottimizzazione CA

Quando sintonizzi un nuovo canale, il modulo TIS si registra per ricevere descrittori CA, ECM ed EMM dal framework PSI Tuner. Un descrittore CA contiene l'ID sistema CA, che identifica in modo univoco un fornitore CA specifico e altri dati specifici del fornitore. TIS esegue query sul Media CAS per determinare se esiste un plug-in CAS in grado di gestire il descrittore CA.

Diagramma di ottimizzazione dei contenuti del CAS.

Figura 3. Ottimizzazione dei contenuti del CAS

Se l'ID sistema CA è supportato, viene creata un'istanza del Media CAS e i dati privati del fornitore dal descrittore CA vengono forniti al plug-in. Successivamente, in Media CAS vengono aperte nuove sessioni per gestire gli stream audio e video. Le sessioni appena aperte ricevono ECM ed EMM per il plug-in.

Flusso di esempio del plug-in CAS

TIS carica i contenuti multimediali nel plug-in CAS utilizzando le API Media CAS. Un file ECM contiene la parola di controllo criptata, che deve essere decriptata utilizzando le informazioni di un EMM. Il plug-in CAS determina come acquisire un EMM per la risorsa in base alle informazioni specifiche del fornitore nel descrittore CA, fornito dal metodo setPrivateData().

Gli EMM potrebbero essere inviati in banda nello stream di contenuti o out of band utilizzando una richiesta di rete avviata dal plug-in CA. TIS utilizza il metodo processEMM() per inviare eventuali EMM in banda al plug-in CA.

Se per ottenere un EMM è necessaria una richiesta di rete, il plug-in CA è responsabile dell'esecuzione della transazione di rete con un server delle licenze.

Diagramma di un CAS di esempio.

Figura 4. Esempio di plug-in CAS per l'elaborazione di EMM ed ECM

Quando viene ricevuto l'EMM, il plug-in CA lo analizza per ottenere la chiave criptata per decriptare la parola di controllo. La chiave EMM e la parola di controllo criptate potrebbero essere caricate in una struttura a scale di chiavi o in un ambiente attendibile per eseguire la decrittografia della parola di controllo e il successivo decrittografia dello stream di contenuti.

API Java Media CAS

L'API Java Media CAS contiene i seguenti metodi.

  • Elenca tutti i plug-in CA disponibili sul dispositivo.

    class MediaCas.PluginDescriptor {
      public String getName();
      public int getSystemId();
    }
    static PluginDescriptor[] enumeratePlugins();
    
  • Crea un'istanza Media CAS per il sistema CA specificato. Ciò significa che il framework Media CAS può gestire più sistemi CAS contemporaneamente.

    MediaCas(int CA_system_id);
    MediaCas(@NonNull Context context, int casSystemId,
             @Nullable String tvInputServiceSessionId,
             @PriorityHintUseCaseType int priorityHint);
    
  • Registra un gestore di eventi e consenti all'app di specificare un gestore di cui viene utilizzato il loop.

    interface MediaCas.EventListener {
      void onEvent(MediaCas, int event, int arg, byte[] data);
      void onSessionEvent(@NonNull MediaCas mediaCas, @NonNull Session session, int event, int arg, @Nullable byte[] data);
      void onPluginStatusUpdate(@NonNull MediaCas mediaCas, @PluginStatus int status, int arg);
      void onResourceLost(@NonNull MediaCas mediaCas);
    }
    void setEventListener(MediaCas.EventListener listener, Handler handler);
    
  • Invia i dati privati per il sistema CA. I dati privati possono provenire dal descrittore CA, dalla tabella di accesso condizionale o da origini out-of-band. Non è associato a una sessione specifica.

    void setPrivateData(@NonNull byte[] data);
    
  • Elabora un pacchetto EMM.

    void processEmm(@NonNull byte[] data, int offset, int length);
    
  • Invia un evento a un sistema CA. Il formato dell'evento è specifico per lo schema e opaco per il framework.

    void sendEvent(int event, int arg, @Nullable byte[] data);
    
  • Avvia un'operazione di provisioning del tipo specificato per un sistema CA. Quando un dispositivo si registra per la prima volta a un servizio di pay TV, deve prima essere eseguito il provisioning sul server CAS. Fornisci un insieme di parametri correlati al dispositivo per il provisioning.

    void provision(String provisionString);
    
  • Attivare un aggiornamento dei diritti. Quando un utente si abbona a un nuovo canale (ad esempio rispondendo a un annuncio o aggiungendo un canale nella guida elettronica dei programmi (EPG)), l'app dovrebbe essere in grado di indicare ai client CA di aggiornare le chiavi dei diritti.

    void refreshEntitlements(int refreshType);
    
  • Chiudi l'oggetto Media CAS.

    void close();
    
  • Apri una sessione.

    Session openSession();
    Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode);
    
  • Chiudere una sessione aperta in precedenza.

    void Session#close();
    
  • Fornisci i dati privati della CA da un descrittore CA nel PMT, che può essere proveniente dalla sezione Informazioni sul programma o Informazioni ES, a una sessione CAS.

    void Session#setPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data);
    
  • Elabora un pacchetto ECM per una sessione.

    void Session#processEcm(@NonNull byte[] data, int offset, int length);
    
  • Recupera l'ID sessione.

    byte[] Session#getSessionId();
    
  • Invia un evento di sessione a un sistema CA. Il formato dell'evento è specifico per lo schema ed è opaco per il framework.

    void Session#sendSessionEvent(int event, int arg, @Nullable byte[] data);