[dvblast-devel] [PATCH] Add support for ECM and EMM passthrough

Georgi Chorbadzhiyski gf at unixsol.org
Mon Jun 6 21:27:02 CEST 2011


The attached patch adds support for two new options -M and -C
that allow EMM and ECM pass through. The patch is against dvblast
1.2 because that is what I were using. I'll send patch against
trunk tomorrow.

I'll be happy to address any comments on the patch.

-- 
Georgi Chorbadzhiyski
http://georgi.unixsol.org/

-------------- next part --------------
commit 4c925c0f2669a2d57fb8b17bc67f6fbb76ee4084
Author: Georgi Chorbadzhiyski <gf at unixsol.org>
Date:   Mon Jun 6 16:10:24 2011 +0300

    Add support for EMM and ECM passthrough

diff --git a/tags/1.2/demux.c b/tags/1.2/demux.c
index c8e0696..3726ccc 100644
--- a/tags/1.2/demux.c
+++ b/tags/1.2/demux.c
@@ -35,6 +35,7 @@
 
 #include <dvbpsi/demux.h>
 #include <dvbpsi/pat.h>
+#include <dvbpsi/cat.h>
 #include <dvbpsi/eit.h>
 #include <dvbpsi/sdt.h>
 #include <dvbpsi/dr.h>
@@ -45,16 +46,21 @@
  *****************************************************************************/
 
 #define PAT_PID        0x00
+#define CAT_PID        0x01
 #define SDT_PID        0x11
 #define EIT_PID        0x12
 #define TDT_PID        0x14
 
+#define CA_SYSTEM_DR   0x09
+
 typedef struct ts_pid_t
 {
     int i_refcount;
     int b_pes;
     int i_last_cc;
     int i_demux_fd;
+    int b_emm;          // Set to true if the PID carries EMM info and
+                        // should be added to all services
 
     output_t **pp_outputs;
     int i_nb_outputs;
@@ -72,9 +78,11 @@ static sid_t **pp_sids = NULL;
 static int i_nb_sids = 0;
 
 static dvbpsi_handle p_pat_dvbpsi_handle;
+static dvbpsi_handle p_cat_dvbpsi_handle;
 static dvbpsi_handle p_sdt_dvbpsi_handle;
 static dvbpsi_handle p_eit_dvbpsi_handle;
 static dvbpsi_pat_t *p_current_pat = NULL;
+static dvbpsi_cat_t *p_current_cat = NULL;
 static dvbpsi_sdt_t *p_current_sdt = NULL;
 static int i_demux_fd;
 
@@ -83,6 +91,7 @@ static int i_demux_fd;
  *****************************************************************************/
 static void demux_Handle( block_t *p_ts );
 static void SetPID( uint16_t i_pid );
+static void SetPID_EMM( uint16_t i_pid );
 static void UnsetPID( uint16_t i_pid );
 static void StartPID( output_t *p_output, uint16_t i_pid );
 static void StopPID( output_t *p_output, uint16_t i_pid );
@@ -103,6 +112,7 @@ static void NewPAT( output_t *p_output );
 static void NewSDT( output_t *p_output );
 static void NewPMT( output_t *p_output );
 static void PATCallback( void *_unused, dvbpsi_pat_t *p_pat );
+static void CATCallback( void *_unused, dvbpsi_cat_t *p_cat );
 static void SDTCallback( void *_unused, dvbpsi_sdt_t *p_sdt );
 static void PMTCallback( void *_unused, dvbpsi_pmt_t *p_pmt );
 static void PSITableCallback( void *_unused, dvbpsi_handle h_dvbpsi,
@@ -131,6 +141,12 @@ void demux_Open( void )
     SetPID(PAT_PID); /* PAT */
     p_pat_dvbpsi_handle = dvbpsi_AttachPAT( PATCallback, NULL );
 
+    if ( b_enable_emm )
+    {
+        SetPID_EMM(CAT_PID); /* CAT */
+        p_cat_dvbpsi_handle = dvbpsi_AttachCAT( CATCallback, NULL );
+    }
+
     if( b_enable_epg )
     {
         SetPID(SDT_PID); /* SDT */
@@ -211,6 +227,16 @@ static void demux_Handle( block_t *p_ts )
                     output_Put( pp_outputs[i], p_ts );
             }
         }
+        else if ( b_enable_emm && p_pids[i_pid].b_emm )
+        {
+            if ( i_pid == CAT_PID )
+                dvbpsi_PushPacket( p_cat_dvbpsi_handle, p_ts->p_ts );
+            for ( i = 0; i < i_nb_outputs; i++ )
+            {
+                if ( ( pp_outputs[i]->i_config & OUTPUT_VALID ) )
+                    output_Put( pp_outputs[i], p_ts );
+            }
+        }
         else
         {
             for ( i = 0; i < i_nb_sids; i++ )
@@ -444,6 +470,12 @@ static void SetPID( uint16_t i_pid )
         p_pids[i_pid].i_demux_fd = pf_SetFilter( i_pid );
 }
 
+static void SetPID_EMM( uint16_t i_pid )
+{
+    SetPID( i_pid );
+    p_pids[i_pid].b_emm = 1;
+}
+
 static void UnsetPID( uint16_t i_pid )
 {
     p_pids[i_pid].i_refcount--;
@@ -1242,10 +1274,81 @@ static void PATCallback( void *_unused, dvbpsi_pat_t *p_pat )
     }
 }
 
+static void CATCallback( void *_unused, dvbpsi_cat_t *p_cat )
+{
+    dvbpsi_cat_t *p_old_cat = p_current_cat;
+    dvbpsi_descriptor_t *p_dr, *p_old_dr;
+    dvbpsi_ca_dr_t *p_ca_dr, *p_old_ca_dr;
+
+    if ( !b_enable_emm )
+        return;
+
+    if ( p_current_cat != NULL &&
+        ( !p_cat->b_current_next ||
+          p_cat->i_version == p_current_cat->i_version ) )
+    {
+        dvbpsi_DeleteCAT( p_cat );
+        return;
+    }
+
+    msg_Dbg( NULL, "new CAT version=%d current_next=%d",
+             p_cat->i_version, p_cat->b_current_next );
+    p_current_cat = p_cat;
+
+    for( p_dr = p_cat->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next ) {
+        if ( p_dr->i_tag != CA_SYSTEM_DR )
+            continue;
+
+        p_ca_dr = dvbpsi_DecodeCADr( p_dr );
+        if ( p_ca_dr )
+        {
+            msg_Dbg( NULL, "  * emm pid=%d", p_ca_dr->i_ca_pid );
+            SetPID_EMM( p_ca_dr->i_ca_pid );
+        }
+    }
+
+    if ( p_old_cat != NULL )
+    {
+        for ( p_old_dr = p_old_cat->p_first_descriptor; p_old_dr != NULL;
+              p_old_dr = p_old_dr->p_next )
+        {
+            if ( p_old_dr->i_tag != CA_SYSTEM_DR )
+                continue;
+
+            p_old_ca_dr = dvbpsi_DecodeCADr( p_old_dr );
+            if ( p_old_ca_dr )
+            {
+                for( p_dr = p_cat->p_first_descriptor; p_dr != NULL;
+                     p_dr = p_dr->p_next )
+                {
+                    if ( p_dr->i_tag != CA_SYSTEM_DR )
+                        continue;
+
+                    p_ca_dr = dvbpsi_DecodeCADr( p_dr );
+                    if ( p_ca_dr && p_ca_dr->i_ca_pid == p_old_ca_dr->i_ca_pid )
+                        break;
+                }
+
+                if ( p_dr == NULL )
+                {
+                    msg_Dbg( NULL, "  * removed emm pid=%d",
+                             p_old_ca_dr->i_ca_pid );
+                    UnsetPID( p_old_ca_dr->i_ca_pid );
+                }
+            }
+        }
+
+        dvbpsi_DeleteCAT( p_old_cat );
+    }
+}
+
 static void PMTCallback( void *_unused, dvbpsi_pmt_t *p_pmt )
 {
     dvbpsi_pmt_t *p_current_pmt = NULL;
     dvbpsi_pmt_es_t *p_es, *p_current_es;
+    dvbpsi_descriptor_t *p_dr, *p_current_dr;
+    dvbpsi_ca_dr_t *p_ca_dr, *p_current_ca_dr;
+
     int b_needs_descrambling = PMTNeedsDescrambling( p_pmt );
     int b_needed_descrambling = 0;
     int b_is_selected = SIDIsSelected( p_pmt->i_program_number );
@@ -1288,6 +1391,22 @@ static void PMTCallback( void *_unused, dvbpsi_pmt_t *p_pmt )
           && p_pmt->i_pcr_pid != pp_sids[i_pmt]->i_pmt_pid )
         SelectPID( p_pmt->i_program_number, p_pmt->i_pcr_pid );
 
