CAS-Framework

Das Media CAS-Framework (Media Conditional Access Systems) bietet Standard-APIs, um CA-Dienste (Conditional Access, bedingter Zugriff) auf einer Reihe von Digital-TV-Hardware zu ermöglichen, darunter digitale Kabel-, Satelliten-, terrestrische und IPTV-Systeme. Das Framework funktioniert mit dem Android TV Input Framework und dem Android TV Tuner Framework und bietet Java-APIs, die von der TIS-App (TV Input Service) aufgerufen werden.

Die Hauptziele von Media CAS sind:

  • Eine öffentliche Java API und ein natives Plug-in-Framework bereitstellen, die von Drittentwicklern und OEMs verwendet werden können, um CAS für Broadcast-TV in Android zu unterstützen.
  • Ein CAS-Framework in Android, das ATV-OEMs eine konsistente Interoperabilität mit einer Vielzahl von CAS-Anbietern ermöglicht.
  • Unterstützung mehrerer Drittanbieter für CAS mithilfe nativer Plug-ins CAS-Plug-ins verwenden möglicherweise anbieterspezifische Netzwerkprotokolle, EMM-/ECM-Formate (Entitlement Management Message/Entitlement Control Message) und Entschlüsseler.
  • Unterstützung von Hardwaresicherheit wie Schlüsselhierarchien.
  • Unterstützung von vertrauenswürdigen Ausführungsumgebungen (Trusted Execution Environments, TEEs) wie TrustZone.

Unterstützte Konfigurationen

Konfiguration des Hardware-Tuners

Wenn die Hardware für das Demultiplexing und die Entschlüsselung von MPEG-Transportstreams verantwortlich ist, stellt das Tuner-Framework der TIS-App programmspezifische Informationen (PSI) für den bedingten Zugriff zur Verfügung, um eine Schnittstelle zu hardwarebasierten TV-Tunern zu schaffen.

Zu den PSI-Daten für den bedingten Zugriff gehören CA-Deskriptoren, ECMs und EMMs. Diese Strukturen ermöglichen es dem CAS-Plug-in, die zum Entschlüsseln der Content-Streams erforderlichen Schlüssel abzurufen.

Diagramm der Hardware-Tuner-Konfiguration

Abbildung 1: Konfiguration des Hardware-Tuners

Die Hardwarekonfiguration kann eine TEE-Schicht wie TrustZone haben, wie in Abbildung 1 dargestellt. Wenn es keine TEE-Ebene gibt, kann ein CAS-Client-Plug-in mit Hardware-Schlüssel-Ladder-Diensten kommunizieren, die von der Plattform bereitgestellt werden. Aufgrund anbieterspezifischer Variationen dieser Schnittstellen werden sie von Media CAS nicht standardisiert.

Softwarekonfiguration

Vor Android 11 konnte das Media CAS-Framework weiterhin zur Verarbeitung von softwarebasierten Inhalten wie IPTV aus IP-Multicast/Unicast verwendet werden. Die TIS-App ist für die Instanziierung und ordnungsgemäße Bereitstellung des Media CAS-Java-Objekts verantwortlich.

Die App verwendet möglicherweise MediaExtractor oder andere MPEG2-TS-Parser, um CA-bezogene PSI-Daten wie CA-Deskriptoren, ECMs und EMMs zu extrahieren. Wenn die App das Framework MediaExtractor verwendet, kann sie die CAS-Sitzungsverwaltung, z. B. das Öffnen einer Sitzung und die Verarbeitung von EMM/ECM, an das Framework MediaExtractor delegieren. MediaExtractor konfiguriert die CAS-Sitzung dann direkt über die native API.

Andernfalls ist die App dafür verantwortlich, die CA-bezogenen PSI-Daten zu extrahieren und die CAS-Sitzung mit den Media CAS Java APIs zu konfigurieren (z. B. wenn die App ihren eigenen MPEG2-TS-Parser verwendet).

Diagramm der Tuner-Konfiguration.

Abbildung 2: IPTV-Eingabe, CAS und Descrambler-Konfiguration mit dem Framework „MediaExtractor“

