структура CAS

Фреймворк систем условного доступа к медиаконтенту (Media CAS) предоставляет стандартные API для реализации сервисов условного доступа (CA) на различных устройствах цифрового телевидения, включая цифровые кабельные, спутниковые, эфирные системы и системы IPTV. Фреймворк работает с фреймворками Android TV Input и Android TV Tuner , предоставляя API Java, вызываемые из приложения TV Input Service (TIS).

Основными задачами Media CAS являются:

  • Предоставить общедоступный API Java и собственную платформу плагинов, которые могут использоваться сторонними разработчиками и OEM-производителями для поддержки CAS для вещательного телевидения на Android.
  • Предоставить инфраструктуру CAS в Android, которая позволит производителям квадроциклов согласованно взаимодействовать с различными поставщиками CAS.
  • Поддержка нескольких сторонних поставщиков CAS с помощью собственных плагинов. Плагины CAS могут использовать сетевые протоколы, специфичные для поставщиков, форматы сообщений управления правами доступа (EMM)/сообщений контроля прав доступа (ECM) и дешифраторы.
  • Поддерживайте безопасность аппаратных средств, таких как ключевые лестницы.
  • Поддержка доверенных сред выполнения (TEE), таких как TrustZone.

Поддерживаемые конфигурации

Конфигурация аппаратного тюнера

Если оборудование отвечает за демультиплексирование и дескремблирование транспортного потока MPEG, инфраструктура тюнера предоставляет приложению TIS данные условного доступа к специфичной для программы информации (PSI) для взаимодействия с аппаратными ТВ-тюнерами.

Данные PSI условного доступа включают дескрипторы CA, ECM и EMM. Эти структуры позволяют плагину CAS получать ключи, необходимые для расшифровки потоков контента.

Схема конфигурации аппаратного тюнера.

Рисунок 1. Конфигурация аппаратного тюнера

Аппаратная конфигурация может включать уровень TEE, например, TrustZone, показанный на рисунке 1. При отсутствии уровня TEE клиентский плагин CAS может взаимодействовать с аппаратными сервисами управления ключами, предоставляемыми платформой. В связи с различиями в этих интерфейсах у разных производителей, Media CAS не стандартизирует их.

Конфигурация программного обеспечения

До Android 11 фреймворк Media CAS всё ещё можно было использовать для обработки программного контента, например, IPTV, передаваемого по IP multicast/unicast. Приложение TIS отвечает за создание и корректную подготовку Java-объекта Media CAS.

Приложение может использовать MediaExtractor или другие парсеры MPEG2-TS для извлечения данных PSI, связанных с CA, таких как дескрипторы CA, ECM и EMM. Если приложение использует фреймворк MediaExtractor, оно может делегировать управление сеансом CAS, например, открытие сеанса и обработку EMM/ECM, фреймворку MediaExtractor. Затем MediaExtractor настраивает сеанс CAS напрямую, используя нативный API.

В противном случае приложение отвечает за извлечение данных PSI, связанных с CA, и настройку сеанса CAS с использованием API-интерфейсов Java Media CAS (например, когда приложение использует собственный анализатор MPEG2-TS).

Схема конфигурации тюнера.

Рисунок 2. Настройка входа IPTV, CAS и дешифратора с использованием фреймворка MediaExtractor

В сценарии программного экстрактора экстрактору требуется программный или аппаратный объект дескремблера для каждого скремблированного трека, независимо от того, требует ли трек использования безопасных декодеров. Это обусловлено следующим:

  • Если дорожка не требует безопасного декодирования, экстрактор дескремблирует блок доступа, чтобы очистить буферы, и извлекает сэмплы, как будто из чистого потока. Таким образом, MediaCodec не участвует в дескремблировании.
  • Если дорожка требует безопасного декодирования, экстрактору может всё равно понадобиться дескремблер. Это происходит, когда транспортный поток скремблируется на уровне транспортных пакетов, где скремблируется заголовок пакетированного элементарного потока (PES). Экстрактору необходим доступ к заголовку PES для извлечения определённой информации (например, временной метки презентации).

    Дескремблер не используется экстрактором, если транспортный поток скремблируется на уровне PES-пакетов, где заголовок PES остаётся пустым. Однако невозможно определить момент скремблирования до получения самого скремблированного пакета. Для простоты предположим, что дескремблер используется, если дорожка определена как скремблированная на основе таблицы сопоставления программ (PMT).

Ограничения конфигурации программного обеспечения

Если дорожка требует безопасного декодирования, дескремблеру следует проявлять осторожность, допуская операцию дескремблирования в чистые буферы. Поскольку требуется незащищённое декодирование аудио, если для декодирования видео требуются защищённые декодеры, скремблирование следует проводить в сеансе, отличном от аудио. Модуль ECM для сеанса должен сообщать плагину о необходимости защищённого декодера.

В качестве альтернативы, плагин должен иметь возможность надёжно привязывать ключ к своей политике безопасности. В противном случае приложение может легко получить видеокадры с помощью аудиодешифратора.

