מסגרת CAS

מסגרת של מערכות גישה מותנית למדיה (Media CAS) מספקת ממשקי API סטנדרטיים שמאפשרים להפעיל שירותי גישה מותנית (CA) במגוון רכיבי חומרה לטלוויזיה דיגיטלית, כולל מערכות של כבלים דיגיטליים, לוויין, מערכות יבשתיות ומערכות IPTV. המסגרת פועלת עם Android TV Input framework ו-Android TV Tuner framework, ומספקת ממשקי Java API שמופעלים מאפליקציית TV Input Service‏ (TIS).

היעדים העיקריים של Media CAS הם:

  • לספק ממשק API ציבורי ל-Java ותשתית פלאגין מקורית שיזמי צד שלישי ויצרני ציוד מקורי (OEM) יוכלו להשתמש בהם כדי לתמוך ב-CAS לטלוויזיה רגילה ב-Android.
  • מסגרת CAS ב-Android שמאפשרת ליצרני ציוד מקורי לטלוויזיות חכמות (ATV) לבצע פעולות הדדיות עם מגוון ספקי CAS באופן עקבי.
  • לתמוך בכמה ספקי CAS של צד שלישי באמצעות יישומי פלאגין מקוריים. יכול להיות שבתוספים של CAS נעשה שימוש בפרוטוקולים ספציפיים לרשת, בפורמטים של הודעות לניהול הרשאות (EMM) או הודעות לבקרת הרשאות (ECM) ובמקודדים.
  • תמיכה באבטחת חומרה כמו סולמות מפתחות.
  • תמיכה בסביבות מחשוב מהימנות (TEE), כמו TrustZone.

הגדרות נתמכות

הגדרת טיונר חומרה

אם החומרה אחראית לביטול המרובולקס ולפענוח של מקור הנתונים של MPEG, Tuner framework מספק לאפליקציית 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 באמצעות ממשקי Media CAS Java API (למשל, כשהאפליקציה משתמשת במנתח MPEG2-TS משלה).

תרשים של הגדרת הטיונר.

איור 2. הגדרת קלט IPTV, CAS ו-descrambler באמצעות המסגרת MediaExtractor

בתרחיש של חילוץ התוכנה, מכשיר החילוץ דורש תוכנה או אובייקט מפענח נתונים מבוסס חומרה לכל מסלול מעורבל, בין אם הטראק קורא למפענחים מאובטחים. הסיבה לכך היא:

  • אם הטראק לא דורש פענוח מאובטח, הכלי לחילוץ מבצע פענוח של יחידת הגישה כדי לנקות את המאגרים ומחליץ דגימות כאילו מזרם נקי. כך MediaCodec לא צריך להיות מעורב בפענוח.
  • אם הטראק דורש פענוח מאובטח, יכול להיות שעדיין יהיה צורך במכשיר לביטול הצפנה בתוך המכשיר שמפריד את הנתונים. המצב הזה מתרחש כשזרם התעבורה עבר ערבוב ברמת החבילה של התעבורה, שבה עבר ערבוב גם הכותרת של זרם האלמנטים המנותב (PES). למחולל הנתונים צריכה להיות גישה לכותרת ה-PES כדי לקבל מידע מסוים במורד הזרם (לדוגמה, חותמת הזמן של ההצגה).

    אם מקור הנתונים עבר ערבול ברמת החבילה של PES, כותרת ה-PES נשארת ללא שינוי, והחילוץ לא משתמש במפענח. עם זאת, אי אפשר לאשר מתי מתבצע הערבוב עד שמגיעה החבילה המעורבת בפועל. כדי לפשט את העניין, נניח שמשתמשים במפענח אם נקבע שהטראק מוצפן על סמך טבלת המיפוי של התוכנית (PMT).

מגבלות בהגדרת התוכנה

כשהטראק מחייב פענוח מאובטח, צריך להפעיל שיקול דעת כשמאפשרים לפעולת פענוח לעבור למאגרים גלויים. בגלל שנדרש פענוח אודיו לא מאובטח, אם נדרשים מפענחים מאובטחים לפענוח סרטון, צריך ערבול שלו בסשן שונה מהאודיו. ה-ECM לסשן צריך לאותת לפלאגין שנדרש למפענח מאובטח.