Im Szenario mit dem Software-Extractor benötigt der Extractor für jeden verschlüsselten Track ein Software- oder hardwarebasiertes Entschlüsselungsobjekt, unabhängig davon, ob für den Track sichere Decoder erforderlich sind. Das hat folgende Gründe.

  • Wenn für den Track keine sichere Decodierung erforderlich ist, entschlüsselt der Extractor die Zugriffseinheit, um Puffer zu leeren, und extrahiert Samples wie aus einem unverschlüsselten Stream. So muss MediaCodec nicht in die Entschlüsselung einbezogen werden.
  • Wenn für den Track eine sichere Decodierung erforderlich ist, benötigt der Extractor möglicherweise weiterhin einen Descrambler. Dies geschieht, wenn der Transportstream auf Transportpaketebene verschlüsselt wird und der PES-Header (Packetized Elementary Stream) verschlüsselt ist. Der Extractor muss auf den PES-Header zugreifen, um bestimmte Informationen (z. B. den Präsentations-Zeitstempel) weiterzugeben.

    Der Descrambler wird vom Extractor nicht verwendet, wenn der Transportstream auf PES-Paketebene verschlüsselt ist und der PES-Header unverschlüsselt bleibt. Es ist jedoch nicht möglich, den Zeitpunkt der Verschlüsselung zu bestätigen, bis das tatsächlich verschlüsselte Paket eintrifft. Der Einfachheit halber wird davon ausgegangen, dass ein Entschlüssler verwendet wird, wenn der Track anhand der Program Mapping Table (PMT) als verschlüsselt erkannt wird.

Einschränkungen der Softwarekonfiguration

Wenn für den Track eine sichere Decodierung erforderlich ist, muss der Descrambler vorsichtig sein, wenn er einen Descramble-Vorgang in Clear-Puffer zulässt. Da eine unsichere Audiodecodierung erforderlich ist, sollte die Videodecodierung, wenn sie sichere Decoder erfordert, in einer anderen Sitzung als die Audiodecodierung verschlüsselt werden. Das ECM für die Sitzung muss dem Plug-in signalisieren, dass ein sicherer Decoder erforderlich ist.

Alternativ muss das Plug-in einen Schlüssel zuverlässig mit seiner Sicherheitsrichtlinie verknüpfen können. Andernfalls kann die App mit dem Audio-Descrambler ganz einfach Videoframes abrufen.

Auch wenn für die Sitzung ein sicherer Decoder erforderlich ist, kann es sein, dass eine kleine Menge an Daten ausgegeben werden muss, damit der Extractor Puffer leeren und den PES-Header verarbeiten kann. Damit eine schädliche App nicht das gesamte Zugriffsmodul zurückgeben kann, muss das Plug-in die Transportnutzlast parsen, um sicherzustellen, dass die Nutzlast mit einem PES-Header des entsprechenden Streamtyps beginnt. Andernfalls sollte das Plug-in die Anfrage ablehnen.

CA-Abstimmungssequenz

Beim Umschalten auf einen neuen Kanal registriert sich das TIS-Modul, um CA-Deskriptoren, ECMs und EMMs vom PSI Tuner-Framework zu empfangen. Ein CA-Deskriptor enthält die CA-System-ID, die einen bestimmten CA-Anbieter eindeutig identifiziert, sowie andere anbieterspezifische Daten. TIS fragt das Media CAS ab, um festzustellen, ob ein CAS-Plug-in vorhanden ist, das den CA-Deskriptor verarbeiten kann.

Diagramm zur Optimierung von CAS-Inhalten.

Abbildung 3: CAS-Inhalte anpassen

Wenn die CA-System-ID unterstützt wird, wird eine Instanz von Media CAS erstellt und die privaten Anbieterdaten aus dem CA-Deskriptor werden dem Plug-in zur Verfügung gestellt. Anschließend werden neue Sitzungen in Media CAS geöffnet, um die Audio- und Videostreams zu verarbeiten. Die neu geöffneten Sitzungen empfangen ECMs und EMMs für das Plug-in.

Beispiel für den CAS-Plug‑in-Ablauf

TIS stellt ECMs über Media CAS APIs an das CAS-Plug-in bereit. Ein ECM enthält das verschlüsselte Kontrollwort, das mit Informationen aus einem EMM entschlüsselt werden muss. Das CAS-Plug-in bestimmt, wie ein EMM für das Asset anhand anbieterspezifischer Informationen im CA-Deskriptor abgerufen wird, der von der Methode setPrivateData() bereitgestellt wird.