+    if ( b_enable_ecm )
+    {
+        for( p_dr = p_pmt->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next )
+        {
+            if ( p_dr->i_tag != CA_SYSTEM_DR )
+                continue;
+
+            p_ca_dr = dvbpsi_DecodeCADr( p_dr );
+            if ( p_ca_dr )
+            {
+                msg_Dbg( NULL, "  * ecm pid=%d", p_ca_dr->i_ca_pid );
+                SelectPID( p_pmt->i_program_number, p_ca_dr->i_ca_pid );
+            }
+        }
+    }
+
     for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next )
     {
         msg_Dbg( NULL, "  * es pid=%d type=%d",
@@ -1305,6 +1424,41 @@ static void PMTCallback( void *_unused, dvbpsi_pmt_t *p_pmt )
               && p_current_pmt->i_pcr_pid != pp_sids[i_pmt]->i_pmt_pid )
             UnselectPID( p_pmt->i_program_number, p_current_pmt->i_pcr_pid );
 
+        if ( b_enable_ecm )
+        {
+            for( p_current_dr = p_current_pmt->p_first_descriptor;
+                 p_current_dr != NULL;
+                 p_current_dr = p_current_dr->p_next )
+            {
+                if ( p_current_dr->i_tag != CA_SYSTEM_DR )
+                    continue;
+
+                p_current_ca_dr = dvbpsi_DecodeCADr( p_current_dr );
+                if ( p_current_ca_dr )
+                {
+                    for( p_dr = p_pmt->p_first_descriptor; p_dr != NULL;
+                         p_dr = p_dr->p_next )
+                    {
+                        if ( p_dr->i_tag != CA_SYSTEM_DR )
+                            continue;
+
+                        p_ca_dr = dvbpsi_DecodeCADr( p_current_dr );
+                        if ( p_ca_dr &&
+                             p_ca_dr->i_ca_pid == p_current_ca_dr->i_ca_pid )
+                            break;
+                    }
+
+                    if ( p_dr == NULL )
+                    {
+                        msg_Dbg( NULL, "  * removed ecm pid=%d",
+                                 p_current_ca_dr->i_ca_pid );
+                        UnselectPID( p_pmt->i_program_number,
+                                     p_current_ca_dr->i_ca_pid );
+                    }
+                }
+            }
+        }
+
         for( p_current_es = p_current_pmt->p_first_es; p_current_es != NULL;
              p_current_es = p_current_es->p_next )
         {
diff --git a/tags/1.2/dvblast.c b/tags/1.2/dvblast.c
index 8773a61..859bc86 100644
--- a/tags/1.2/dvblast.c
+++ b/tags/1.2/dvblast.c
@@ -61,6 +61,8 @@ char *psz_modulation = NULL;
 int b_budget_mode = 0;
 int b_slow_cam = 0;
 int b_output_udp = 0;
+int b_enable_emm = 0;
+int b_enable_ecm = 0;
 int b_enable_epg = 0;
 int b_unique_tsid = 0;
 volatile int b_hup_received = 0;
@@ -312,13 +314,15 @@ static void DisplayVersion()
  *****************************************************************************/
 void usage()
 {
-    msg_Raw( NULL, "Usage: dvblast [-q] [-c <config file>] [-r <remote socket>] [-t <ttl>] [-o <SSRC IP>] [-i <RT priority>] [-a <adapter>] [-n <frontend number>] [-S <diseqc>] [-f <frequency>|-D <src mcast>:<port>|-A <ASI adapter>] [-s <symbol rate>] [-v <0|13|18>] [-p] [-b <bandwidth>] [-m <modulation] [-u] [-W] [-U] [-d <dest IP:port>] [-e] [-T]" );
+    msg_Raw( NULL, "Usage: dvblast [-q] [-c <config file>] [-r <remote socket>] [-t <ttl>] [-o <SSRC IP>] [-i <RT priority>] [-a <adapter>] [-n <frontend number>] [-S <diseqc>] [-f <frequency>|-D <src mcast>:<port>|-A <ASI adapter>] [-s <symbol rate>] [-v <0|13|18>] [-p] [-b <bandwidth>] [-m <modulation] [-u] [-W] [-U] [-d <dest IP:port>] [-M] [-C] [-e] [-T]" );
 
     msg_Raw( NULL, "Input:" );
     msg_Raw( NULL, "  -a --adapter <adapter>" );
     msg_Raw( NULL, "  -A --asi-adapter      read packets from an ASI adapter (0-n)" );
     msg_Raw( NULL, "  -b --bandwidth        frontend bandwith" );
     msg_Raw( NULL, "  -D --rtp-input        read packets from a multicast address instead of a DVB card" );
+    msg_Raw( NULL, "  -M --emm-passthrough  enable EMM pass through (CA system data)" );
+    msg_Raw( NULL, "  -C --ecm-passthrough  enable ECM pass through (CA program data)" );
     msg_Raw( NULL, "  -e --epg-passthrough  enable EPG pass through (EIT data)" );
     msg_Raw( NULL, "  -f --frequency        frontend frequency" );
     msg_Raw( NULL, "  -m --modulation       Modulation type" );
@@ -384,13 +388,15 @@ int main( int i_argc, char **pp_argv )
         { "duplicate",       required_argument, NULL, 'd' },
         { "rtp-input",       required_argument, NULL, 'D' },
         { "asi-adapter",     required_argument, NULL, 'A' },
+        { "emm-passthrough", no_argument,       NULL, 'M' },
+        { "ecm-passthrough", no_argument,       NULL, 'C' },
         { "epg-passthrough", no_argument,       NULL, 'e' },
         { "help",            no_argument,       NULL, 'h' },
         { "version",         no_argument,       NULL, 'V' },
         { 0, 0, 0, 0}
     }; 
 
-    while ( ( c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:f:s:S:v:pb:m:uWUTd:D:A:ehV", long_options, NULL)) != -1 )
+    while ( ( c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:f:s:S:v:pb:m:uWUTd:D:A:MCehV", long_options, NULL)) != -1 )
     {
         switch ( c )
         {
@@ -640,6 +646,14 @@ int main( int i_argc, char **pp_argv )
             pf_UnsetFilter = asi_UnsetFilter;
             break;
 
+        case 'M':
+            b_enable_emm = 1;
+            break;
+
+        case 'C':
+            b_enable_ecm = 1;
+            break;
+
         case 'e':
             b_enable_epg = 1;
             break;
diff --git a/tags/1.2/dvblast.h b/tags/1.2/dvblast.h
index 2f0bbec..ddeefc3 100644
--- a/tags/1.2/dvblast.h
+++ b/tags/1.2/dvblast.h
@@ -119,6 +119,8 @@ extern char *psz_modulation;
 extern int b_budget_mode;
 extern int b_slow_cam;
 extern int b_output_udp;
+extern int b_enable_emm;
+extern int b_enable_ecm;
 extern int b_enable_epg;
 extern int b_unique_tsid;
 extern volatile int b_hup_received;


More information about the dvblast-devel mailing list