לחלופין, הפלאגין צריך להיות מסוגל לקשר מפתח למדיניות האבטחה שלו באופן מהימן. אחרת, האפליקציה יכולה להשיג בקלות פריימים של וידאו באמצעות מפענח האודיו.

גם אם הסשן מחייב מפענח מאובטח, יכול להיות שהוא יתבקש להפיק כמות קטנה של נתונים כדי לנקות את המאגרים של המחולץ לצורך עיבוד כותרת ה-PES. כדי למנוע מאפליקציה זדונית לגרום לפלאגין להחזיר את כל יחידת הגישה, הפלאגין צריך לנתח את עומס העבודה של התעבורה כדי לוודא שעומס העבודה מתחיל בכותרת PES מסוג הסטרימינג המתאים. אחרת, הפלאגין אמור לדחות את הבקשה.

רצף כוונון של רשות אישורים

כשמכוונים לערוץ חדש, מודול ה-TIS מתעדכן כדי לקבל מתבניות ה-PSI Tuner מתארי CA,‏ ECM ו-EMM. מתאר של רשות אישורים מכיל את מזהה המערכת של רשות האישורים, שמזהה באופן ייחודי ספק ספציפי של רשות אישורים ונתונים אחרים שספציפיים לספק. מערכת TIS שולחת שאילתה ל-Media CAS כדי לקבוע אם יש פלאגין CAS שיכול לטפל במתאר ה-CA.

תרשים של התאמת התוכן של CAS.

איור 3. התאמת התוכן של CAS

אם מזהה מערכת ה-CA נתמך, נוצרת מופע של Media CAS והנתונים הפרטיים של הספק מתוארת ה-CA מסופקים לתוסף. לאחר מכן, נפתחים סשנים חדשים ב-Media CAS כדי לטפל בסטרימינג של האודיו והווידאו. הסשנים שנפתחים מקבלים הודעות ECM ו-EMM עבור הפלאגין.

תהליך לדוגמה של פלאגין CAS

TIS מעביר את קובצי ה-ECM לתוסף CAS באמצעות ממשקי Media CAS API. קובץ ECM מכיל את מפתח הבקרה המוצפן, שצריך לפענח באמצעות מידע מ-EMM. הפלאגין של CAS קובע איך לקבל EMM לנכס על סמך מידע ספציפי לספק בתיאור ה-CA, שמסופק על ידי השיטה setPrivateData().

ייתכן שה-EMMs יישלחו בפס ברוחב פס של שידור התוכן או מחוץ לפס באמצעות בקשת רשת שמופעלת על ידי הפלאגין של CA. TIS משתמשת בשיטה processEMM() כדי להעביר כל שירות EMM בתחום התדרים הנוכחי (in band) לתוסף ה-CA.

אם נדרשת בקשת רשת כדי לקבל EMM, הפלאגין של CA אחראי לבצע את העסקה ברשת עם שרת הרישיונות.

דיאגרמה של דוגמה ל-CAS.

איור 4. דוגמה לפלאגין של CAS לעיבוד EMM ו-ECM

כשמקבלים את ה-EMM, הפלאגין של CA מנתח אותו כדי לקבל את המפתח המוצפן לצורך פענוח של מילת הבקרה. יכול להיות שמפתח ה-EMM המוצפן ומילה הבקרה המוצפנת יוטמעו בסולם מפתחות או בסביבה מהימנה כדי לבצע את פענוח של מילה הבקרה ואת פענוח הנתונים של תוכן השידור.

Media CAS Java API

ממשק ה-API של Media CAS ב-Java מכיל את השיטות הבאות.

  • הצגת רשימה של כל יישומי הפלאגין של 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, מטבלת הגישה המותנית או ממקורות מחוץ לתדר. הוא לא משויך לסשן מסוים.

    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);
    
  • סוגרים את אובייקט ה-CAS של המדיה.

    void close();
    
  • פותחים סשן.

    Session openSession();
    Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode);
    
  • סגירת סשן שנפתח בעבר.

    void Session#close();
    
  • העברת הנתונים הפרטיים של CA מתווית CA ב-PMT, שיכולה להיות מהקטע 'פרטי התוכנית' או מהקטע 'פרטי ES', לסשן CAS.

    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);