Даже если сеанс требует безопасного декодера, экстрактор может запросить вывод небольшого объёма данных для очистки буферов при обработке заголовка PES. Чтобы вредоносное приложение не заставило плагин вернуть весь блок доступа, плагин должен проанализировать транспортную полезную нагрузку, чтобы убедиться, что она начинается с заголовка PES соответствующего типа потока. В противном случае плагин должен отклонить запрос.

последовательность настройки CA

При настройке на новый канал модуль TIS регистрируется для получения дескрипторов CA, ECM и EMM от фреймворка PSI Tuner. Дескриптор CA содержит идентификатор системы CA, который однозначно идентифицирует конкретного поставщика CA, а также другие данные, специфичные для этого поставщика. TIS запрашивает Media CAS, чтобы определить, существует ли плагин CAS, способный обрабатывать этот дескриптор CA.

Схема настройки содержимого CAS.

Рисунок 3. Настройка содержимого CAS

Если системный идентификатор CA поддерживается, создаётся экземпляр Media CAS, и личные данные поставщика из дескриптора CA передаются плагину. Затем в Media CAS открываются новые сеансы для обработки аудио- и видеопотоков. Вновь открытые сеансы получают ECM и EMM для плагина.

Пример работы плагина CAS

TIS доставляет ECM-данные в плагин CAS через API Media CAS. ECM-данные содержат зашифрованное контрольное слово, которое необходимо расшифровать с использованием информации из EMM-модуля. Плагин CAS определяет, как получить EMM-модуль для актива, на основе информации поставщика в дескрипторе CA, предоставляемой методом setPrivateData() .

EMM-сообщения могут доставляться внутри канала в потоке контента или вне канала с помощью сетевого запроса, инициированного плагином CA. TIS использует метод processEMM() для доставки любых внутриканальных EMM-сообщений плагину CA.

Если для получения EMM требуется сетевой запрос, плагин CA отвечает за выполнение сетевой транзакции с сервером лицензий.

Схема примера CAS.

Рисунок 4. Пример плагина CAS для обработки EMM и ECM

При получении EMM плагин CA анализирует его, чтобы получить зашифрованный ключ для расшифровки контрольного слова. Зашифрованный ключ EMM и зашифрованное контрольное слово могут быть загружены в ключевой иерархический алгоритм или доверенную среду для расшифровки контрольного слова и последующего дескремблирования потока контента.

API Java Media CAS

Media CAS Java API содержит следующие методы.

  • Перечислите все доступные плагины CA на устройстве.

    class MediaCas.PluginDescriptor {
      public String getName();
      public int getSystemId();
    }
    static PluginDescriptor[] enumeratePlugins();
    
  • Создайте экземпляр Media CAS для указанной системы CA. Это означает, что фреймворк Media CAS сможет обрабатывать несколько систем CAS одновременно.

    MediaCas(int CA_system_id);
    MediaCas(@NonNull Context context, int casSystemId,
             @Nullable String tvInputServiceSessionId,
             @PriorityHintUseCaseType int priorityHint);
    
  • Зарегистрируйте прослушиватель событий и разрешите приложению указать обработчик, цикл которого будет использоваться.

    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);
    
  • Отправьте приватные данные для системы CA. Приватные данные могут быть получены из дескриптора CA, таблицы условного доступа или из внешних источников. Они не связаны с конкретным сеансом.

    void setPrivateData(@NonNull byte[] data);
    
  • Обработать пакет EMM.

    void processEmm(@NonNull byte[] data, int offset, int length);
    
  • Отправка события в систему CA. Формат события зависит от схемы и непрозрачен для фреймворка.

    void sendEvent(int event, int arg, @Nullable byte[] data);
    
  • Инициируйте операцию подготовки указанного типа для системы CA. При первой регистрации устройства в услуге платного телевидения сначала необходимо подготовить его к работе на сервере CAS. Предоставьте устройству набор соответствующих параметров для подготовки.

    void provision(String provisionString);
    
  • Запустить обновление ключей прав. Когда пользователь подписывается на новый канал (например, откликаясь на рекламу или добавляя канал в электронный программный гид (EPG)), приложение должно иметь возможность сообщить клиентам CA о необходимости обновить ключи прав.

    void refreshEntitlements(int refreshType);
    
  • Закройте объект Media CAS.

    void close();
    
  • Откройте сессию.

    Session openSession();
    Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode);
    
  • Закрыть ранее открытый сеанс.

    void Session#close();
    
  • Предоставьте сеансу CAS личные данные CA из дескриптора CA в PMT, который может быть из раздела информации о программе или информации ES.

    void Session#setPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data);
    
  • Обработать пакет ECM для сеанса.

    void Session#processEcm(@NonNull byte[] data, int offset, int length);
    
  • Получите идентификатор сеанса.

    byte[] Session#getSessionId();
    
  • Отправка события сеанса в систему CA. Формат события зависит от схемы и непрозрачен для фреймворка.

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