El marco de los sistemas de acceso condicional a los medios (Media CAS) proporciona API estándar para habilitar servicios de acceso condicional (CA) en una variedad de hardware de televisión digital, incluidos sistemas de cable digital, satélite, terrestres y sistemas de IPTV. El marco funciona con el marco Android TV Input y el marco Android TV Tuner , proporcionando API de Java invocadas desde la aplicación TV Input Service (TIS).
Los principales objetivos de Media CAS son los siguientes.
- Proporcione una API de Java pública y un marco de complementos nativos que puedan utilizar desarrolladores externos y OEM para admitir CAS para transmisiones de televisión en Android.
- Proporcionar un marco CAS dentro de Android que permita a los OEM de ATV interoperar con una variedad de proveedores de CAS de manera consistente.
- Admite múltiples proveedores de CAS externos mediante complementos nativos. Los complementos de CAS pueden utilizar protocolos de red específicos del proveedor, formatos de mensajes de gestión de derechos (EMM)/mensajes de control de derechos (ECM) y decodificadores.
- Admite seguridad de hardware, como escaleras de claves.
- Admite entornos de ejecución confiables (TEE) como TrustZone.
Configuraciones admitidas
Configuración del sintonizador de hardware
Si el hardware es responsable de la demultiplexación y descodificación del flujo de transporte MPEG, el marco Tuner proporciona datos de información específica del programa (PSI) de acceso condicional a la aplicación TIS para interactuar con 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 CAS obtenga las claves necesarias para descifrar los flujos de contenido.
Figura 1. Configuración del sintonizador de hardware
La configuración de hardware puede tener una capa TEE, como TrustZone, que se ilustra en la Figura 1. Si no hay una capa TEE, un complemento de cliente CAS puede comunicarse con los servicios de escalera de claves de hardware proporcionados por la plataforma. Debido a las variaciones de estas interfaces específicas del proveedor, Media CAS no las estandariza.
Configuración de software
Antes de Android 11, el marco Media CAS todavía se podía utilizar para procesar contenido basado en software, como IPTV desde multidifusión/unidifusión IP. La aplicación TIS es responsable de crear instancias y aprovisionar adecuadamente el objeto Java Media CAS.
La aplicación puede usar MediaExtractor u otros analizadores MPEG2-TS para extraer datos PSI relacionados con CA, como descriptores de CA, ECM y EMM. Si la aplicación utiliza el marco MediaExtractor, puede delegar la gestión de la sesión CAS, como abrir una sesión y procesar EMM/ECM, al marco MediaExtractor. Luego, MediaExtractor configura la sesión CAS utilizando la API nativa directamente.
De lo contrario, la aplicación es responsable de extraer los datos PSI relacionados con CA y configurar la sesión CAS usando las API Java de Media CAS (por ejemplo, cuando la aplicación usa su propio analizador MPEG2-TS).
Figura 2. Configuración de entrada de IPTV, CAS y decodificador utilizando el marco MediaExtractor
En el escenario del extractor de software, el extractor requiere un objeto descifrador 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 buffers y extrae muestras como si fuera una secuencia clara. De esta manera
MediaCodec
no necesita participar en la descodificación. Si la pista requiere una decodificación segura, es posible que el extractor aún necesite un decodificador. Esto sucede cuando el flujo de transporte se codifica en el nivel del paquete de transporte, donde se codifica el encabezado del flujo elemental paquetizado (PES). El extractor necesita acceder al encabezado PES para transmitir cierta información (por ejemplo, la marca de tiempo de presentación).
El extractor no utiliza el decodificador si el flujo de transporte está codificado en el nivel del paquete PES, donde el encabezado PES se deja en blanco. Sin embargo, no es posible confirmar cuándo ocurre la codificación hasta que llegue el paquete codificado real. Para simplificar, supongamos que se utiliza un descodificador si se determina que la pista está codificada basándose en la tabla de asignación de programas (PMT).
Limitaciones de la configuración del software
Cuando la pista requiere una decodificación segura, el decodificador debe tener cuidado al permitir una operación de decodificación en buffers claros. Debido a que se requiere una decodificación de audio insegura, si la decodificación de video requiere decodificadores seguros, se debe codificar en una sesión diferente a la del audio. El ECM de la sesión debe indicarle al complemento que se requiere un decodificador seguro.
Alternativamente, el complemento debe poder vincular de manera confiable una clave a su política de seguridad. De lo contrario, la aplicación puede obtener fácilmente fotogramas de vídeo 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 buffers para procesar el encabezado PES. Para evitar que una aplicación maliciosa haga que el complemento devuelva la unidad de acceso completa, el complemento debe analizar la carga útil de transporte para garantizar que comience con un encabezado PES del tipo de flujo apropiado. De lo contrario, el complemento debería rechazar la solicitud.
Secuencia de sintonización de CA
Al sintonizar un nuevo canal, el módulo TIS se registra para recibir descriptores de CA, ECM y EMM del marco 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 Media CAS para determinar si existe un complemento de CAS que pueda manejar el descriptor de CA.
Figura 3. Ajuste del contenido de CAS
Si se admite el ID del sistema CA, se crea una instancia de Media CAS y los datos privados del proveedor del descriptor de CA se proporcionan al complemento. Luego, se abren nuevas sesiones en Media CAS para manejar las transmisiones de audio y video. Las sesiones recién abiertas reciben ECM y EMM para el complemento.
Flujo de complemento CAS de muestra
TIS entrega ECM al complemento CAS mediante las API de Media CAS. Un ECM contiene la palabra de control cifrada, que debe descifrarse utilizando información de un EMM. El complemento CAS determina cómo adquirir un EMM para el activo en función de la información específica del proveedor en el descriptor de CA, que proporciona el método setPrivateData()
.
Los EMM pueden entregarse en banda en el flujo de contenido o fuera de banda mediante una solicitud de red iniciada por el complemento CA. TIS utiliza el método processEMM()
para entregar cualquier EMM en banda al complemento CA.
Si se requiere una solicitud de red para obtener un EMM, el complemento CA es responsable de realizar la transacción de red con un servidor de licencias.
Figura 4. Ejemplo de complemento CAS para procesamiento EMM y ECM
Cuando se recibe el EMM, el complemento CA lo analiza para obtener la clave cifrada para descifrar la palabra de control. La clave EMM cifrada y la palabra de control cifrada se pueden cargar en una escalera de claves o en un entorno confiable para realizar el descifrado de la palabra de control y la posterior descodificación del flujo de contenido.
API Java de CAS multimedia
La API Java de Media CAS contiene los siguientes métodos.
Enumere todos los complementos de CA disponibles en el dispositivo.
class MediaCas.PluginDescriptor { public String getName(); public int getSystemId(); } static PluginDescriptor[] enumeratePlugins();
Construya una instancia de Media CAS para el sistema CA especificado. Esto significa que el marco Media CAS puede manejar múltiples sistemas CAS simultáneamente.
MediaCas(int CA_system_id); MediaCas(@NonNull Context context, int casSystemId, @Nullable String tvInputServiceSessionId, @PriorityHintUseCaseType int priorityHint);
Registre un detector de eventos y permita que la aplicación especifique un controlador cuyo looper se utiliza.
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íe los datos privados para el sistema 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);
Procesar un paquete EMM.
void processEmm(@NonNull byte[] data, int offset, int length);
Enviar un evento a un sistema CA. El formato del evento es específico del esquema y opaco al marco.
void sendEvent(int event, int arg, @Nullable byte[] data);
Iniciar una operación de aprovisionamiento del tipo especificado para un sistema de CA. Cuando un dispositivo se registra en un servicio de televisión de pago por primera vez, primero debe aprovisionarse en el servidor CAS. Proporcione un conjunto de parámetros relacionados al dispositivo para su aprovisionamiento.
void provision(String provisionString);
Activar una actualización de derechos. Cuando un usuario se suscribe a un nuevo canal (por ejemplo, respondiendo a un anuncio o agregando un canal en la guía electrónica de programas (EPG)), la aplicación debería poder indicar a los clientes de CA que actualicen las claves de derechos.
void refreshEntitlements(int refreshType);
Cierre el objeto Media CAS.
void close();
Abrir una sesión.
Session openSession(); Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode);
Cerrar una sesión abierta anteriormente.
void Session#close();
Proporcione los datos privados de CA desde 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);
Procesar un paquete ECM para una sesión.
void Session#processEcm(@NonNull byte[] data, int offset, int length);
Obtenga el ID de la sesión.
byte[] Session#getSessionId();
Enviar un evento de sesión a un sistema CA. El formato del evento es específico del esquema y opaco al marco.
void Session#sendSessionEvent(int event, int arg, @Nullable byte[] data);