Commit ce994d1b authored by Christophe Massiot's avatar Christophe Massiot

* modules/demux/ts.c: New option --ts-capmt-sysid to filter CA descriptors

  of a given system provider (this is apparently needed for SCM Cryptoworks
  CAM).
* modules/access/dvb/dvb.h: Allow up to 256 demux slots.
* modules/access/dvb/en50221.c: Do not send the CAPMT too often (apparently
  bad for some CAM).
parent 7bcf380e
...@@ -54,7 +54,7 @@ typedef struct ...@@ -54,7 +54,7 @@ typedef struct
void *p_sys; void *p_sys;
} en50221_session_t; } en50221_session_t;
#define MAX_DEMUX 48 #define MAX_DEMUX 256
#define MAX_CI_SLOTS 16 #define MAX_CI_SLOTS 16
#define MAX_SESSIONS 32 #define MAX_SESSIONS 32
...@@ -71,7 +71,7 @@ struct access_sys_t ...@@ -71,7 +71,7 @@ struct access_sys_t
vlc_bool_t pb_active_slot[MAX_CI_SLOTS]; vlc_bool_t pb_active_slot[MAX_CI_SLOTS];
vlc_bool_t pb_tc_has_data[MAX_CI_SLOTS]; vlc_bool_t pb_tc_has_data[MAX_CI_SLOTS];
en50221_session_t p_sessions[MAX_SESSIONS]; en50221_session_t p_sessions[MAX_SESSIONS];
mtime_t i_ca_timeout, i_ca_next_event; mtime_t i_ca_timeout, i_ca_next_event, i_ca_next_pmt;
uint8_t **pp_capmts; uint8_t **pp_capmts;
int i_nb_capmts; int i_nb_capmts;
}; };
......
...@@ -685,7 +685,7 @@ static void ApplicationInformationHandle( access_t * p_access, int i_session_id, ...@@ -685,7 +685,7 @@ static void ApplicationInformationHandle( access_t * p_access, int i_session_id,
uint8_t *d = APDUGetLength( p_apdu, &l ); uint8_t *d = APDUGetLength( p_apdu, &l );
if ( l < 4 ) break; if ( l < 4 ) break;
p_apdu[l + 3] = '\0'; p_apdu[l + 4] = '\0';
i_type = *d++; i_type = *d++;
i_manufacturer = ((int)d[0] << 8) | d[1]; i_manufacturer = ((int)d[0] << 8) | d[1];
...@@ -744,8 +744,7 @@ static void ConditionalAccessHandle( access_t * p_access, int i_session_id, ...@@ -744,8 +744,7 @@ static void ConditionalAccessHandle( access_t * p_access, int i_session_id,
SPDUSend( p_access, i_session_id, p_sys->pp_capmts[i], SPDUSend( p_access, i_session_id, p_sys->pp_capmts[i],
i_size + (p - p_sys->pp_capmts[i]) ); i_size + (p - p_sys->pp_capmts[i]) );
} }
p_sys->i_ca_next_pmt = 0;
p_sys->i_ca_timeout = 100000;
} }
break; break;
} }
...@@ -956,7 +955,7 @@ static int InitSlot( access_t * p_access, int i_slot ) ...@@ -956,7 +955,7 @@ static int InitSlot( access_t * p_access, int i_slot )
} }
if ( p_sys->pb_active_slot[i_slot] ) if ( p_sys->pb_active_slot[i_slot] )
{ {
p_sys->i_ca_timeout = 1000; p_sys->i_ca_timeout = 100000;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -1074,6 +1073,30 @@ int E_(en50221_Poll)( access_t * p_access ) ...@@ -1074,6 +1073,30 @@ int E_(en50221_Poll)( access_t * p_access )
} }
} }
if ( p_sys->i_ca_next_pmt && p_sys->i_ca_next_pmt <= mdate() )
{
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{
int i;
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id
!= RI_CONDITIONAL_ACCESS_SUPPORT )
continue;
msg_Dbg( p_access, "sending CAPMT on session %d", i_session_id );
for ( i = 0; i < p_sys->i_nb_capmts; i++ )
{
int i_size;
uint8_t *p;
p = GetLength( &p_sys->pp_capmts[i][3], &i_size );
SPDUSend( p_access, i_session_id, p_sys->pp_capmts[i],
i_size + (p - p_sys->pp_capmts[i]) );
}
}
p_sys->i_ca_next_pmt = 0;
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -1085,28 +1108,6 @@ int E_(en50221_SetCAPMT)( access_t * p_access, uint8_t **pp_capmts, ...@@ -1085,28 +1108,6 @@ int E_(en50221_SetCAPMT)( access_t * p_access, uint8_t **pp_capmts,
int i_nb_capmts ) int i_nb_capmts )
{ {
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
int i_session_id;
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{
int i;
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id
!= RI_CONDITIONAL_ACCESS_SUPPORT )
continue;
msg_Dbg( p_access, "sending CAPMT on session %d", i_session_id );
for ( i = 0; i < i_nb_capmts; i++ )
{
int i_size;
uint8_t *p;
p = GetLength( &pp_capmts[i][3], &i_size );
SPDUSend( p_access, i_session_id, pp_capmts[i],
i_size + (p - pp_capmts[i]) );
}
p_sys->i_ca_timeout = 100000;
}
if ( p_sys->i_nb_capmts ) if ( p_sys->i_nb_capmts )
{ {
...@@ -1119,6 +1120,7 @@ int E_(en50221_SetCAPMT)( access_t * p_access, uint8_t **pp_capmts, ...@@ -1119,6 +1120,7 @@ int E_(en50221_SetCAPMT)( access_t * p_access, uint8_t **pp_capmts,
} }
p_sys->pp_capmts = pp_capmts; p_sys->pp_capmts = pp_capmts;
p_sys->i_nb_capmts = i_nb_capmts; p_sys->i_nb_capmts = i_nb_capmts;
p_sys->i_ca_next_pmt = mdate() + 1000000;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
...@@ -83,6 +83,9 @@ static void Close ( vlc_object_t * ); ...@@ -83,6 +83,9 @@ static void Close ( vlc_object_t * );
#define SILENT_TEXT N_("Silent mode") #define SILENT_TEXT N_("Silent mode")
#define SILENT_LONGTEXT N_("do not complain on encrypted PES") #define SILENT_LONGTEXT N_("do not complain on encrypted PES")
#define CAPMT_SYSID_TEXT N_("CAPMT System ID")
#define CAPMT_SYSID_LONGTEXT N_("only forward descriptors from this SysID to the CAM")
vlc_module_begin(); vlc_module_begin();
set_description( _("ISO 13818-1 MPEG Transport Stream input - new" ) ); set_description( _("ISO 13818-1 MPEG Transport Stream input - new" ) );
set_shortname ( _("MPEG-TS") ); set_shortname ( _("MPEG-TS") );
...@@ -96,6 +99,8 @@ vlc_module_begin(); ...@@ -96,6 +99,8 @@ vlc_module_begin();
MTUOUT_LONGTEXT, VLC_TRUE ); MTUOUT_LONGTEXT, VLC_TRUE );
add_string( "ts-csa-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, VLC_TRUE ); add_string( "ts-csa-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, VLC_TRUE );
add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, VLC_TRUE ); add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, VLC_TRUE );
add_integer( "ts-capmt-sysid", 0, NULL, CAPMT_SYSID_TEXT,
CAPMT_SYSID_LONGTEXT, VLC_TRUE );
set_capability( "demux2", 10 ); set_capability( "demux2", 10 );
set_callbacks( Open, Close ); set_callbacks( Open, Close );
...@@ -270,6 +275,7 @@ struct demux_sys_t ...@@ -270,6 +275,7 @@ struct demux_sys_t
vlc_bool_t b_es_id_pid; vlc_bool_t b_es_id_pid;
csa_t *csa; csa_t *csa;
vlc_bool_t b_silent; vlc_bool_t b_silent;
uint16_t i_capmt_sysid;
vlc_bool_t b_udp_out; vlc_bool_t b_udp_out;
int fd; /* udp socket */ int fd; /* udp socket */
...@@ -572,6 +578,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -572,6 +578,10 @@ static int Open( vlc_object_t *p_this )
var_Get( p_demux, "ts-silent", &val ); var_Get( p_demux, "ts-silent", &val );
p_sys->b_silent = val.b_bool; p_sys->b_silent = val.b_bool;
var_Create( p_demux, "ts-capmt-sysid", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Get( p_demux, "ts-capmt-sysid", &val );
p_sys->i_capmt_sysid = val.i_int;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -2033,8 +2043,11 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -2033,8 +2043,11 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
} }
else if( p_dr->i_tag == 0x9 ) else if( p_dr->i_tag == 0x9 )
{ {
msg_Dbg( p_demux, " * descriptor : CA (0x9)" ); uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
i_cad_length += p_dr->i_length + 2; | p_dr->p_data[1];
msg_Dbg( p_demux, " * descriptor : CA (0x9) SysID 0x%x", i_sysid );
if ( !p_sys->i_capmt_sysid || p_sys->i_capmt_sysid == i_sysid )
i_cad_length += p_dr->i_length + 2;
} }
else else
{ {
...@@ -2049,7 +2062,7 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -2049,7 +2062,7 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
prg->p_capmt[0] = p_pmt->i_program_number >> 8; prg->p_capmt[0] = p_pmt->i_program_number >> 8;
prg->p_capmt[1] = p_pmt->i_program_number & 0xff; prg->p_capmt[1] = p_pmt->i_program_number & 0xff;
prg->p_capmt[2] = (p_pmt->i_version << 1) | 0x1; prg->p_capmt[2] = ((p_pmt->i_version & 0x1f) << 1) | 0x1;
prg->p_capmt[3] = (i_cad_length + 1) >> 8; prg->p_capmt[3] = (i_cad_length + 1) >> 8;
prg->p_capmt[4] = (i_cad_length + 1) & 0xff; prg->p_capmt[4] = (i_cad_length + 1) & 0xff;
prg->p_capmt[5] = 0x1; /* ok_descrambling */ prg->p_capmt[5] = 0x1; /* ok_descrambling */
...@@ -2059,10 +2072,15 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -2059,10 +2072,15 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
{ {
if( p_dr->i_tag == 0x9 ) if( p_dr->i_tag == 0x9 )
{ {
prg->p_capmt[i] = 0x9; uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
prg->p_capmt[i+1] = p_dr->i_length; | p_dr->p_data[1];
memcpy( &prg->p_capmt[i+2], p_dr->p_data, p_dr->i_length ); if ( !p_sys->i_capmt_sysid || p_sys->i_capmt_sysid == i_sysid )
i += p_dr->i_length + 2; {
prg->p_capmt[i] = 0x9;
prg->p_capmt[i+1] = p_dr->i_length;
memcpy( &prg->p_capmt[i+2], p_dr->p_data, p_dr->i_length );
i += p_dr->i_length + 2;
}
} }
} }
} }
...@@ -2449,8 +2467,12 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -2449,8 +2467,12 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
{ {
if( p_dr->i_tag == 0x9 ) if( p_dr->i_tag == 0x9 )
{ {
msg_Dbg( p_demux, " * descriptor : CA (0x9)" ); uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
i_cad_length += p_dr->i_length + 2; | p_dr->p_data[1];
msg_Dbg( p_demux, " * descriptor : CA (0x9) SysID 0x%x",
i_sysid );
if ( !p_sys->i_capmt_sysid || p_sys->i_capmt_sysid == i_sysid )
i_cad_length += p_dr->i_length + 2;
} }
else else
{ {
...@@ -2468,7 +2490,7 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -2468,7 +2490,7 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
prg->p_capmt[0] = p_pmt->i_program_number >> 8; prg->p_capmt[0] = p_pmt->i_program_number >> 8;
prg->p_capmt[1] = p_pmt->i_program_number & 0xff; prg->p_capmt[1] = p_pmt->i_program_number & 0xff;
prg->p_capmt[2] = (p_pmt->i_version << 1) | 0x1; prg->p_capmt[2] = ((p_pmt->i_version & 0x1f) << 1) | 0x1;
prg->p_capmt[3] = 0; /* cad length */ prg->p_capmt[3] = 0; /* cad length */
prg->p_capmt[4] = 0; prg->p_capmt[4] = 0;
...@@ -2494,10 +2516,16 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -2494,10 +2516,16 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
{ {
if( p_dr->i_tag == 0x9 ) if( p_dr->i_tag == 0x9 )
{ {
prg->p_capmt[i] = 0x9; uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
prg->p_capmt[i+1] = p_dr->i_length; | p_dr->p_data[1];
memcpy( &prg->p_capmt[i+2], p_dr->p_data, p_dr->i_length ); if ( !p_sys->i_capmt_sysid
i += p_dr->i_length + 2; || p_sys->i_capmt_sysid == i_sysid )
{
prg->p_capmt[i] = 0x9;
prg->p_capmt[i+1] = p_dr->i_length;
memcpy( &prg->p_capmt[i+2], p_dr->p_data, p_dr->i_length );
i += p_dr->i_length + 2;
}
} }
} }
} }
...@@ -2697,7 +2725,7 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat ) ...@@ -2697,7 +2725,7 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat )
/* Now select PID at access level */ /* Now select PID at access level */
if( p_sys->b_dvb_control ) if( p_sys->b_dvb_control )
{ {
if( p_sys->i_dvb_program <= 0 || p_sys->i_dvb_program == p_program->i_number ) if( DVBProgramIsSelected( p_demux, p_program->i_number ) )
{ {
if( p_sys->i_dvb_program == 0 ) if( p_sys->i_dvb_program == 0 )
p_sys->i_dvb_program = p_program->i_number; p_sys->i_dvb_program = p_program->i_number;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment