Framework de CAS

El framework de sistemas de acceso condicional multimedia (Media CAS) proporciona APIs estándar para habilitar servicios de acceso condicional (CA) en una variedad de hardware de TV digital, incluidos los sistemas de cable digital, satelitales, terrestres y de 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 invocadas desde la app de servicio de entrada de TV (TIS).

Los principales objetivos de Media CAS son los siguientes:

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

Parámetros de configuración admitidos

Configuración del sintonizador de hardware

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

Los datos de PSI de acceso condicional incluyen descriptores de CA, ECM y EMM. Estas estructuras permiten que el complemento de CAS obtenga las claves necesarias para desencriptar las transmisiones 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 de CAS puede comunicarse con los servicios de escalera de claves de hardware que proporciona la plataforma. Debido a las variaciones específicas del proveedor de estas interfaces, Media CAS no las estandariza.

Config. de software

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

La app puede usar MediaExtractor o cualquier otro analizador de MPEG2-TS para extraer datos de PSI relacionados con la CA, como descriptores de CA, ECM y EMM. Si la app usa el framework de MediaExtractor, puede delegar la administración de sesiones de CAS, como abrir una sesión y procesar EMM/ECM, al framework de MediaExtractor. Luego, MediaExtractor configura la sesión de CAS con la API nativa directamente.

De lo contrario, la app es responsable de extraer los datos de PSI relacionados con la CA y configurar la sesión de CAS con las APIs de Java de Media CAS (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 decodificador con el framework de MediaExtractor

En el caso del extractor de software, el extractor requiere un objeto decodificador basado en software o hardware para cada pista codificada, independientemente de si la pista requiere decodificadores seguros. Esto se debe a lo siguiente:

  • Si la pista no requiere una decodificación segura, el extractor decodifica la unidad de acceso para borrar los búferes y extraer muestras como si fuera de una transmisión clara. De esta manera, MediaCodec no necesita participar en la decodificación.
  • Si la pista requiere una decodificación segura, es posible que el extractor aún necesite un decodificador. 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 necesita acceder al encabezado de PES para transmitir cierta información (por ejemplo, la marca de tiempo de presentación).

    El extractor no usa el decodificador si la transmisión de transporte se codifica a nivel del paquete de PES, donde el encabezado de PES se deja claro. Sin embargo, no es posible confirmar cuándo ocurre la codificación hasta que llega el paquete codificado real. Para simplificar, supongamos que se usa un decodificador si se determina que la pista está codificada según la tabla de asignación de programas (PMT).

Limitaciones de la configuración de software

Cuando la pista requiere una decodificación segura, el decodificador debe tener cuidado cuando permite una operación de decodificación 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 del audio. El ECM de la sesión debe indicarle al complemento que se requiere un decodificador seguro.

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

Incluso cuando la sesión requiere un decodificador seguro, es posible que se le solicite que genere una pequeña cantidad de datos para borrar los búferes del extractor para procesar el encabezado de PES. Para evitar que una app maliciosa haga que el complemento muestre 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 denegar la solicitud.

Secuencia de ajuste de CA

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

Diagrama del ajuste del contenido de la CAS.

Figura 3: Ajuste del contenido de CAS

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

Flujo de muestra del complemento de CAS

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

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

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

Diagrama de un CAS de ejemplo.

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

Cuando se recibe el EMM, el complemento de CA lo analiza para obtener la clave encriptada para desencriptar la palabra de control. La clave EMM encriptada y la palabra de control encriptada se pueden cargar en una escalera de claves o en un entorno confiable para realizar la desencriptación de la palabra de control y la posterior decodificación de la transmisión de contenido.

API de Java de Media CAS

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

  • Enumera todos los complementos de CA 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 CA 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 generador de bucles 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 CA. Los datos privados pueden provenir del descriptor de CA, la tabla de acceso condicional o fuentes fuera de banda. Esto 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 CA. El formato del evento es específico del 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 CA. 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 los 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 programas electrónica [EPG]), la app debería poder indicarle a los clientes de CA que actualicen las claves de derechos.

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

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

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

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

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

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

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

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