Framework de CAS

El framework de sistemas de acceso condicional de medios (Media CAS) proporciona APIs estándar para habilitar servicios de acceso condicional (CA) en una variedad de hardware de TV digital, incluidos sistemas de cable digital, satélites, terrestres y sistemas IPTV. El framework funciona con el framework de entrada de Android TV y el framework de sintonizador de Android TV, y proporciona APIs de Java que se invocan desde la app del servicio de entrada de TV (TIS).

Los objetivos principales de Media CAS son los siguientes:

  • Proporcionar una API pública de Java y un framework de complementos nativos que los desarrolladores externos y los OEM puedan usar para admitir CAS para la transmisión de TV en Android.
  • Proporciona un framework de CAS dentro de Android que permita a los OEM de ATV interoperar con una variedad de proveedores de CAS de manera coherente.
  • Admite varios proveedores de CAS de terceros con complementos nativos. Los complementos CAS pueden usar protocolos de red específicos del proveedor, formatos de mensajes de administración de derechos (EMM)/mensajes de control de derechos (ECM) y decodificadores.
  • Brinda compatibilidad con la seguridad de hardware, como las llaves de acceso.
  • Brinda compatibilidad con entornos de ejecución confiables (TEE), como TrustZone.

Parámetros de configuración compatibles

Configuración del sintonizador de hardware

Si el hardware es responsable de la demultiplexación y la descodificación de la transmisión de transporte de MPEG, el marco de trabajo de Tunener proporciona datos de información específica del programa de acceso condicional (PSI) a la app de TIS para interactuar con sintonizadores de TV basados en hardware.

Los datos de PSI de acceso condicional incluyen descriptores de la AC, ECM y EMM. Estas estructuras permiten que el complemento de CAS obtenga las claves necesarias para desencriptar los flujos de contenido.

Diagrama de la configuración del sintonizador de hardware

Figura 1: Configuración del sintonizador de hardware

La configuración de hardware puede tener una capa de TEE, como TrustZone, que se ilustra en la Figura 1. Si no hay una capa de TEE, un complemento de cliente CAS puede comunicarse con los servicios de escalera de claves de hardware que proporciona la plataforma. Debido a las variaciones específicas de cada proveedor de estas interfaces, Media CAS no las estandariza.

Configuración de software

Antes de Android 11, el framework Media CAS aún se podía usar para procesar contenido basado en software, como IPTV de multidifusión o unidifusión de IP. La app de TIS es responsable de crear una instancia y aprovisionar correctamente el objeto Media CAS de Java.

Es posible que la app use MediaExtractor o algún otro analizador MPEG2-TS para extraer datos de PSI relacionados con la AC, como descriptores de AC, ECM y EMM. Si la app usa el framework MediaExtractor, puede delegar la administración de la sesión de CAS, como abrir una sesión y procesar EMM/ECM, al framework MediaExtractor. Luego, MediaExtractor configura la sesión de CAS directamente con la API nativa.

De lo contrario, la app es responsable de extraer los datos de PSI relacionados con la AC y configurar la sesión de CAS con las APIs de Media CAS Java (por ejemplo, cuando la app usa su propio analizador de MPEG2-TS).

Diagrama de la configuración del sintonizador.

Figura 2: Configuración de entrada de IPTV, CAS y descrambler con el framework MediaExtractor

En la situación del extractor de software, el extractor requiere un objeto decodificador basado en software o hardware para cada pista codificado, sin importar si la pista llama a decodificadores seguros. Esto se debe a los siguientes motivos:

  • Si la pista no requiere una decodificación segura, el extractor decodifica la unidad de acceso para borrar los búferes y extrae las muestras como si fueran de una transmisión clara. De esta manera, MediaCodec no necesita participar en la desviación.
  • Si la pista requiere una decodificación segura, es posible que el extractor aún necesite un descodificador. Esto sucede cuando la transmisión de transporte se codifica a nivel del paquete de transporte, donde se codifica el encabezado de la transmisión elemental empaquetada (PES). El extractor debe acceder al encabezado de PES para transferir cierta información (por ejemplo, la marca de tiempo de presentación).

    El extractor no usa el descodificador si la transmisión de transporte está desordenada a nivel del paquete PES, donde el encabezado PES queda claro. Sin embargo, no es posible confirmar cuándo se produce la codificación hasta que llega el paquete codificado. Para simplificar, supongamos que se usa un decodificador si se determina que el segmento está desordenado según la tabla de asignación del programa (PMT).

Limitaciones de la configuración de software

Cuando la pista requiere una decodificación segura, el decodificador debe tener cuidado cuando permite que una operación decodifica en búferes claros. Debido a que se requiere una decodificación de audio no segura, si la decodificación de video requiere decodificadores seguros, se debe codificar en una sesión diferente a la del audio. La ECM de la sesión debe indicarle al complemento que se requiere un decodificador seguro.

Como alternativa, el complemento debe poder vincular de forma confiable una clave a su política de seguridad. De lo contrario, la app puede obtener fácilmente fotogramas de video con el descodificador de audio.

