Das Media CAS-Framework (Media Conditional Access Systems) bietet Standard-APIs, um Dienste für den bedingten Zugriff (Conditional Access, CAS) auf einer Reihe von digitaler TV-Hardware zu ermöglichen, darunter digitale Kabel-, Satelliten-, terrestrische Systeme und IPTV-Systeme. Das Framework funktioniert mit dem Android TV-Eingabe-Framework und dem Android TV-Tuner-Framework und stellt Java APIs bereit, 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, das von Drittentwicklern und OEMs zur Unterstützung von CAS für Fernsehübertragungen in Android verwendet werden kann.
- Bereitstellung eines CAS-Frameworks innerhalb von Android, das es ATV-OEMs ermöglicht, mit einer Vielzahl von CAS-Anbietern auf einheitliche Weise zusammenzuarbeiten.
- Unterstützung mehrerer CAS-Drittanbieter mithilfe nativer Plug-ins. CAS-Plug-ins können anbieterspezifische Netzwerkprotokolle, EMM-/ECM-Formate (Berechtigungsverwaltungsnachrichten) und Entschlüsseler verwenden.
- Sie müssen die Hardwaresicherheit wie Schlüsselleitern unterstützen.
- Unterstützung für vertrauenswürdige Ausführungsumgebungen (Trusted Execution Environments, TEEs) wie TrustZone.
Unterstützte Konfigurationen
Hardware-Tuner-Konfiguration
Wenn die Hardware für das Demultiplexing und Entschlüsseln von MPEG-Transportstreams verantwortlich ist, stellt das Tuner-Framework der TIS-App PSI-Daten (Conditional Access Program-Specific Information) bereit, um eine Verbindung zu hardwarebasierten TV-Tunern herzustellen.
Zu den PSI-Daten für den bedingten Zugriff gehören CA-Beschreibungen, ECMs und EMMs. Diese Strukturen ermöglichen es dem CAS-Plug-in, Schlüssel abzurufen, die zum Entschlüsseln der Inhaltsstreams erforderlich sind.
Abbildung 1. Konfiguration des Hardware-Tuners
Die Hardwarekonfiguration kann eine TEE-Schicht wie TrustZone haben, wie in Abbildung 1 dargestellt. Wenn keine TEE-Ebene vorhanden ist, kann ein CAS-Client-Plug-in mit Hardware-Schlüsselleiterdiensten kommunizieren, die von der Plattform bereitgestellt werden. Aufgrund anbieterspezifischer Variationen dieser Schnittstellen standardisiert Media CAS sie nicht.
Softwarekonfiguration
Vor Android 11 konnte das Media CAS-Framework noch zur Verarbeitung softwarebasierter Inhalte verwendet werden, z. B. IPTV aus IP-Multicast/Unicast. Die TIS-Anwendung ist für die Instanziierung und ordnungsgemäße Bereitstellung des Media CAS-Java-Objekts verantwortlich.
Die Anwendung kann MediaExtractor oder andere MPEG2-TS-Parser verwenden, um CA-bezogene PSI-Daten wie CA-Deskriptoren, ECMs und EMMs zu extrahieren. Wenn die App das MediaExtractor-Framework verwendet, kann sie die CAS-Sitzungsverwaltung, z. B. das Öffnen einer Sitzung und die Verarbeitung von EMM/ECM, an das MediaExtractor-Framework delegieren. MediaExtractor konfiguriert dann die CAS-Sitzung direkt über die native API.
Andernfalls ist die App dafür verantwortlich, die CA-bezogenen PSI-Daten zu extrahieren und die CAS-Sitzung mithilfe der Media CAS Java APIs zu konfigurieren (z. B. wenn die App einen eigenen MPEG2-TS-Parser verwendet).
Abbildung 2: Konfiguration von IPTV-Eingabe, CAS und Descrambler mithilfe des Frameworks MediaExtractor
Im Szenario mit Software-Extraktion benötigt der Extractor für jeden verschlüsselten Titel ein software- oder hardwarebasiertes Descramber-Objekt, unabhängig davon, ob für den Titel sichere Decoder erforderlich sind. Das hat folgende Gründe:
- Wenn für den Track keine sichere Decodierung erforderlich ist, entschlüsselt der Extraktor die Zugriffseinheit, um Zwischenspeicher zu löschen und Stichproben wie aus einem leeren Stream zu extrahieren. So muss
MediaCodec
nicht am Entschlüsseln beteiligt sein. Wenn für den Track eine sichere Decodierung erforderlich ist, benötigt der Extraktor möglicherweise noch einen Entschlüsseler. Dies ist der Fall, wenn der Transportstream auf Transportpaketebene verschlüsselt wird. Dabei wird der PES-Header (Packageized Elementary Stream) verschlüsselt. Der Extractor muss auf den PES-Header zugreifen, um bestimmte Informationen weiterzuleiten (z. B. den Präsentationszeitstempel).
Der Descrambler wird vom Extractor nicht verwendet, wenn der Transportstream auf PES-Paketebene verschlüsselt ist und der PES-Header leer bleibt. Sie können jedoch erst feststellen, wann die Verschlüsselung erfolgt, wenn das eigentliche verschlüsselte Paket eintrifft. Angenommen, ein Dekoder wird verwendet, wenn der Track anhand der Programmzuordnungstabelle (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 Entschlüsseler vorsichtig sein, wenn ein Entschlüsselungsvorgang in klare Puffer versetzt wird. Da eine unsichere Audiodecodierung erforderlich ist, sollte sie in einer anderen Sitzung als die Audioübertragung verschlüsselt werden, wenn für die Videodecodierung sichere Decoder erforderlich sind. 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 ganz einfach Videoframes mit dem Audio-Entschlüsseler abrufen.
Auch wenn für die Sitzung ein sicherer Decoder erforderlich ist, wird der Extractor möglicherweise aufgefordert, eine kleine Menge an Daten auszugeben, um die Puffer zu leeren und den PES-Header zu verarbeiten. Um zu verhindern, dass eine schädliche Anwendung das Plug-in die gesamte Zugriffseinheit zurückgibt, muss das Plug-in die Transportnutzlast parsen, um sicherzustellen, dass die Nutzlast mit einem PES-Header des entsprechenden Streamtyps beginnt. Andernfalls sollte die Anfrage vom Plug-in abgelehnt werden.
CA-Abstimmungssequenz
Wenn die Umstellung auf einen neuen Kanal erfolgt, registriert sich das TIS-Modul, um CA-Beschreibungen, ECMs und EMMs vom PSI-Tuner-Framework zu empfangen. Ein Zertifizierungsstellen-Beschreibungselement enthält die Zertifizierungsstellen-System-ID, mit der ein bestimmter Zertifizierungsstellenanbieter und andere anbieterspezifische Daten eindeutig identifiziert werden. TIS fragt Media CAS ab, um festzustellen, ob ein CAS-Plug-in vorhanden ist, das den CA-Deskriptor verarbeiten kann.
Abbildung 3: CAS-Inhalte optimieren
Wenn die CA-System-ID unterstützt wird, wird eine Instanz des Media CAS erstellt und die privaten Anbieterdaten aus dem CA-Deskriptor werden dem Plug-in bereitgestellt. Anschließend werden neue Sitzungen in Media CAS geöffnet, um die Audio- und Videostreams zu verarbeiten. Die neu geöffneten Sitzungen erhalten ECMs und EMMs für das Plug-in.
Beispiel für den Ablauf eines CAS-Plug-ins
TIS übergibt ECMs mithilfe von Media CAS APIs an das CAS-Plug-in. Ein ECM enthält das verschlüsselte Kontrollwort, das mithilfe von Informationen aus einem EMM-Dienst entschlüsselt werden muss. Das CAS-Plug-in bestimmt anhand der anbieterspezifischen Informationen im CA-Beschreibungselement, das über die setPrivateData()
-Methode bereitgestellt wird, wie ein EMM für das Asset erworben wird.
EMMs können im Contentstream oder Out-of-Band mithilfe einer vom CA-Plug-in initiierten Netzwerkanfrage bereitgestellt werden. TIS verwendet die processEMM()
-Methode, um alle In-Band-EMMs an das CA-Plug-in zu senden.
Wenn für den Erhalt einer EMM eine Netzwerkanfrage erforderlich ist, ist das CA-Plug-in für die Durchführung der Netzwerktransaktion mit einem Lizenzserver verantwortlich.
Abbildung 4 Beispiel für ein CAS-Plug-in für die EMM- und ECM-Verarbeitung
Wenn der EMM-Anbieter empfangen wird, parst das CA-Plug-in ihn, 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üsselleiter oder eine vertrauenswürdige Umgebung geladen werden, um die Entschlüsselung des Kontrollworts und die anschließende Entschlüsselung des Inhaltsstreams durchzuführen.
Media CAS Java API
Die Media CAS Java API enthält die folgenden Methoden.
Listet alle verfügbaren CA-Plug-ins auf dem Gerät auf.
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-Beschreibungsobjekt, der Tabelle für den bedingten Zugriff oder aus Out-of-Band-Quellen stammen. Dieser Wert ist keiner bestimmten Sitzung zugeordnet.
void setPrivateData(@NonNull byte[] data);
EMM-Paket verarbeiten
void processEmm(@NonNull byte[] data, int offset, int length);
Ereignis an ein Zertifizierungsstellensystem 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);
Initiiert einen Bereitstellungsvorgang des angegebenen Typs für ein Zertifizierungsstellensystem. Wenn sich ein Gerät zum ersten Mal für einen Pay-TV-Dienst registriert, muss es zuerst auf dem CAS-Server bereitgestellt werden. Geben Sie eine Reihe zugehöriger Parameter für die Bereitstellung des Geräts an.
void provision(String provisionString);
Eine Aktualisierung der Berechtigungen auslösen. Wenn ein Nutzer einen neuen Kanal abonniert (z. B. durch Beantworten einer Werbung oder Hinzufügen eines Kanals im elektronischen Programmführer (EPG)), sollte die App die CA-Clients auffordern 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 Daten der Zertifizierungsstelle aus einem CA-Deskriptor im PMT für eine CAS-Sitzung bereit. Dieser kann aus den Programminformationen oder dem Abschnitt mit 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);
Sitzungs-ID abrufen
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);