EMMs können im Contentstream oder außerhalb des Streams über eine vom CA-Plug-in initiierte Netzwerkanfrage bereitgestellt werden. TIS verwendet die processEMM()-Methode, um In-Band-EMMs an das CA-Plug-in zu senden.

Wenn eine Netzwerkanfrage erforderlich ist, um ein EMM zu erhalten, ist das CA-Plug-in für die Durchführung der Netzwerktransaktion mit einem Lizenzserver verantwortlich.

Diagramm eines Beispiel-CAS.

Abbildung 4: Beispiel für ein CAS-Plug-in für die EMM- und ECM-Verarbeitung

Wenn das EMM empfangen wird, parst das CA-Plug-in es, um den verschlüsselten Schlüssel zum Entschlüsseln des Kontrollworts zu erhalten. Der verschlüsselte EMM-Schlüssel und das verschlüsselte Kontrollwort können in eine Schlüsselkette oder eine vertrauenswürdige Umgebung geladen werden, um das Kontrollwort zu entschlüsseln und den Contentstream anschließend zu entschlüsseln.

Media CAS Java API

Die Media CAS Java API enthält die folgenden Methoden.

  • Alle verfügbaren CA-Plug-ins auf dem Gerät auflisten.

    class MediaCas.PluginDescriptor {
      public String getName();
      public int getSystemId();
    }
    static PluginDescriptor[] enumeratePlugins();
    
  • Erstellt eine Media CAS-Instanz für das angegebene CA-System. Das bedeutet, dass das Media CAS-Framework mehrere CAS-Systeme gleichzeitig verarbeiten kann.

    MediaCas(int CA_system_id);
    MediaCas(@NonNull Context context, int casSystemId,
             @Nullable String tvInputServiceSessionId,
             @PriorityHintUseCaseType int priorityHint);
    
  • Registrieren Sie einen Event-Listener und erlauben Sie der App, einen Handler anzugeben, dessen Looper verwendet wird.

    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);
    
  • Senden Sie die privaten Daten für das CA-System. Die privaten Daten können aus dem CA-Deskriptor, der Tabelle für bedingten Zugriff oder aus Out-of-Band-Quellen stammen. Das ist nicht mit einer bestimmten Sitzung verknüpft.

    void setPrivateData(@NonNull byte[] data);
    
  • EMM-Paket verarbeiten

    void processEmm(@NonNull byte[] data, int offset, int length);
    
  • Ein Ereignis an ein CA-System senden Das Format des Ereignisses ist spezifisch für das Schema und für das Framework nicht transparent.

    void sendEvent(int event, int arg, @Nullable byte[] data);
    
  • Einen Bereitstellungsvorgang des angegebenen Typs für ein CA-System initiieren. Wenn sich ein Gerät zum ersten Mal für einen Pay-TV-Dienst registriert, muss es zuerst auf dem CAS-Server bereitgestellt werden. Stellen Sie dem Gerät eine Reihe von zugehörigen Parametern für die Bereitstellung zur Verfügung.

    void provision(String provisionString);
    
  • Aktualisierung von Berechtigungen auslösen Wenn ein Nutzer einen neuen Kanal abonniert (z. B. durch Reaktion auf eine Anzeige oder durch Hinzufügen eines Kanals im EPG), sollte die App die CA-Clients anweisen können, Berechtigungsschlüssel zu aktualisieren.

    void refreshEntitlements(int refreshType);
    
  • Schließen Sie das Media CAS-Objekt.

    void close();
    
  • Öffnen Sie eine Sitzung.

    Session openSession();
    Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode);
    
  • Schließen Sie eine zuvor geöffnete Sitzung.

    void Session#close();
    
  • Stellen Sie die privaten CA-Daten aus einem CA-Deskriptor im PMT (Program Map Table) für eine CAS-Sitzung bereit. Diese Daten können aus dem Abschnitt mit den Programminformationen oder den ES-Informationen stammen.

    void Session#setPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data);
    
  • ECM-Paket für eine Sitzung verarbeiten.

    void Session#processEcm(@NonNull byte[] data, int offset, int length);
    
  • Rufen Sie die Sitzungs-ID ab.

    byte[] Session#getSessionId();
    
  • Senden Sie ein Sitzungsereignis an ein CA-System. Das Format des Ereignisses ist spezifisch für das Schema und für das Framework nicht transparent.

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