CAS 架構

媒體條件存取系統 (媒體 CAS) 架構提供標準 API,可在各種數位電視硬體上啟用條件存取 (CA) 服務,包括數位有線電視、衛星電視、地面系統和 IPTV 系統。這個架構可與 Android TV 輸入架構Android TV 調諧器架構搭配運作,提供從 TV 輸入服務 (TIS) 應用程式叫用的 Java API。

媒體 CAS 的主要目標如下。

  • 提供公開的 Java API 和原生外掛程式架構,供第三方開發人員和 OEM 用於支援 Android 廣播電視的 CAS。
  • 在 Android 中提供 CAS 架構,讓 ATV OEM 以一致的方式與各種 CAS 供應商互通。
  • 使用原生外掛程式支援多個第三方 CAS 供應商。 CAS 外掛程式可能會使用廠商專屬的網路通訊協定、授權管理訊息 (EMM)/授權控制訊息 (ECM) 格式,以及解擾器。
  • 支援金鑰梯等硬體安全機制。
  • 支援 TrustZone 等受信任的執行環境 (TEE)。

支援的設定

設定硬體調諧器

如果硬體負責 MPEG 傳輸串流解多工和解擾,Tuner 架構會將條件存取節目專屬資訊 (PSI) 資料提供給 TIS 應用程式,以便與硬體型電視調諧器介接。

有條件存取 PSI 資料包括 CA 描述元、ECM 和 EMM。CAS 外掛程式可透過這些結構取得解密內容串流所需的金鑰。

硬體調諧器設定圖。

圖 1. 設定硬體調諧器

硬體設定可能會有 TEE 層 (例如 TrustZone),如圖 1 所示。如果沒有 TEE 層,CAS 用戶端外掛程式可以與平台提供的硬體金鑰階梯服務通訊。由於這些介面有廠商專屬的變化,因此 Media CAS 不會將其標準化。

軟體設定

在 Android 11 之前,媒體 CAS 架構仍可用於處理軟體型內容,例如來自 IP 多點傳播/單點傳播的 IPTV。TIS 應用程式負責例項化及正確佈建 Media CAS Java 物件。

應用程式可能會使用 MediaExtractor 或其他 MPEG2-TS 剖析器,擷取 CA 相關的 PSI 資料,例如 CA 描述元、ECM 和 EMM。如果應用程式使用 MediaExtractor 架構,可以將 CAS 工作階段管理 (例如開啟工作階段和處理 EMM/ECM) 委派給 MediaExtractor 架構。然後 MediaExtractor 會直接使用原生 API 設定 CAS 工作階段。

否則,應用程式必須負責擷取與 CA 相關的 PSI 資料,並使用 Media CAS Java API 設定 CAS 工作階段 (例如,應用程式使用自己的 MPEG2-TS 剖析器時)。

Tuner 設定圖。

圖 2. 使用架構 MediaExtractor 設定 IPTV 輸入、CAS 和解擾器

在軟體擷取器情境中,無論曲目是否需要安全解碼器,擷取器都必須為每個經過加擾的曲目提供軟體或硬體型解擾器物件。原因如下。

  • 如果音軌不需要安全解碼,擷取器會解擾存取單元,清除緩衝區,並擷取樣本,就像是從未加密的串流擷取一樣。這樣一來,MediaCodec就不需要參與解擾。
  • 如果音軌需要安全解碼,擷取器可能仍需解擾器。當傳輸串流在傳輸封包層級經過擾亂時,就會發生這種情況,也就是封包化基本串流 (PES) 標頭經過擾亂。擷取器需要存取 PES 標頭,才能將特定資訊 (例如呈現時間戳記) 傳送至下游。

    如果傳輸串流是在 PES 封包層級經過擾亂,且 PES 標頭保持清除狀態,擷取器就不會使用解擾器。不過,在實際的擾亂封包抵達前,無法確認擾亂發生時間。為簡化說明,假設系統根據節目對應表 (PMT) 判斷音軌已加擾,就會使用解擾器。

軟體設定限制

如果軌道需要安全解碼,解擾器讓解擾作業進入清除緩衝區時,必須謹慎處理。由於需要不安全的音訊解碼,如果影片解碼需要安全解碼器,則應在與音訊不同的工作階段中進行擾亂。工作階段的 ECM 必須向外掛程式發出信號,表示需要安全解碼器。

或者,外掛程式必須能夠可靠地將金鑰與安全政策連結。否則,應用程式很容易就能透過音訊解擾器取得影片影格。

即使工作階段需要安全解碼器,系統也可能會要求輸出少量資料,讓擷取器清除緩衝區,以處理 PES 標頭。為防止惡意應用程式讓外掛程式傳回整個存取單元,外掛程式必須剖析傳輸酬載,確保酬載以適當串流類型的 PES 標頭開頭。否則外掛程式應拒絕要求。

CA 調整順序

切換至新頻道時,TIS 模組會註冊,以便從 PSI Tuner 架構接收 CA 描述元、ECM 和 EMM。CA 描述元包含 CA 系統 ID,可明確識別特定 CA 供應商和其他供應商專屬資料。TIS 會查詢 Media CAS,判斷是否有可處理 CA 描述元的 CAS 外掛程式。

調整 CAS 內容的圖表。

圖 3. 微調 CAS 內容

如果系統支援 CA 系統 ID,系統會建立 Media CAS 執行個體,並將 CA 描述元的供應商私有資料提供給外掛程式。接著,Media CAS 會開啟新的工作階段,處理音訊和視訊串流。新開啟的工作階段會收到外掛程式的 ECM 和 EMM。

CAS 外掛程式流程範例

TIS 會使用 Media CAS API,將 ECM 傳送至 CAS 外掛程式。ECM 包含加密的控制字,必須使用 EMM 的資訊解密。CAS 外掛程式會根據 CA 描述元中的供應商專屬資訊,決定如何取得資產的 EMM。CA 描述元是由 setPrivateData() 方法提供。

EMM 可能會透過內容串流中的頻內傳輸方式傳送,也可能透過 CA 外掛程式啟動的網路要求,以頻外傳輸方式傳送。TIS 會使用 processEMM() 方法,將任何頻內 EMM 傳送至 CA 外掛程式。

如果需要網路要求才能取得 EMM,CA 外掛程式會負責與授權伺服器執行網路交易。

CAS 範例圖表。

圖 4. EMM 和 ECM 處理作業的 CAS 外掛程式範例

收到 EMM 後,CA 外掛程式會剖析該 EMM,取得用於解密控制字的加密金鑰。加密的 EMM 金鑰和加密的控制字可能會載入金鑰階梯或可信環境,以執行控制字解密作業,並隨後解擾內容串流。

Media CAS Java API

Media CAS Java API 包含下列方法。

  • 列出裝置上所有可用的 CA 外掛程式。

    class MediaCas.PluginDescriptor {
      public String getName();
      public int getSystemId();
    }
    static PluginDescriptor[] enumeratePlugins();
    
  • 為指定的 CA 系統建構 Media CAS 執行個體。也就是說,媒體 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();
    
  • 將 PMT 中 CA 描述元的 CA 私人資料 (可來自節目資訊或 ES 資訊部分) 提供給 CAS 工作階段。

    void Session#setPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data);
    
  • 處理工作階段的 ECM 封包。

    void Session#processEcm(@NonNull byte[] data, int offset, int length);
    
  • 取得工作階段 ID。

    byte[] Session#getSessionId();
    
  • 將工作階段事件傳送至 CA 系統。事件格式會因架構而異,且對架構而言是不透明的。

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