Incluso cuando la sesión requiere un decodificador seguro, es posible que el extractor le solicite que genere una pequeña cantidad de datos para borrar los búferes y procesar el encabezado PES. Para evitar que una app maliciosa haga que el complemento devuelva toda la unidad de acceso, el complemento debe analizar la carga útil de transporte para asegurarse de que comience con un encabezado de PES del tipo de transmisión adecuado. De lo contrario, el complemento debe rechazar la solicitud.

Secuencia de ajuste de CA

Cuando se realiza un ajuste a un canal nuevo, el módulo TIS se registra para recibir descriptores de CA, ECM y EMM del framework de PSI Tuner. Un descriptor de AC contiene el ID del sistema de AC, que identifica de manera inequívoca a un proveedor de AC específico y otros datos específicos del proveedor. TIS consulta el CAS de Media para determinar si existe un complemento de CAS que pueda controlar el descriptor de AC.

Diagrama del contenido de ajuste de CAS.

Figura 3: Cómo ajustar el contenido de CAS

Si se admite el ID del sistema de la AC, se crea una instancia del CAS de Media y se proporcionan al complemento los datos privados del proveedor del descriptor de la AC. Luego, se abren nuevas sesiones en Media CAS para controlar las transmisiones de audio y video. Las sesiones abiertas recientemente reciben ECM y EMM del complemento.

Ejemplo de flujo del complemento CAS

TIS entrega ECM al complemento de CAS con las APIs de Media CAS. Una ECM contiene la palabra de control encriptada, que debe desencriptarse con información de una EMM. El complemento CAS determina cómo adquirir un EMM para el recurso según la información específica del proveedor en el descriptor de AC, que proporciona el método setPrivateData().

Las EMM pueden entregarse en banda en la transmisión de contenido o fuera de banda mediante una solicitud de red iniciada por el complemento de CA. TIS usa el método processEMM() para entregar cualquier EMM de banda al complemento de CA.

Si se requiere una solicitud de red para obtener una EMM, el complemento de CA es responsable de realizar la transacción de red con un servidor de licencias.

Diagrama de un ejemplo de CAS

Figura 4: Ejemplo de complemento de CAS para el procesamiento de EMM y ECM

Cuando se recibe el EMM, el complemento de AC lo analiza para obtener la clave encriptada y desencriptar la palabra de control. La clave EMM encriptada y la palabra de control encriptada se pueden cargar en una escalera de claves o un entorno de confianza para realizar la desencriptación de la palabra de control y, luego, el desentrelazamiento del flujo de contenido.

API de Java de Media CAS

La API de Java de Media CAS contiene los siguientes métodos.

  • Muestra una lista de todos los complementos de AC disponibles en el dispositivo.

    class MediaCas.PluginDescriptor {
      public String getName();
      public int getSystemId();
    }
    static PluginDescriptor[] enumeratePlugins();
    
  • Crea una instancia de Media CAS para el sistema de AC especificado. Esto significa que el framework de Media CAS puede controlar varios sistemas de CAS de forma simultánea.

    MediaCas(int CA_system_id);
    MediaCas(@NonNull Context context, int casSystemId,
             @Nullable String tvInputServiceSessionId,
             @PriorityHintUseCaseType int priorityHint);
    
  • Registra un objeto de escucha de eventos y permite que la app especifique un controlador cuyo bucle se use.

    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);
    
  • Envía los datos privados del sistema de la AC. Los datos privados pueden provenir del descriptor de la AC, la tabla de acceso condicional o fuentes fuera de banda. No está asociado con una sesión en particular.

    void setPrivateData(@NonNull byte[] data);
    
  • Procesa un paquete de EMM.

    void processEmm(@NonNull byte[] data, int offset, int length);
    
  • Envía un evento a un sistema de AC. El formato del evento es específico para el esquema y opaco para el framework.

    void sendEvent(int event, int arg, @Nullable byte[] data);
    
  • Inicia una operación de aprovisionamiento del tipo especificado para un sistema de AC. Cuando un dispositivo se registra en un servicio de TV paga por primera vez, primero debe aprovisionarse en el servidor de CAS. Proporciona un conjunto de parámetros relacionados al dispositivo para el aprovisionamiento.

    void provision(String provisionString);
    
  • Activa una actualización de derechos. Cuando un usuario se suscribe a un canal nuevo (por ejemplo, respondiendo a un anuncio o agregando un canal en la guía de programación electrónica (EPG)), la app debería poder indicarles a los clientes de la AC que actualicen las claves de derechos.

    void refreshEntitlements(int refreshType);
    
  • Cierra el objeto Media CAS.

    void close();
    
  • Abre una sesión.

    Session openSession();
    Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode);
    
  • Cerrar una sesión abierta anteriormente

    void Session#close();
    
  • Proporciona los datos privados de la AC desde un descriptor de AC en el PMT, que puede ser de la información del programa o de la sección de información de ES, a una sesión de CAS.

    void Session#setPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data);
    
  • Procesa un paquete ECM para una sesión.

    void Session#processEcm(@NonNull byte[] data, int offset, int length);
    
  • Obtén el ID de sesión.

    byte[] Session#getSessionId();
    
  • Envía un evento de sesión a un sistema de AC. El formato del evento es específico del esquema y es opaco para el framework.

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