Commit f324c82b authored by Christophe Massiot's avatar Christophe Massiot

* modules/access/dvb: Fixed a bug with CAMs which take a long time to

   initialize.
parent ea928459
......@@ -102,7 +102,6 @@ int E_(CAMPoll)( access_t * );
int E_(CAMSet)( access_t *, uint8_t **, int );
void E_(CAMClose)( access_t * );
int E_(en50221_Init)( access_t * );
int E_(en50221_Poll)( access_t * );
int E_(en50221_SetCAPMT)( access_t *, uint8_t **, int );
void E_(en50221_End)( access_t * );
......
......@@ -36,6 +36,12 @@
#include <sys/stat.h>
#include <sys/poll.h>
/* DVB Card Drivers */
#include <linux/dvb/version.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/ca.h>
#include "dvb.h"
#undef DEBUG_TPDU
......@@ -907,61 +913,61 @@ static void MMIOpen( access_t * p_access, int i_session_id )
/*
* External entry points
* Hardware handling
*/
/*****************************************************************************
* en50221_Init : Open the transport layer
* InitSlot: Open the transport layer
*****************************************************************************/
#define MAX_TC_RETRIES 20
int E_(en50221_Init)( access_t * p_access )
static int InitSlot( access_t * p_access, int i_slot )
{
access_sys_t *p_sys = p_access->p_sys;
int i_slot, i_active_slots = 0;
int i;
for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ )
if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 )
!= VLC_SUCCESS )
{
int i;
if ( !p_sys->pb_active_slot[i_slot] )
continue;
p_sys->pb_active_slot[i_slot] = VLC_FALSE;
msg_Err( p_access, "en50221_Init: couldn't send TPDU on slot %d",
i_slot );
return VLC_EGENERIC;
}
/* This is out of the spec */
for ( i = 0; i < MAX_TC_RETRIES; i++ )
{
uint8_t i_tag;
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) == VLC_SUCCESS
&& i_tag == T_CTC_REPLY )
{
p_sys->pb_active_slot[i_slot] = VLC_TRUE;
break;
}
if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 )
!= VLC_SUCCESS )
{
msg_Err( p_access, "en50221_Init: couldn't send TPDU on slot %d",
msg_Err( p_access,
"en50221_Init: couldn't send TPDU on slot %d",
i_slot );
continue;
}
/* This is out of the spec */
for ( i = 0; i < MAX_TC_RETRIES; i++ )
{
uint8_t i_tag;
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) == VLC_SUCCESS
&& i_tag == T_CTC_REPLY )
{
p_sys->pb_active_slot[i_slot] = VLC_TRUE;
i_active_slots++;
break;
}
if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 )
!= VLC_SUCCESS )
{
msg_Err( p_access,
"en50221_Init: couldn't send TPDU on slot %d",
i_slot );
continue;
}
}
}
p_sys->i_ca_timeout = 1000;
if ( p_sys->pb_active_slot[i_slot] )
{
p_sys->i_ca_timeout = 1000;
return VLC_SUCCESS;
}
return i_active_slots;
return VLC_EGENERIC;
}
/*
* External entry points
*/
/*****************************************************************************
* en50221_Poll : Poll the CAM for TPDUs
*****************************************************************************/
......@@ -976,7 +982,27 @@ int E_(en50221_Poll)( access_t * p_access )
uint8_t i_tag;
if ( !p_sys->pb_active_slot[i_slot] )
continue;
{
ca_slot_info_t sinfo;
sinfo.num = i_slot;
if ( ioctl( p_sys->i_ca_handle, CA_GET_SLOT_INFO, &sinfo ) != 0 )
{
msg_Err( p_access, "en50221_Poll: couldn't get info on slot %d",
i_slot );
continue;
}
if ( sinfo.flags & CA_CI_MODULE_READY )
{
msg_Dbg( p_access, "en50221_Poll: slot %d is active",
i_slot );
p_sys->pb_active_slot[i_slot] = VLC_TRUE;
}
else
continue;
InitSlot( p_access, i_slot );
}
if ( !p_sys->pb_tc_has_data[i_slot] )
{
......@@ -1061,7 +1087,7 @@ int E_(en50221_SetCAPMT)( access_t * p_access, uint8_t **pp_capmts,
access_sys_t *p_sys = p_access->p_sys;
int i_session_id;
for ( i_session_id = 0; i_session_id < MAX_SESSIONS; i_session_id++ )
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{
int i;
......
......@@ -47,7 +47,6 @@
#include "dvb.h"
#define DMX_BUFFER_SIZE (1024 * 1024)
#define CA_MAX_STATE_RETRY 5
/*
* Frontends
......@@ -1116,7 +1115,7 @@ int E_(CAMOpen)( access_t *p_access )
{
access_sys_t *p_sys = p_access->p_sys;
char ca[128];
int i_adapter, i_device, i_slot, i_active_slots = 0;
int i_adapter, i_device, i_slot;
ca_caps_t caps;
i_adapter = var_GetInteger( p_access, "dvb-adapter" );
......@@ -1133,6 +1132,7 @@ int E_(CAMOpen)( access_t *p_access )
{
msg_Err( p_access, "CAMInit: opening device failed (%s)",
strerror(errno) );
p_sys->i_ca_handle = 0;
return VLC_EGENERIC;
}
......@@ -1150,45 +1150,18 @@ int E_(CAMOpen)( access_t *p_access )
for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ )
{
ca_slot_info_t sinfo;
int i;
if ( ioctl( p_sys->i_ca_handle, CA_RESET, 1 << i_slot) != 0 )
{
msg_Err( p_access, "CAMInit: couldn't reset slot %d", i_slot );
continue;
}
for ( i = 0; i < CA_MAX_STATE_RETRY; i++ )
{
msleep(100000);
sinfo.num = i_slot;
if ( ioctl( p_sys->i_ca_handle, CA_GET_SLOT_INFO, &sinfo ) != 0 )
{
msg_Err( p_access, "CAMInit: couldn't get info on slot %d",
i_slot );
continue;
}
if ( sinfo.flags & CA_CI_MODULE_READY )
{
p_sys->pb_active_slot[i_slot] = VLC_TRUE;
}
}
}
i_active_slots = E_(en50221_Init)( p_access );
msg_Dbg( p_access, "CAMInit: found a CI handler with %d slots",
p_sys->i_nb_slots );
msg_Dbg( p_access, "CAMInit: found a CI handler with %d slots, %d active",
p_sys->i_nb_slots, i_active_slots );
if ( !i_active_slots )
{
close( p_sys->i_ca_handle );
p_sys->i_ca_handle = 0;
return VLC_EGENERIC;
}
p_sys->i_ca_timeout = 100000;
/* Wait a bit otherwise it doesn't initialize properly... */
msleep( 1000000 );
return VLC_SUCCESS;
}
......
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