Framework CAS

Il framework Media Conditional Access Systems (Media CAS) fornisce API standard per abilitare i servizi di accesso condizionato (CA) su una gamma di hardware TV digitale, inclusi sistemi via cavo, satellitari, terrestri e IPTV. Il framework funziona con il framework di input di Android TV e il framework del sintonizzatore di 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 può essere utilizzato da sviluppatori di terze parti e OEM per supportare CAS per la TV broadcast in Android.
  • Fornire un framework CAS all'interno di Android che consenta agli OEM 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)/messaggi di controllo dei diritti (ECM) e decodificatori.
  • Supporta la sicurezza hardware, ad esempio le scale di chiavi.
  • Supporta Trusted Execution Environment (TEE) come TrustZone.

Configurazioni supportate

Configurazione del sintonizzatore hardware

Se l'hardware è responsabile del demultiplexing e della decodifica dello stream di trasporto MPEG, il framework del tuner fornisce dati PSI (program-specific information) di accesso condizionale all'app TIS per interfacciarsi con i tuner TV basati su hardware.

I dati PSI di 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, ad esempio TrustZone, come illustrato nella Figura 1. Se non è presente un livello TEE, un plug-in client CAS può comunicare con i servizi di laddering delle chiavi hardware forniti dalla piattaforma. A causa delle variazioni specifiche del fornitore di queste interfacce, Media CAS non le standardizza.

Configurazione software

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

L'app potrebbe utilizzare MediaExtractor o altri parser MPEG2-TS per estrarre dati PSI correlati alla 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, l'app è responsabile dell'estrazione dei dati PSI correlati alla CA e della configurazione della sessione CAS utilizzando le API Java Media CAS (ad esempio, quando l'app utilizza il proprio parser MPEG2-TS).

Diagramma della configurazione di Tuner.

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

Nello scenario di estrazione del software, l'estrattore richiede un oggetto decodificatore basato su software o hardware per ogni traccia codificata, indipendentemente dal fatto che la traccia richieda decodificatori sicuri. Ciò è dovuto a quanto segue.

  • Se la traccia non richiede la decodifica sicura, l'estrattore decodifica l'unità di accesso per svuotare i buffer ed estrae i campioni come se provenissero da un flusso chiaro. In questo modo MediaCodec non deve essere coinvolto nella decodifica.
  • Se la traccia richiede una decodifica sicura, l'estrattore potrebbe comunque aver bisogno di un decodificatore. Ciò si verifica quando lo stream di trasporto viene crittografato a livello di pacchetto di trasporto, dove l'intestazione dello stream elementare pacchettizzato (PES) è crittografata. L'estrattore deve accedere all'intestazione PES per trasmettere alcune informazioni (ad esempio, il timestamp di presentazione).

    Il decodificatore non viene utilizzato dall'estrattore se lo stream di trasporto è codificato a livello di pacchetto PES, dove l'intestazione PES viene lasciata in chiaro. Tuttavia, non è possibile confermare quando avviene la codifica finché non arriva il pacchetto codificato effettivo. Per semplicità, supponi che venga utilizzato un decodificatore se la traccia viene considerata codificata in base alla tabella di mapping dei programmi (PMT).

Limitazioni della configurazione software

Quando la traccia richiede una decodifica sicura, il decodificatore deve fare attenzione quando consente a un'operazione di decodifica di accedere ai buffer in chiaro. Poiché è necessaria la decodifica audio non sicura, se la decodifica video richiede decoder sicuri, deve essere eseguita in una sessione diversa da quella audio. 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 collegare in modo affidabile una chiave al relativo criterio di sicurezza. In caso contrario, l'app può ottenere facilmente i fotogrammi video con il decodificatore audio.

Anche quando la sessione richiede un decodificatore sicuro, potrebbe essere richiesto di restituire una piccola quantità di dati per svuotare i buffer da parte dell'estrattore per elaborare l'intestazione PES. Per impedire a un'app dannosa di fare in modo che il plug-in restituisca 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 flusso appropriato. In caso contrario, il plug-in deve rifiutare la richiesta.

Sequenza di ottimizzazione CA

Quando si sintonizza 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 su Media CAS per determinare se esiste un plug-in CAS in grado di gestire il descrittore CA.

Diagramma dell'ottimizzazione dei contenuti CAS.

Figura 3. Ottimizzazione dei contenuti CAS

Se l'ID sistema CA è supportato, viene creata un'istanza di Media CAS e i dati privati del fornitore del 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 plug-in CAS di esempio

TIS fornisce i moduli ECM al plug-in CAS utilizzando le API Media CAS. Un 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 l'asset in base alle informazioni specifiche del fornitore nel descrittore CA, fornito dal metodo setPrivateData().

Gli EMM possono essere forniti in banda nel flusso di contenuti o fuori banda utilizzando una richiesta di rete avviata dal plug-in CA. TIS utilizza il metodo processEMM() per fornire eventuali EMM in banda al plug-in CA.

Se è necessaria una richiesta di rete per ottenere un EMM, 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 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 criptata e la parola di controllo criptata potrebbero essere caricate in una scala di chiavi o in un ambiente attendibile per eseguire la decrittografia della parola di controllo e la successiva decodifica del flusso 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();
    
  • Costruisci 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 listener di eventi e consente all'app di specificare un gestore il cui looper viene utilizzato.

    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 fonti out-of-band. Non è associato a una sessione specifica.

    void setPrivateData(@NonNull byte[] data);
    
  • Elaborare 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 abbona a un servizio di TV a pagamento per la prima volta, deve prima essere sottoposto al provisioning sul server CAS. Fornisci un insieme di parametri correlati al dispositivo per il provisioning.

    void provision(String provisionString);
    
  • Attiva un aggiornamento dei diritti. Quando un utente si iscrive a un nuovo canale (ad esempio, rispondendo a una pubblicità o aggiungendo un canale alla guida elettronica dei programmi (EPG)), l'app deve essere in grado di comunicare ai client CA di aggiornare le chiavi di autorizzazione.

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

    void close();
    
  • Apri una sessione.

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

    void Session#close();
    
  • Fornisci i dati privati della CA da un descrittore della CA nella PMT, che può provenire dalla sezione delle informazioni sul programma o delle 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);