Systemy warunkowego dostępu do mediów (Media CAS) zapewniają standardowe interfejsy API umożliwiające świadczenie usług warunkowego dostępu (CA) w przypadku różnych rodzajów sprzętu do telewizji cyfrowej, w tym telewizji cyfrowej kablowej, satelitarnej, naziemnej i IPTV. Ten framework współpracuje z frameworkiem Android TV Input i frameworkem Android TV Tuner, udostępniając interfejsy API w języku Java wywoływane z aplikacji TV Input Service (TIS).
Główne cele Media CAS:
- Udostępnianie publicznego interfejsu API Java i ramowego środowiska natywnych wtyczek, które mogą być używane przez zewnętrznych programistów i producentów OEM do obsługi CAS dla telewizji cyfrowej na Androidzie.
- Udostępniać w Androidzie platformę CAS, która umożliwia OEM-om ATV współpracę z różnymi dostawcami usług CAS w sposób spójny.
- Obsługa wielu zewnętrznych dostawców usług uwierzytelniania za pomocą wtyczek natywnych. Wtyczki CAS mogą używać protokołów sieciowych specyficznych dla dostawcy, formatów wiadomości dotyczących zarządzania uprawnieniami (EMM) lub kontroli uprawnień (ECM) oraz deskryptorów.
- Obsługa zabezpieczeń sprzętowych, takich jak drabiny kluczy.
- obsługa zaufanych środowisk wykonawczych (TEE), takich jak TrustZone;
Obsługiwane konfiguracje
Konfiguracja tunera sprzętowego
Jeśli sprzęt odpowiada za demultipleksowanie i dekodowanie strumienia transportowego MPEG, ramka tunera przekazuje aplikacji TIS dane o programach (PSI) dotyczące warunkowego dostępu, aby umożliwić jej współpracę z tunerami telewizyjnymi opartymi na sprzęcie.
Dane PSI dotyczące dostępu warunkowego obejmują opisy CA, ECM i EMM. Te struktury umożliwiają wtyczce CAS uzyskiwanie kluczy potrzebnych do odszyfrowywania strumieni treści.
Rysunek 1. Konfiguracja tunera sprzętowego
Konfiguracja sprzętowa może zawierać warstwę TEE, taką jak TrustZone, jak pokazano na rysunku 1. Jeśli nie ma warstwy TEE, wtyczka klienta CAS może komunikować się z usługami schodów kluczy sprzętowych udostępnianymi przez platformę. Ze względu na różnice w tych interfejsach zależne od dostawcy Media CAS nie standaryzuje ich.
Konfiguracja oprogramowania
Przed Androidem 11 framework Media CAS można było nadal używać do przetwarzania treści opartych na oprogramowaniu, takich jak IPTV z multicastu/unicastu IP. Aplikacja TIS odpowiada za tworzenie instancji i prawidłowe inicjowanie obiektu Java Media CAS.
Aplikacja może używać MediaExtractor lub innych parserów MPEG2-TS do wyodrębniania danych PSI związanych z CA, takich jak opisy CA, ECM i EMM. Jeśli aplikacja korzysta z ram Work MediaExtractor, może zlecić zarządzanie sesją CAS, na przykład otwieranie sesji i przetwarzanie EMM/ECM, do frameworku MediaExtractor. Następnie MediaExtractor konfiguruje sesję CAS bezpośrednio za pomocą natywnej interfejsu API.
W przeciwnym razie aplikacja jest odpowiedzialna za wyodrębnienie danych PSI związanych z CA oraz skonfigurowanie sesji CAS za pomocą interfejsów API Media CAS w języku Java (np. gdy aplikacja używa własnego parsowania MPEG2-TS).
Rysunek 2. Konfiguracja dekoderów IPTV, CAS i dekoderów za pomocą frameworka MediaExtractor
W sytuacji, gdy wyodrębniacz oprogramowania jest używany do wyodrębniania treści, wymaga on obiektu deskryptora oprogramowania lub sprzętowego dla każdego zakodowanego utworu, niezależnie od tego, czy utwór wymaga bezpiecznych deskryptorów. Wynika to z tych czynników:
- Jeśli ścieżka nie wymaga bezpiecznego dekodowania, dekoder odszyfrowuje jednostkę dostępu, aby wyczyścić bufory, i wyodrębnia próbki tak, jakby pochodziły ze strumienia czystego. W ten sposób element
MediaCodec
nie musi być uwzględniany w rozszyfrowywaniu. Jeśli ścieżka wymaga bezpiecznego dekodowania, narzędzie do wyodrębniania może nadal wymagać deszyfratora. Dzieje się tak, gdy strumień transportu jest zaszyfrowany na poziomie pakietu transportowego, gdzie nagłówek pakietów strumienia podstawowego (PES) jest zaszyfrowany. Aby wyodrębniacz mógł przekazać określone informacje (np. sygnaturę czasową prezentacji), musi mieć dostęp do nagłówka PES.
Rozszyfrator nie jest używany przez ekstraktor, jeśli strumień transportowy jest zaszyfrowany na poziomie pakietu PES, gdzie nagłówek PES jest pusty. Nie można jednak potwierdzić, kiedy nastąpiło zaszyfrowanie, dopóki nie dotrze zaszyfrowany pakiet. Dla uproszczenia przyjmijmy, że dekoder jest używany, jeśli ścieżka jest zaszyfrowana na podstawie tabeli mapowania programu (PMT).
Ograniczenia konfiguracji oprogramowania
Gdy utwór wymaga bezpiecznego dekodowania, dekoder musi zachować ostrożność podczas stosowania operacji dekodera na czystym buforze. Ponieważ do dekodowania dźwięku wymagane jest niepewne dekodowanie, jeśli dekodowanie wideo wymaga bezpiecznych dekoderów, należy je zaszyfrować w innej sesji niż dźwięk. ECM sesji musi przekazać wtyczce informację, że wymagany jest bezpieczny dekoder.
Alternatywnie wtyczka musi umożliwiać niezawodne powiązanie klucza z zasadami bezpieczeństwa. W przeciwnym razie aplikacja może łatwo uzyskać klatki wideo za pomocą dekoderu dźwięku.
Nawet jeśli sesja wymaga bezpiecznego dekodera, może być poproszona o wydanie niewielkiej ilości danych, aby oczyszczyć bufory ekstraktora w celu przetworzenia nagłówka PES. Aby zapobiec temu, aby złośliwa aplikacja zmusiła wtyczkę do zwrócenia całego zasobu dostępu, wtyczka musi przeanalizować ładunek transportowy, aby upewnić się, że ładunek zaczyna się nagłówkiem PES odpowiedniego typu strumienia. W przeciwnym razie wtyczka powinna odrzucić żądanie.
Sekwencja dostrajania urzędu certyfikacji
Podczas dostrajania do nowego kanału moduł TIS rejestruje się, aby otrzymywać z ram PSI Tuner oznaczenia CA, ECM i EMM. Opis urzędu certyfikacji zawiera identyfikator systemu urzędu certyfikacji, który jednoznacznie identyfikuje konkretnego dostawcę urzędu certyfikacji oraz inne dane dotyczące dostawcy. TIS wysyła zapytanie do Media CAS, aby sprawdzić, czy istnieje wtyczka CAS, która może obsłużyć deskryptor CA.
Rysunek 3. Dostosowywanie treści CAS
Jeśli identyfikator systemu CA jest obsługiwany, tworzony jest egzemplarz Media CAS, a dane prywatne dostawcy z opisu CA są przekazywane do wtyczki. Następnie w Media CAS otwierane są nowe sesje, aby obsługiwać strumienie audio i wideo. Nowo otwarte sesje otrzymują ECM i EMM dla wtyczki.
Przykładowy proces obsługiwany przez wtyczkę CAS
TIS dostarcza ECM do wtyczki CAS za pomocą interfejsów Media CAS API. ECM zawiera zaszyfrowane słowo kontrolne, które należy odszyfrować za pomocą informacji z EMM. Wtyczka CAS określa sposób pobierania EMM zasobu na podstawie informacji o usługodawcy w opisie CA, który jest udostępniany przez metodę setPrivateData()
.
EMM mogą być dostarczane w paśmie w strumieniu treści lub poza pasmem za pomocą żądania sieciowego zainicjowanego przez wtyczkę CA. TIS używa metody processEMM()
do dostarczania do wtyczki CA wszystkich EMM w paśmie.
Jeśli do uzyskania EMM wymagane jest żądanie sieciowe, wtyczka CA jest odpowiedzialna za wykonanie transakcji sieciowej z serwerem licencji.
Rysunek 4. Przykład wtyczki CAS do przetwarzania EMM i ECM
Po otrzymaniu EMM wtyczka CA analizuje go, aby uzyskać zaszyfrowany klucz do odszyfrowania słowa sterującego. Zaszyfrowany klucz EMM i zaszyfrowane słowo kontrolne mogą zostać załadowane do drabiny kluczy lub zaufanej grupy, aby przeprowadzić odszyfrowanie słowa kontrolnego i dalsze odszyfrowywanie strumienia treści.
Media CAS Java API
Interfejs Media CAS API w Javie zawiera te metody:
Lista wszystkich dostępnych wtyczek CA na urządzeniu.
class MediaCas.PluginDescriptor { public String getName(); public int getSystemId(); } static PluginDescriptor[] enumeratePlugins();
Utwórz instancję Media CAS dla określonego systemu CA. Oznacza to, że framework Media CAS może obsługiwać wiele systemów CAS jednocześnie.
MediaCas(int CA_system_id); MediaCas(@NonNull Context context, int casSystemId, @Nullable String tvInputServiceSessionId, @PriorityHintUseCaseType int priorityHint);
Zarejestruj odbiornik zdarzeń i pozwala aplikacji określić moduł obsługi, którego ma używać pętli.
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);
Prześlij prywatne dane systemu CA. Dane prywatne mogą pochodzić z opisu urzędu certyfikacji, tabeli dostępu warunkowego lub źródeł spoza sieci. Nie jest on powiązany z żadną konkretną sesją.
void setPrivateData(@NonNull byte[] data);
Przetwarzanie pakietu EMM.
void processEmm(@NonNull byte[] data, int offset, int length);
wysyłać zdarzenie do systemu CA. Format zdarzenia jest specyficzny dla schematu i nie jest widoczny dla frameworku.
void sendEvent(int event, int arg, @Nullable byte[] data);
Rozpoczęcie operacji obsługi określonego typu w systemie CA. Gdy urządzenie po raz pierwszy zarejestruje się w usłudze płatnej telewizji, musi zostać najpierw udostępnione na serwerze CAS. Podaj zestaw parametrów powiązanych z urządzeniem na potrzeby jego wdrożenia.
void provision(String provisionString);
Wywołaj odświeżenie uprawnień. Gdy użytkownik subskrybuje nowy kanał (np. odpowiadając na reklamę lub dodając kanał w elektronicznym przewodniku po programach), aplikacja powinna móc poinformować klientów CA o konieczności odświeżenia kluczy uprawnień.
void refreshEntitlements(int refreshType);
Zamknij obiekt Media CAS.
void close();
Otwórz sesję.
Session openSession(); Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode);
zamknąć wcześniej otwartą sesję.
void Session#close();
Przekaż dane prywatne CA z opisu CA w PMT, które mogą pochodzić z sekcji informacji o programie lub z sekcji informacji o ES, do sesji CAS.
void Session#setPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data);
Przetwarzanie pakietu ECM na potrzeby sesji.
void Session#processEcm(@NonNull byte[] data, int offset, int length);
Uzyskaj identyfikator sesji.
byte[] Session#getSessionId();
wysyłać zdarzenie sesji do systemu CA. Format zdarzenia jest określony przez schemat i nie jest widoczny dla frameworka.
void Session#sendSessionEvent(int event, int arg, @Nullable byte[] data);