Commit 3c83efbe authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

DVB: separate CA management

parent cc4cb782
SOURCES_dvb = \ SOURCES_dvb = \
access.c \ access.c \
scan.c \ scan.c scan.h \
scan.h \
linux_dvb.c \ linux_dvb.c \
en50221.c \ en50221.c en50221.h \
http.c \ http.c \
dvb.h \ dvb.h \
$(NULL) $(NULL)
...@@ -473,11 +473,7 @@ static block_t *Block( access_t *p_access ) ...@@ -473,11 +473,7 @@ static block_t *Block( access_t *p_access )
return NULL; return NULL;
} }
if ( p_sys->i_ca_handle && mdate() > p_sys->i_ca_next_event )
{
CAMPoll( p_access ); CAMPoll( p_access );
p_sys->i_ca_next_event = mdate() + p_sys->i_ca_timeout;
}
if ( ufds[1].revents ) if ( ufds[1].revents )
{ {
......
...@@ -51,113 +51,19 @@ typedef struct ...@@ -51,113 +51,19 @@ typedef struct
typedef struct scan_parameter_t scan_parameter_t; typedef struct scan_parameter_t scan_parameter_t;
typedef struct scan_t scan_t; typedef struct scan_t scan_t;
typedef struct en50221_session_t
{
int i_slot;
int i_resource_id;
void (* pf_handle)( access_t *, int, uint8_t *, int );
void (* pf_close)( access_t *, int );
void (* pf_manage)( access_t *, int );
void *p_sys;
} en50221_session_t;
#define EN50221_MMI_NONE 0
#define EN50221_MMI_ENQ 1
#define EN50221_MMI_ANSW 2
#define EN50221_MMI_MENU 3
#define EN50221_MMI_MENU_ANSW 4
#define EN50221_MMI_LIST 5
typedef struct en50221_mmi_object_t
{
int i_object_type;
union
{
struct
{
bool b_blind;
char *psz_text;
} enq;
struct
{
bool b_ok;
char *psz_answ;
} answ;
struct
{
char *psz_title, *psz_subtitle, *psz_bottom;
char **ppsz_choices;
int i_choices;
} menu; /* menu and list are the same */
struct
{
int i_choice;
} menu_answ;
} u;
} en50221_mmi_object_t;
static inline void en50221_MMIFree( en50221_mmi_object_t *p_object )
{
int i;
switch ( p_object->i_object_type )
{
case EN50221_MMI_ENQ:
FREENULL( p_object->u.enq.psz_text );
break;
case EN50221_MMI_ANSW:
if ( p_object->u.answ.b_ok )
{
FREENULL( p_object->u.answ.psz_answ );
}
break;
case EN50221_MMI_MENU:
case EN50221_MMI_LIST:
FREENULL( p_object->u.menu.psz_title );
FREENULL( p_object->u.menu.psz_subtitle );
FREENULL( p_object->u.menu.psz_bottom );
for ( i = 0; i < p_object->u.menu.i_choices; i++ )
{
free( p_object->u.menu.ppsz_choices[i] );
}
FREENULL( p_object->u.menu.ppsz_choices );
break;
default:
break;
}
}
#define MAX_DEMUX 256 #define MAX_DEMUX 256
#define MAX_CI_SLOTS 16
#define MAX_SESSIONS 32 #include "en50221.h"
#define MAX_PROGRAMS 24
struct access_sys_t struct access_sys_t
{ {
int i_handle, i_frontend_handle; int i_handle, i_frontend_handle;
demux_handle_t p_demux_handles[MAX_DEMUX]; demux_handle_t p_demux_handles[MAX_DEMUX];
frontend_t *p_frontend; frontend_t *p_frontend;
mtime_t i_frontend_timeout;
bool b_budget_mode; bool b_budget_mode;
/* CA management */ cam_t cam;
int i_ca_handle;
int i_ca_type;
int i_nb_slots;
bool pb_active_slot[MAX_CI_SLOTS];
bool pb_tc_has_data[MAX_CI_SLOTS];
bool pb_slot_mmi_expected[MAX_CI_SLOTS];
bool pb_slot_mmi_undisplayed[MAX_CI_SLOTS];
en50221_session_t p_sessions[MAX_SESSIONS];
mtime_t i_ca_timeout, i_ca_next_event, i_frontend_timeout;
dvbpsi_pmt_t *pp_selected_programs[MAX_PROGRAMS];
int i_selected_programs;
/* */ /* */
int i_read_once; int i_read_once;
...@@ -220,19 +126,6 @@ void CAMClose( access_t * ); ...@@ -220,19 +126,6 @@ void CAMClose( access_t * );
void CAMStatus( access_t * ); void CAMStatus( access_t * );
#endif #endif
int en50221_Init( access_t * );
int en50221_Poll( access_t * );
int en50221_SetCAPMT( access_t *, dvbpsi_pmt_t * );
int en50221_OpenMMI( access_t * p_access, int i_slot );
int en50221_CloseMMI( access_t * p_access, int i_slot );
en50221_mmi_object_t *en50221_GetMMIObject( access_t * p_access,
int i_slot );
void en50221_SendMMIObject( access_t * p_access, int i_slot,
en50221_mmi_object_t *p_object );
void en50221_End( access_t * );
char *dvbsi_to_utf8( const char *psz_instring, size_t i_length );
#ifdef ENABLE_HTTPD #ifdef ENABLE_HTTPD
int HTTPOpen( access_t *p_access ); int HTTPOpen( access_t *p_access );
void HTTPClose( access_t *p_access ); void HTTPClose( access_t *p_access );
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#endif #endif
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_access.h>
#include <vlc_charset.h> #include <vlc_charset.h>
#include <errno.h> #include <errno.h>
...@@ -61,11 +60,11 @@ ...@@ -61,11 +60,11 @@
#define CAM_PROG_MAX MAX_PROGRAMS #define CAM_PROG_MAX MAX_PROGRAMS
//#define CAPMT_WAIT 100 /* uncomment this for slow CAMs */ //#define CAPMT_WAIT 100 /* uncomment this for slow CAMs */
static void ResourceManagerOpen( access_t * p_access, int i_session_id ); static void ResourceManagerOpen( cam_t *, unsigned i_session_id );
static void ApplicationInformationOpen( access_t * p_access, int i_session_id ); static void ApplicationInformationOpen( cam_t *, unsigned i_session_id );
static void ConditionalAccessOpen( access_t * p_access, int i_session_id ); static void ConditionalAccessOpen( cam_t *, unsigned i_session_id );
static void DateTimeOpen( access_t * p_access, int i_session_id ); static void DateTimeOpen( cam_t *, unsigned i_session_id );
static void MMIOpen( access_t * p_access, int i_session_id ); static void MMIOpen( cam_t *, unsigned i_session_id );
/***************************************************************************** /*****************************************************************************
* Utility functions * Utility functions
...@@ -166,10 +165,9 @@ static void Dump( bool b_outgoing, uint8_t *p_data, int i_size ) ...@@ -166,10 +165,9 @@ static void Dump( bool b_outgoing, uint8_t *p_data, int i_size )
/***************************************************************************** /*****************************************************************************
* TPDUSend * TPDUSend
*****************************************************************************/ *****************************************************************************/
static int TPDUSend( access_t * p_access, uint8_t i_slot, uint8_t i_tag, static int TPDUSend( cam_t * p_cam, uint8_t i_slot, uint8_t i_tag,
const uint8_t *p_content, int i_length ) const uint8_t *p_content, int i_length )
{ {
access_sys_t *p_sys = p_access->p_sys;
uint8_t i_tcid = i_slot + 1; uint8_t i_tcid = i_slot + 1;
uint8_t p_data[MAX_TPDU_SIZE]; uint8_t p_data[MAX_TPDU_SIZE];
int i_size; int i_size;
...@@ -219,9 +217,9 @@ static int TPDUSend( access_t * p_access, uint8_t i_slot, uint8_t i_tag, ...@@ -219,9 +217,9 @@ static int TPDUSend( access_t * p_access, uint8_t i_slot, uint8_t i_tag,
} }
Dump( true, p_data, i_size ); Dump( true, p_data, i_size );
if ( write( p_sys->i_ca_handle, p_data, i_size ) != i_size ) if ( write( p_cam->fd, p_data, i_size ) != i_size )
{ {
msg_Err( p_access, "cannot write to CAM device (%m)" ); msg_Err( p_cam->obj, "cannot write to CAM device (%m)" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -234,27 +232,26 @@ static int TPDUSend( access_t * p_access, uint8_t i_slot, uint8_t i_tag, ...@@ -234,27 +232,26 @@ static int TPDUSend( access_t * p_access, uint8_t i_slot, uint8_t i_tag,
*****************************************************************************/ *****************************************************************************/
#define CAM_READ_TIMEOUT 3500 // ms #define CAM_READ_TIMEOUT 3500 // ms
static int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag, static int TPDURecv( cam_t *p_cam, uint8_t i_slot, uint8_t *pi_tag,
uint8_t *p_data, int *pi_size ) uint8_t *p_data, int *pi_size )
{ {
access_sys_t *p_sys = p_access->p_sys;
uint8_t i_tcid = i_slot + 1; uint8_t i_tcid = i_slot + 1;
int i_size; int i_size;
struct pollfd pfd[1]; struct pollfd pfd[1];
pfd[0].fd = p_sys->i_ca_handle; pfd[0].fd = p_cam->fd;
pfd[0].events = POLLIN; pfd[0].events = POLLIN;
while( poll(pfd, 1, CAM_READ_TIMEOUT ) == -1 ) while( poll(pfd, 1, CAM_READ_TIMEOUT ) == -1 )
if( errno != EINTR ) if( errno != EINTR )
{ {
msg_Err( p_access, "poll error: %m" ); msg_Err( p_cam->obj, "poll error: %m" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if ( !(pfd[0].revents & POLLIN) ) if ( !(pfd[0].revents & POLLIN) )
{ {
msg_Err( p_access, "CAM device poll time-out" ); msg_Err( p_cam->obj, "CAM device poll time-out" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -265,7 +262,7 @@ static int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag, ...@@ -265,7 +262,7 @@ static int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag,
for ( ; ; ) for ( ; ; )
{ {
i_size = read( p_sys->i_ca_handle, p_data, MAX_TPDU_SIZE ); i_size = read( p_cam->fd, p_data, MAX_TPDU_SIZE );
if ( i_size >= 0 || errno != EINTR ) if ( i_size >= 0 || errno != EINTR )
break; break;
...@@ -273,7 +270,7 @@ static int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag, ...@@ -273,7 +270,7 @@ static int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag,
if ( i_size < 5 ) if ( i_size < 5 )
{ {
msg_Err( p_access, "cannot read from CAM device (%d:%m)", i_size ); msg_Err( p_cam->obj, "cannot read from CAM device (%d:%m)", i_size );
if( pi_size == NULL ) if( pi_size == NULL )
free( p_data ); free( p_data );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -281,7 +278,7 @@ static int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag, ...@@ -281,7 +278,7 @@ static int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag,
if ( p_data[1] != i_tcid ) if ( p_data[1] != i_tcid )
{ {
msg_Err( p_access, "invalid read from CAM device (%d instead of %d)", msg_Err( p_cam->obj, "invalid read from CAM device (%d instead of %d)",
p_data[1], i_tcid ); p_data[1], i_tcid );
if( pi_size == NULL ) if( pi_size == NULL )
free( p_data ); free( p_data );
...@@ -289,7 +286,7 @@ static int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag, ...@@ -289,7 +286,7 @@ static int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag,
} }
*pi_tag = p_data[2]; *pi_tag = p_data[2];
p_sys->pb_tc_has_data[i_slot] = (i_size >= 4 p_cam->pb_tc_has_data[i_slot] = (i_size >= 4
&& p_data[i_size - 4] == T_SB && p_data[i_size - 4] == T_SB
&& p_data[i_size - 3] == 2 && p_data[i_size - 3] == 2
&& (p_data[i_size - 1] & DATA_INDICATOR)) && (p_data[i_size - 1] & DATA_INDICATOR))
...@@ -337,14 +334,13 @@ static int ResourceIdToInt( uint8_t *p_data ) ...@@ -337,14 +334,13 @@ static int ResourceIdToInt( uint8_t *p_data )
/***************************************************************************** /*****************************************************************************
* SPDUSend * SPDUSend
*****************************************************************************/ *****************************************************************************/
static int SPDUSend( access_t * p_access, int i_session_id, static int SPDUSend( cam_t * p_cam, int i_session_id,
uint8_t *p_data, int i_size ) uint8_t *p_data, int i_size )
{ {
access_sys_t *p_sys = p_access->p_sys;
uint8_t *p_spdu = xmalloc( i_size + 4 ); uint8_t *p_spdu = xmalloc( i_size + 4 );
uint8_t *p = p_spdu; uint8_t *p = p_spdu;
uint8_t i_tag; uint8_t i_tag;
uint8_t i_slot = p_sys->p_sessions[i_session_id - 1].i_slot; uint8_t i_slot = p_cam->p_sessions[i_session_id - 1].i_slot;
*p++ = ST_SESSION_NUMBER; *p++ = ST_SESSION_NUMBER;
*p++ = 0x02; *p++ = 0x02;
...@@ -360,10 +356,10 @@ static int SPDUSend( access_t * p_access, int i_session_id, ...@@ -360,10 +356,10 @@ static int SPDUSend( access_t * p_access, int i_session_id,
{ {
if ( i_size > MAX_TPDU_DATA ) if ( i_size > MAX_TPDU_DATA )
{ {
if ( TPDUSend( p_access, i_slot, T_DATA_MORE, p, if ( TPDUSend( p_cam, i_slot, T_DATA_MORE, p,
MAX_TPDU_DATA ) != VLC_SUCCESS ) MAX_TPDU_DATA ) != VLC_SUCCESS )
{ {
msg_Err( p_access, "couldn't send TPDU on session %d", msg_Err( p_cam->obj, "couldn't send TPDU on session %d",
i_session_id ); i_session_id );
free( p_spdu ); free( p_spdu );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -373,10 +369,10 @@ static int SPDUSend( access_t * p_access, int i_session_id, ...@@ -373,10 +369,10 @@ static int SPDUSend( access_t * p_access, int i_session_id,
} }
else else
{ {
if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p, i_size ) if ( TPDUSend( p_cam, i_slot, T_DATA_LAST, p, i_size )
!= VLC_SUCCESS ) != VLC_SUCCESS )
{ {
msg_Err( p_access, "couldn't send TPDU on session %d", msg_Err( p_cam->obj, "couldn't send TPDU on session %d",
i_session_id ); i_session_id );
free( p_spdu ); free( p_spdu );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -384,10 +380,10 @@ static int SPDUSend( access_t * p_access, int i_session_id, ...@@ -384,10 +380,10 @@ static int SPDUSend( access_t * p_access, int i_session_id,
i_size = 0; i_size = 0;
} }
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS if ( TPDURecv( p_cam, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS
|| i_tag != T_SB ) || i_tag != T_SB )
{ {
msg_Err( p_access, "couldn't recv TPDU on session %d", msg_Err( p_cam->obj, "couldn't recv TPDU on session %d",
i_session_id ); i_session_id );
free( p_spdu ); free( p_spdu );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -401,12 +397,11 @@ static int SPDUSend( access_t * p_access, int i_session_id, ...@@ -401,12 +397,11 @@ static int SPDUSend( access_t * p_access, int i_session_id,
/***************************************************************************** /*****************************************************************************
* SessionOpen * SessionOpen
*****************************************************************************/ *****************************************************************************/
static void SessionOpen( access_t * p_access, uint8_t i_slot, static void SessionOpen( cam_t * p_cam, uint8_t i_slot,
uint8_t *p_spdu, int i_size ) uint8_t *p_spdu, int i_size )
{ {
VLC_UNUSED( i_size ); VLC_UNUSED( i_size );
access_sys_t *p_sys = p_access->p_sys;
int i_session_id; int i_session_id;
int i_resource_id = ResourceIdToInt( &p_spdu[2] ); int i_resource_id = ResourceIdToInt( &p_spdu[2] );
uint8_t p_response[16]; uint8_t p_response[16];
...@@ -415,18 +410,18 @@ static void SessionOpen( access_t * p_access, uint8_t i_slot, ...@@ -415,18 +410,18 @@ static void SessionOpen( access_t * p_access, uint8_t i_slot,
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ ) for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{ {
if ( !p_sys->p_sessions[i_session_id - 1].i_resource_id ) if ( !p_cam->p_sessions[i_session_id - 1].i_resource_id )
break; break;
} }
if ( i_session_id > MAX_SESSIONS ) if ( i_session_id > MAX_SESSIONS )
{ {
msg_Err( p_access, "too many sessions !" ); msg_Err( p_cam->obj, "too many sessions !" );
return; return;
} }
p_sys->p_sessions[i_session_id - 1].i_slot = i_slot; p_cam->p_sessions[i_session_id - 1].i_slot = i_slot;
p_sys->p_sessions[i_session_id - 1].i_resource_id = i_resource_id; p_cam->p_sessions[i_session_id - 1].i_resource_id = i_resource_id;
p_sys->p_sessions[i_session_id - 1].pf_close = NULL; p_cam->p_sessions[i_session_id - 1].pf_close = NULL;
p_sys->p_sessions[i_session_id - 1].pf_manage = NULL; p_cam->p_sessions[i_session_id - 1].pf_manage = NULL;
if ( i_resource_id == RI_RESOURCE_MANAGER if ( i_resource_id == RI_RESOURCE_MANAGER
|| i_resource_id == RI_APPLICATION_INFORMATION || i_resource_id == RI_APPLICATION_INFORMATION
...@@ -447,16 +442,16 @@ static void SessionOpen( access_t * p_access, uint8_t i_slot, ...@@ -447,16 +442,16 @@ static void SessionOpen( access_t * p_access, uint8_t i_slot,
p_response[7] = i_session_id >> 8; p_response[7] = i_session_id >> 8;
p_response[8] = i_session_id & 0xff; p_response[8] = i_session_id & 0xff;
if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p_response, 9 ) != if ( TPDUSend( p_cam, i_slot, T_DATA_LAST, p_response, 9 ) !=
VLC_SUCCESS ) VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"SessionOpen: couldn't send TPDU on slot %d", i_slot ); "SessionOpen: couldn't send TPDU on slot %d", i_slot );
return; return;
} }
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS ) if ( TPDURecv( p_cam, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"SessionOpen: couldn't recv TPDU on slot %d", i_slot ); "SessionOpen: couldn't recv TPDU on slot %d", i_slot );
return; return;
} }
...@@ -464,20 +459,20 @@ static void SessionOpen( access_t * p_access, uint8_t i_slot, ...@@ -464,20 +459,20 @@ static void SessionOpen( access_t * p_access, uint8_t i_slot,
switch ( i_resource_id ) switch ( i_resource_id )
{ {
case RI_RESOURCE_MANAGER: case RI_RESOURCE_MANAGER:
ResourceManagerOpen( p_access, i_session_id ); break; ResourceManagerOpen( p_cam, i_session_id ); break;
case RI_APPLICATION_INFORMATION: case RI_APPLICATION_INFORMATION:
ApplicationInformationOpen( p_access, i_session_id ); break; ApplicationInformationOpen( p_cam, i_session_id ); break;
case RI_CONDITIONAL_ACCESS_SUPPORT: case RI_CONDITIONAL_ACCESS_SUPPORT:
ConditionalAccessOpen( p_access, i_session_id ); break; ConditionalAccessOpen( p_cam, i_session_id ); break;
case RI_DATE_TIME: case RI_DATE_TIME:
DateTimeOpen( p_access, i_session_id ); break; DateTimeOpen( p_cam, i_session_id ); break;
case RI_MMI: case RI_MMI:
MMIOpen( p_access, i_session_id ); break; MMIOpen( p_cam, i_session_id ); break;
case RI_HOST_CONTROL: case RI_HOST_CONTROL:
default: default:
msg_Err( p_access, "unknown resource id (0x%x)", i_resource_id ); msg_Err( p_cam->obj, "unknown resource id (0x%x)", i_resource_id );
p_sys->p_sessions[i_session_id - 1].i_resource_id = 0; p_cam->p_sessions[i_session_id - 1].i_resource_id = 0;
} }
} }
...@@ -486,48 +481,43 @@ static void SessionOpen( access_t * p_access, uint8_t i_slot, ...@@ -486,48 +481,43 @@ static void SessionOpen( access_t * p_access, uint8_t i_slot,
/***************************************************************************** /*****************************************************************************
* SessionCreate * SessionCreate
*****************************************************************************/ *****************************************************************************/
static void SessionCreate( access_t * p_access, int i_slot, int i_resource_id ) static void SessionCreate( cam_t * p_cam, int i_slot, int i_resource_id )
{ {
access_sys_t *p_sys = p_access->p_sys;
uint8_t p_response[16]; uint8_t p_response[16];
uint8_t i_tag; uint8_t i_tag;
int i_session_id; int i_session_id;
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ ) for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{ {
if ( !p_sys->p_sessions[i_session_id - 1].i_resource_id ) if ( !p_cam->p_sessions[i_session_id - 1].i_resource_id )
break; break;
} }
if ( i_session_id == MAX_SESSIONS ) if ( i_session_id == MAX_SESSIONS )
{ {
msg_Err( p_access, "too many sessions !" ); msg_Err( p_cam->obj, "too many sessions !" );
return; return;
} }
p_sys->p_sessions[i_session_id - 1].i_slot = i_slot; p_cam->p_sessions[i_session_id - 1].i_slot = i_slot;
p_sys->p_sessions[i_session_id - 1].i_resource_id = i_resource_id; p_cam->p_sessions[i_session_id - 1].i_resource_id = i_resource_id;
p_sys->p_sessions[i_session_id - 1].pf_close = NULL; p_cam->p_sessions[i_session_id - 1].pf_close = NULL;
p_sys->p_sessions[i_session_id - 1].pf_manage = NULL; p_cam->p_sessions[i_session_id - 1].pf_manage = NULL;
p_sys->p_sessions[i_session_id - 1].p_sys = NULL; p_cam->p_sessions[i_session_id - 1].p_sys = NULL;
p_response[0] = ST_CREATE_SESSION; p_response[0] = ST_CREATE_SESSION;
p_response[1] = 0x6; p_response[1] = 0x6;
p_response[2] = i_resource_id >> 24; SetDWBE( &p_resource[2], i_resource_id );
p_response[3] = (i_resource_id >> 16) & 0xff; SetWBE( &p_response[6]. i_session_id);
p_response[4] = (i_resource_id >> 8) & 0xff;
p_response[5] = i_resource_id & 0xff; if ( TPDUSend( p_cam, i_slot, T_DATA_LAST, p_response, 4 ) !=
p_response[6] = i_session_id >> 8;
p_response[7] = i_session_id & 0xff;
if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p_response, 4 ) !=
VLC_SUCCESS ) VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"SessionCreate: couldn't send TPDU on slot %d", i_slot ); "SessionCreate: couldn't send TPDU on slot %d", i_slot );
return; return;
} }
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS ) if ( TPDURecv( p_cam, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"SessionCreate: couldn't recv TPDU on slot %d", i_slot ); "SessionCreate: couldn't recv TPDU on slot %d", i_slot );
return; return;
} }
...@@ -537,71 +527,68 @@ static void SessionCreate( access_t * p_access, int i_slot, int i_resource_id ) ...@@ -537,71 +527,68 @@ static void SessionCreate( access_t * p_access, int i_slot, int i_resource_id )
/***************************************************************************** /*****************************************************************************
* SessionCreateResponse * SessionCreateResponse
*****************************************************************************/ *****************************************************************************/
static void SessionCreateResponse( access_t * p_access, uint8_t i_slot, static void SessionCreateResponse( cam_t * p_cam, uint8_t i_slot,
uint8_t *p_spdu, int i_size ) uint8_t *p_spdu, int i_size )
{ {
VLC_UNUSED( i_size ); VLC_UNUSED( i_size );
VLC_UNUSED( i_slot ); VLC_UNUSED( i_slot );
access_sys_t *p_sys = p_access->p_sys;
int i_status = p_spdu[2]; int i_status = p_spdu[2];
int i_resource_id = ResourceIdToInt( &p_spdu[3] ); int i_resource_id = ResourceIdToInt( &p_spdu[3] );
int i_session_id = ((int)p_spdu[7] << 8) | p_spdu[8]; int i_session_id = ((int)p_spdu[7] << 8) | p_spdu[8];
if ( i_status != SS_OK ) if ( i_status != SS_OK )
{ {
msg_Err( p_access, "SessionCreateResponse: failed to open session %d" msg_Err( p_cam->obj, "SessionCreateResponse: failed to open session %d"
" resource=0x%x status=0x%x", i_session_id, i_resource_id, " resource=0x%x status=0x%x", i_session_id, i_resource_id,
i_status ); i_status );
p_sys->p_sessions[i_session_id - 1].i_resource_id = 0; p_cam->p_sessions[i_session_id - 1].i_resource_id = 0;
return; return;
} }
switch ( i_resource_id ) switch ( i_resource_id )
{ {
case RI_RESOURCE_MANAGER: case RI_RESOURCE_MANAGER:
ResourceManagerOpen( p_access, i_session_id ); break; ResourceManagerOpen( p_cam, i_session_id ); break;
case RI_APPLICATION_INFORMATION: case RI_APPLICATION_INFORMATION:
ApplicationInformationOpen( p_access, i_session_id ); break; ApplicationInformationOpen( p_cam, i_session_id ); break;
case RI_CONDITIONAL_ACCESS_SUPPORT: case RI_CONDITIONAL_ACCESS_SUPPORT:
ConditionalAccessOpen( p_access, i_session_id ); break; ConditionalAccessOpen( p_cam, i_session_id ); break;
case RI_DATE_TIME: case RI_DATE_TIME:
DateTimeOpen( p_access, i_session_id ); break; DateTimeOpen( p_cam, i_session_id ); break;
case RI_MMI: case RI_MMI:
MMIOpen( p_access, i_session_id ); break; MMIOpen( p_cam, i_session_id ); break;
case RI_HOST_CONTROL: case RI_HOST_CONTROL:
default: default:
msg_Err( p_access, "unknown resource id (0x%x)", i_resource_id ); msg_Err( p_cam->obj, "unknown resource id (0x%x)", i_resource_id );
p_sys->p_sessions[i_session_id - 1].i_resource_id = 0; p_cam->p_sessions[i_session_id - 1].i_resource_id = 0;
} }
} }
/***************************************************************************** /*****************************************************************************
* SessionSendClose * SessionSendClose
*****************************************************************************/ *****************************************************************************/
static void SessionSendClose( access_t * p_access, int i_session_id ) static void SessionSendClose( cam_t *p_cam, int i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys;
uint8_t p_response[16]; uint8_t p_response[16];
uint8_t i_tag; uint8_t i_tag;
uint8_t i_slot = p_sys->p_sessions[i_session_id - 1].i_slot; uint8_t i_slot = p_cam->p_sessions[i_session_id - 1].i_slot;
p_response[0] = ST_CLOSE_SESSION_REQUEST; p_response[0] = ST_CLOSE_SESSION_REQUEST;
p_response[1] = 0x2; p_response[1] = 0x2;
p_response[2] = i_session_id >> 8; SetWBE( &p_response[2], i_session_id );
p_response[3] = i_session_id & 0xff;
if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p_response, 4 ) != if ( TPDUSend( p_cam, i_slot, T_DATA_LAST, p_response, 4 ) !=
VLC_SUCCESS ) VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"SessionSendClose: couldn't send TPDU on slot %d", i_slot ); "SessionSendClose: couldn't send TPDU on slot %d", i_slot );
return; return;
} }
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS ) if ( TPDURecv( p_cam, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"SessionSendClose: couldn't recv TPDU on slot %d", i_slot ); "SessionSendClose: couldn't recv TPDU on slot %d", i_slot );
return; return;
} }
...@@ -610,16 +597,15 @@ static void SessionSendClose( access_t * p_access, int i_session_id ) ...@@ -610,16 +597,15 @@ static void SessionSendClose( access_t * p_access, int i_session_id )
/***************************************************************************** /*****************************************************************************
* SessionClose * SessionClose
*****************************************************************************/ *****************************************************************************/
static void SessionClose( access_t * p_access, int i_session_id ) static void SessionClose( cam_t * p_cam, int i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys;
uint8_t p_response[16]; uint8_t p_response[16];
uint8_t i_tag; uint8_t i_tag;
uint8_t i_slot = p_sys->p_sessions[i_session_id - 1].i_slot; uint8_t i_slot = p_cam->p_sessions[i_session_id - 1].i_slot;
if ( p_sys->p_sessions[i_session_id - 1].pf_close != NULL ) if ( p_cam->p_sessions[i_session_id - 1].pf_close != NULL )
p_sys->p_sessions[i_session_id - 1].pf_close( p_access, i_session_id ); p_cam->p_sessions[i_session_id - 1].pf_close( p_cam, i_session_id );
p_sys->p_sessions[i_session_id - 1].i_resource_id = 0; p_cam->p_sessions[i_session_id - 1].i_resource_id = 0;
p_response[0] = ST_CLOSE_SESSION_RESPONSE; p_response[0] = ST_CLOSE_SESSION_RESPONSE;
p_response[1] = 0x3; p_response[1] = 0x3;
...@@ -627,16 +613,16 @@ static void SessionClose( access_t * p_access, int i_session_id ) ...@@ -627,16 +613,16 @@ static void SessionClose( access_t * p_access, int i_session_id )
p_response[3] = i_session_id >> 8; p_response[3] = i_session_id >> 8;
p_response[4] = i_session_id & 0xff; p_response[4] = i_session_id & 0xff;
if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p_response, 5 ) != if ( TPDUSend( p_cam, i_slot, T_DATA_LAST, p_response, 5 ) !=
VLC_SUCCESS ) VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"SessionClose: couldn't send TPDU on slot %d", i_slot ); "SessionClose: couldn't send TPDU on slot %d", i_slot );
return; return;
} }
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS ) if ( TPDURecv( p_cam, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"SessionClose: couldn't recv TPDU on slot %d", i_slot ); "SessionClose: couldn't recv TPDU on slot %d", i_slot );
return; return;
} }
...@@ -645,10 +631,9 @@ static void SessionClose( access_t * p_access, int i_session_id ) ...@@ -645,10 +631,9 @@ static void SessionClose( access_t * p_access, int i_session_id )
/***************************************************************************** /*****************************************************************************
* SPDUHandle * SPDUHandle
*****************************************************************************/ *****************************************************************************/
static void SPDUHandle( access_t * p_access, uint8_t i_slot, static void SPDUHandle( cam_t * p_cam, uint8_t i_slot,
uint8_t *p_spdu, int i_size ) uint8_t *p_spdu, int i_size )
{ {
access_sys_t *p_sys = p_access->p_sys;
int i_session_id; int i_session_id;
switch ( p_spdu[0] ) switch ( p_spdu[0] )
...@@ -657,27 +642,27 @@ static void SPDUHandle( access_t * p_access, uint8_t i_slot, ...@@ -657,27 +642,27 @@ static void SPDUHandle( access_t * p_access, uint8_t i_slot,
if ( i_size <= 4 ) if ( i_size <= 4 )
return; return;
i_session_id = ((int)p_spdu[2] << 8) | p_spdu[3]; i_session_id = ((int)p_spdu[2] << 8) | p_spdu[3];
p_sys->p_sessions[i_session_id - 1].pf_handle( p_access, i_session_id, p_cam->p_sessions[i_session_id - 1].pf_handle( p_cam, i_session_id,
p_spdu + 4, i_size - 4 ); p_spdu + 4, i_size - 4 );
break; break;
case ST_OPEN_SESSION_REQUEST: case ST_OPEN_SESSION_REQUEST:
if ( i_size != 6 || p_spdu[1] != 0x4 ) if ( i_size != 6 || p_spdu[1] != 0x4 )
return; return;
SessionOpen( p_access, i_slot, p_spdu, i_size ); SessionOpen( p_cam, i_slot, p_spdu, i_size );
break; break;
case ST_CREATE_SESSION_RESPONSE: case ST_CREATE_SESSION_RESPONSE:
if ( i_size != 9 || p_spdu[1] != 0x7 ) if ( i_size != 9 || p_spdu[1] != 0x7 )
return; return;
SessionCreateResponse( p_access, i_slot, p_spdu, i_size ); SessionCreateResponse( p_cam, i_slot, p_spdu, i_size );
break; break;
case ST_CLOSE_SESSION_REQUEST: case ST_CLOSE_SESSION_REQUEST:
if ( i_size != 4 || p_spdu[1] != 0x2 ) if ( i_size != 4 || p_spdu[1] != 0x2 )
return; return;
i_session_id = ((int)p_spdu[2] << 8) | p_spdu[3]; i_session_id = ((int)p_spdu[2] << 8) | p_spdu[3];
SessionClose( p_access, i_session_id ); SessionClose( p_cam, i_session_id );
break; break;
case ST_CLOSE_SESSION_RESPONSE: case ST_CLOSE_SESSION_RESPONSE:
...@@ -686,20 +671,21 @@ static void SPDUHandle( access_t * p_access, uint8_t i_slot, ...@@ -686,20 +671,21 @@ static void SPDUHandle( access_t * p_access, uint8_t i_slot,
i_session_id = ((int)p_spdu[3] << 8) | p_spdu[4]; i_session_id = ((int)p_spdu[3] << 8) | p_spdu[4];
if ( p_spdu[2] ) if ( p_spdu[2] )
{ {
msg_Err( p_access, "closing a session which is not allocated (%d)", msg_Err( p_cam->obj,
"closing a session which is not allocated (%d)",
i_session_id ); i_session_id );
} }
else else
{ {
if ( p_sys->p_sessions[i_session_id - 1].pf_close != NULL ) if ( p_cam->p_sessions[i_session_id - 1].pf_close != NULL )
p_sys->p_sessions[i_session_id - 1].pf_close( p_access, p_cam->p_sessions[i_session_id - 1].pf_close( p_cam,
i_session_id ); i_session_id );
p_sys->p_sessions[i_session_id - 1].i_resource_id = 0; p_cam->p_sessions[i_session_id - 1].i_resource_id = 0;
} }
break; break;
default: default:
msg_Err( p_access, "unexpected tag in SPDUHandle (%x)", p_spdu[0] ); msg_Err( p_cam->obj, "unexpected tag in SPDUHandle (%x)", p_spdu[0] );
break; break;
} }
} }
...@@ -785,10 +771,9 @@ static uint8_t *APDUGetLength( uint8_t *p_apdu, int *pi_size ) ...@@ -785,10 +771,9 @@ static uint8_t *APDUGetLength( uint8_t *p_apdu, int *pi_size )
/***************************************************************************** /*****************************************************************************
* APDUSend * APDUSend
*****************************************************************************/ *****************************************************************************/
static int APDUSend( access_t * p_access, int i_session_id, int i_tag, static int APDUSend( cam_t * p_cam, int i_session_id, int i_tag,
uint8_t *p_data, int i_size ) uint8_t *p_data, int i_size )
{ {
access_sys_t *p_sys = p_access->p_sys;
uint8_t *p_apdu = xmalloc( i_size + 12 ); uint8_t *p_apdu = xmalloc( i_size + 12 );
uint8_t *p = p_apdu; uint8_t *p = p_apdu;
ca_msg_t ca_msg; ca_msg_t ca_msg;
...@@ -800,15 +785,15 @@ static int APDUSend( access_t * p_access, int i_session_id, int i_tag, ...@@ -800,15 +785,15 @@ static int APDUSend( access_t * p_access, int i_session_id, int i_tag,
p = SetLength( p, i_size ); p = SetLength( p, i_size );
if ( i_size ) if ( i_size )
memcpy( p, p_data, i_size ); memcpy( p, p_data, i_size );
if ( p_sys->i_ca_type == CA_CI_LINK ) if ( p_cam->i_ca_type == CA_CI_LINK )
{ {
i_ret = SPDUSend( p_access, i_session_id, p_apdu, i_size + p - p_apdu ); i_ret = SPDUSend( p_cam, i_session_id, p_apdu, i_size + p - p_apdu );
} }
else else
{ {
if ( i_size + p - p_apdu > 256 ) if ( i_size + p - p_apdu > 256 )
{ {
msg_Err( p_access, "CAM: apdu overflow" ); msg_Err( p_cam->obj, "CAM: apdu overflow" );
i_ret = VLC_EGENERIC; i_ret = VLC_EGENERIC;
} }
else else
...@@ -816,10 +801,10 @@ static int APDUSend( access_t * p_access, int i_session_id, int i_tag, ...@@ -816,10 +801,10 @@ static int APDUSend( access_t * p_access, int i_session_id, int i_tag,
ca_msg.length = i_size + p - p_apdu; ca_msg.length = i_size + p - p_apdu;
if ( i_size == 0 ) ca_msg.length=3; if ( i_size == 0 ) ca_msg.length=3;
memcpy( ca_msg.msg, p_apdu, i_size + p - p_apdu ); memcpy( ca_msg.msg, p_apdu, i_size + p - p_apdu );
i_ret = ioctl(p_sys->i_ca_handle, CA_SEND_MSG, &ca_msg ); i_ret = ioctl( p_cam->fd, CA_SEND_MSG, &ca_msg );
if ( i_ret < 0 ) if ( i_ret < 0 )
{ {
msg_Err( p_access, "Error sending to CAM: %m" ); msg_Err( p_cam->obj, "Error sending to CAM: %m" );
i_ret = VLC_EGENERIC; i_ret = VLC_EGENERIC;
} }
} }
...@@ -835,7 +820,7 @@ static int APDUSend( access_t * p_access, int i_session_id, int i_tag, ...@@ -835,7 +820,7 @@ static int APDUSend( access_t * p_access, int i_session_id, int i_tag,
/***************************************************************************** /*****************************************************************************
* ResourceManagerHandle * ResourceManagerHandle
*****************************************************************************/ *****************************************************************************/
static void ResourceManagerHandle( access_t * p_access, int i_session_id, static void ResourceManagerHandle( cam_t * p_cam, int i_session_id,
uint8_t *p_apdu, int i_size ) uint8_t *p_apdu, int i_size )
{ {
int i_tag = APDUGetTag( p_apdu, i_size ); int i_tag = APDUGetTag( p_apdu, i_size );
...@@ -850,16 +835,16 @@ static void ResourceManagerHandle( access_t * p_access, int i_session_id, ...@@ -850,16 +835,16 @@ static void ResourceManagerHandle( access_t * p_access, int i_session_id,
htonl(RI_DATE_TIME), htonl(RI_DATE_TIME),
htonl(RI_MMI) htonl(RI_MMI)
}; };
APDUSend( p_access, i_session_id, AOT_PROFILE, (uint8_t*)resources, APDUSend( p_cam, i_session_id, AOT_PROFILE, (uint8_t*)resources,
sizeof(resources) ); sizeof(resources) );
break; break;
} }
case AOT_PROFILE: case AOT_PROFILE:
APDUSend( p_access, i_session_id, AOT_PROFILE_CHANGE, NULL, 0 ); APDUSend( p_cam, i_session_id, AOT_PROFILE_CHANGE, NULL, 0 );
break; break;
default: default:
msg_Err( p_access, "unexpected tag in ResourceManagerHandle (0x%x)", msg_Err( p_cam->obj, "unexpected tag in ResourceManagerHandle (0x%x)",
i_tag ); i_tag );
} }
} }
...@@ -867,15 +852,12 @@ static void ResourceManagerHandle( access_t * p_access, int i_session_id, ...@@ -867,15 +852,12 @@ static void ResourceManagerHandle( access_t * p_access, int i_session_id,
/***************************************************************************** /*****************************************************************************
* ResourceManagerOpen * ResourceManagerOpen
*****************************************************************************/ *****************************************************************************/
static void ResourceManagerOpen( access_t * p_access, int i_session_id ) static void ResourceManagerOpen( cam_t * p_cam, unsigned i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_cam->obj, "opening ResourceManager session (%u)",
i_session_id );
msg_Dbg( p_access, "opening ResourceManager session (%d)", i_session_id ); p_cam->p_sessions[i_session_id - 1].pf_handle = ResourceManagerHandle;
APDUSend( p_cam, i_session_id, AOT_PROFILE_ENQ, NULL, 0 );
p_sys->p_sessions[i_session_id - 1].pf_handle = ResourceManagerHandle;
APDUSend( p_access, i_session_id, AOT_PROFILE_ENQ, NULL, 0 );
} }
/* /*
...@@ -885,21 +867,19 @@ static void ResourceManagerOpen( access_t * p_access, int i_session_id ) ...@@ -885,21 +867,19 @@ static void ResourceManagerOpen( access_t * p_access, int i_session_id )
/***************************************************************************** /*****************************************************************************
* ApplicationInformationEnterMenu * ApplicationInformationEnterMenu
*****************************************************************************/ *****************************************************************************/
static void ApplicationInformationEnterMenu( access_t * p_access, static void ApplicationInformationEnterMenu( cam_t * p_cam, int i_session_id )
int i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys; int i_slot = p_cam->p_sessions[i_session_id - 1].i_slot;
int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot;
msg_Dbg( p_access, "entering MMI menus on session %d", i_session_id ); msg_Dbg( p_cam->obj, "entering MMI menus on session %d", i_session_id );
APDUSend( p_access, i_session_id, AOT_ENTER_MENU, NULL, 0 ); APDUSend( p_cam, i_session_id, AOT_ENTER_MENU, NULL, 0 );
p_sys->pb_slot_mmi_expected[i_slot] = true; p_cam->pb_slot_mmi_expected[i_slot] = true;
} }
/***************************************************************************** /*****************************************************************************
* ApplicationInformationHandle * ApplicationInformationHandle
*****************************************************************************/ *****************************************************************************/
static void ApplicationInformationHandle( access_t * p_access, int i_session_id, static void ApplicationInformationHandle( cam_t * p_cam, int i_session_id,
uint8_t *p_apdu, int i_size ) uint8_t *p_apdu, int i_size )
{ {
VLC_UNUSED(i_session_id); VLC_UNUSED(i_session_id);
...@@ -923,12 +903,12 @@ static void ApplicationInformationHandle( access_t * p_access, int i_session_id, ...@@ -923,12 +903,12 @@ static void ApplicationInformationHandle( access_t * p_access, int i_session_id,
d += 2; d += 2;
d = GetLength( d, &l ); d = GetLength( d, &l );
d[l] = '\0'; d[l] = '\0';
msg_Info( p_access, "CAM: %s, %02X, %04X, %04X", msg_Info( p_cam->obj, "CAM: %s, %02X, %04X, %04X",
d, i_type, i_manufacturer, i_code ); d, i_type, i_manufacturer, i_code );
break; break;
} }
default: default:
msg_Err( p_access, msg_Err( p_cam->obj,
"unexpected tag in ApplicationInformationHandle (0x%x)", "unexpected tag in ApplicationInformationHandle (0x%x)",
i_tag ); i_tag );
} }
...@@ -937,15 +917,13 @@ static void ApplicationInformationHandle( access_t * p_access, int i_session_id, ...@@ -937,15 +917,13 @@ static void ApplicationInformationHandle( access_t * p_access, int i_session_id,
/***************************************************************************** /*****************************************************************************
* ApplicationInformationOpen * ApplicationInformationOpen
*****************************************************************************/ *****************************************************************************/
static void ApplicationInformationOpen( access_t * p_access, int i_session_id ) static void ApplicationInformationOpen( cam_t * p_cam, unsigned i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_cam->obj, "opening ApplicationInformation session (%u)",
i_session_id );
msg_Dbg( p_access, "opening ApplicationInformation session (%d)", i_session_id ); p_cam->p_sessions[i_session_id - 1].pf_handle =
ApplicationInformationHandle;
p_sys->p_sessions[i_session_id - 1].pf_handle = ApplicationInformationHandle; APDUSend( p_cam, i_session_id, AOT_APPLICATION_INFO_ENQ, NULL, 0 );
APDUSend( p_access, i_session_id, AOT_APPLICATION_INFO_ENQ, NULL, 0 );
} }
/* /*
...@@ -1132,13 +1110,12 @@ static uint8_t *CAPMTES( system_ids_t *p_ids, uint8_t *p_capmt, ...@@ -1132,13 +1110,12 @@ static uint8_t *CAPMTES( system_ids_t *p_ids, uint8_t *p_capmt,
return p_data; return p_data;
} }
static uint8_t *CAPMTBuild( access_t * p_access, int i_session_id, static uint8_t *CAPMTBuild( cam_t * p_cam, int i_session_id,
dvbpsi_pmt_t *p_pmt, uint8_t i_list_mgt, dvbpsi_pmt_t *p_pmt, uint8_t i_list_mgt,
uint8_t i_cmd, int *pi_capmt_size ) uint8_t i_cmd, int *pi_capmt_size )
{ {
access_sys_t *p_sys = p_access->p_sys;
system_ids_t *p_ids = system_ids_t *p_ids =
(system_ids_t *)p_sys->p_sessions[i_session_id - 1].p_sys; (system_ids_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
dvbpsi_pmt_es_t *p_es; dvbpsi_pmt_es_t *p_es;
int i_cad_size, i_cad_program_size; int i_cad_size, i_cad_program_size;
uint8_t *p_capmt; uint8_t *p_capmt;
...@@ -1152,7 +1129,7 @@ static uint8_t *CAPMTBuild( access_t * p_access, int i_session_id, ...@@ -1152,7 +1129,7 @@ static uint8_t *CAPMTBuild( access_t * p_access, int i_session_id,
if ( !i_cad_size ) if ( !i_cad_size )
{ {
msg_Warn( p_access, msg_Warn( p_cam->obj,
"no compatible scrambling system for SID %d on session %d", "no compatible scrambling system for SID %d on session %d",
p_pmt->i_program_number, i_session_id ); p_pmt->i_program_number, i_session_id );
*pi_capmt_size = 0; *pi_capmt_size = 0;
...@@ -1190,22 +1167,22 @@ static uint8_t *CAPMTBuild( access_t * p_access, int i_session_id, ...@@ -1190,22 +1167,22 @@ static uint8_t *CAPMTBuild( access_t * p_access, int i_session_id,
/***************************************************************************** /*****************************************************************************
* CAPMTFirst * CAPMTFirst
*****************************************************************************/ *****************************************************************************/
static void CAPMTFirst( access_t * p_access, int i_session_id, static void CAPMTFirst( cam_t * p_cam, int i_session_id,
dvbpsi_pmt_t *p_pmt ) dvbpsi_pmt_t *p_pmt )
{ {
uint8_t *p_capmt; uint8_t *p_capmt;
int i_capmt_size; int i_capmt_size;
msg_Dbg( p_access, "adding first CAPMT for SID %d on session %d", msg_Dbg( p_cam->obj, "adding first CAPMT for SID %d on session %d",
p_pmt->i_program_number, i_session_id ); p_pmt->i_program_number, i_session_id );
p_capmt = CAPMTBuild( p_access, i_session_id, p_pmt, p_capmt = CAPMTBuild( p_cam, i_session_id, p_pmt,
0x3 /* only */, 0x1 /* ok_descrambling */, 0x3 /* only */, 0x1 /* ok_descrambling */,
&i_capmt_size ); &i_capmt_size );
if( i_capmt_size ) if( i_capmt_size )
{ {
APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size ); APDUSend( p_cam, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );
free( p_capmt ); free( p_capmt );
} }
} }
...@@ -1213,22 +1190,22 @@ static void CAPMTFirst( access_t * p_access, int i_session_id, ...@@ -1213,22 +1190,22 @@ static void CAPMTFirst( access_t * p_access, int i_session_id,
/***************************************************************************** /*****************************************************************************
* CAPMTAdd * CAPMTAdd
*****************************************************************************/ *****************************************************************************/
static void CAPMTAdd( access_t * p_access, int i_session_id, static void CAPMTAdd( cam_t * p_cam, int i_session_id,
dvbpsi_pmt_t *p_pmt ) dvbpsi_pmt_t *p_pmt )
{ {
uint8_t *p_capmt; uint8_t *p_capmt;
int i_capmt_size; int i_capmt_size;
if( p_access->p_sys->i_selected_programs >= CAM_PROG_MAX ) if( p_cam->i_selected_programs >= CAM_PROG_MAX )
{ {
msg_Warn( p_access, "Not adding CAPMT for SID %d, too many programs", msg_Warn( p_cam->obj, "Not adding CAPMT for SID %d, too many programs",
p_pmt->i_program_number ); p_pmt->i_program_number );
return; return;
} }
p_access->p_sys->i_selected_programs++; p_cam->i_selected_programs++;
if( p_access->p_sys->i_selected_programs == 1 ) if( p_cam->i_selected_programs == 1 )
{ {
CAPMTFirst( p_access, i_session_id, p_pmt ); CAPMTFirst( p_cam, i_session_id, p_pmt );
return; return;
} }
...@@ -1236,16 +1213,16 @@ static void CAPMTAdd( access_t * p_access, int i_session_id, ...@@ -1236,16 +1213,16 @@ static void CAPMTAdd( access_t * p_access, int i_session_id,
msleep( CAPMT_WAIT * 1000 ); msleep( CAPMT_WAIT * 1000 );
#endif #endif
msg_Dbg( p_access, "adding CAPMT for SID %d on session %d", msg_Dbg( p_cam->obj, "adding CAPMT for SID %d on session %d",
p_pmt->i_program_number, i_session_id ); p_pmt->i_program_number, i_session_id );
p_capmt = CAPMTBuild( p_access, i_session_id, p_pmt, p_capmt = CAPMTBuild( p_cam, i_session_id, p_pmt,
0x4 /* add */, 0x1 /* ok_descrambling */, 0x4 /* add */, 0x1 /* ok_descrambling */,
&i_capmt_size ); &i_capmt_size );
if( i_capmt_size ) if( i_capmt_size )
{ {
APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size ); APDUSend( p_cam, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );
free( p_capmt ); free( p_capmt );
} }
} }
...@@ -1253,22 +1230,22 @@ static void CAPMTAdd( access_t * p_access, int i_session_id, ...@@ -1253,22 +1230,22 @@ static void CAPMTAdd( access_t * p_access, int i_session_id,
/***************************************************************************** /*****************************************************************************
* CAPMTUpdate * CAPMTUpdate
*****************************************************************************/ *****************************************************************************/
static void CAPMTUpdate( access_t * p_access, int i_session_id, static void CAPMTUpdate( cam_t * p_cam, int i_session_id,
dvbpsi_pmt_t *p_pmt ) dvbpsi_pmt_t *p_pmt )
{ {
uint8_t *p_capmt; uint8_t *p_capmt;
int i_capmt_size; int i_capmt_size;
msg_Dbg( p_access, "updating CAPMT for SID %d on session %d", msg_Dbg( p_cam->obj, "updating CAPMT for SID %d on session %d",
p_pmt->i_program_number, i_session_id ); p_pmt->i_program_number, i_session_id );
p_capmt = CAPMTBuild( p_access, i_session_id, p_pmt, p_capmt = CAPMTBuild( p_cam, i_session_id, p_pmt,
0x5 /* update */, 0x1 /* ok_descrambling */, 0x5 /* update */, 0x1 /* ok_descrambling */,
&i_capmt_size ); &i_capmt_size );
if( i_capmt_size ) if( i_capmt_size )
{ {
APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size ); APDUSend( p_cam, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );
free( p_capmt ); free( p_capmt );
} }
} }
...@@ -1276,23 +1253,23 @@ static void CAPMTUpdate( access_t * p_access, int i_session_id, ...@@ -1276,23 +1253,23 @@ static void CAPMTUpdate( access_t * p_access, int i_session_id,
/***************************************************************************** /*****************************************************************************
* CAPMTDelete * CAPMTDelete
*****************************************************************************/ *****************************************************************************/
static void CAPMTDelete( access_t * p_access, int i_session_id, static void CAPMTDelete( cam_t * p_cam, int i_session_id,
dvbpsi_pmt_t *p_pmt ) dvbpsi_pmt_t *p_pmt )
{ {
uint8_t *p_capmt; uint8_t *p_capmt;
int i_capmt_size; int i_capmt_size;
p_access->p_sys->i_selected_programs--; p_cam->i_selected_programs--;
msg_Dbg( p_access, "deleting CAPMT for SID %d on session %d", msg_Dbg( p_cam->obj, "deleting CAPMT for SID %d on session %d",
p_pmt->i_program_number, i_session_id ); p_pmt->i_program_number, i_session_id );
p_capmt = CAPMTBuild( p_access, i_session_id, p_pmt, p_capmt = CAPMTBuild( p_cam, i_session_id, p_pmt,
0x5 /* update */, 0x4 /* not selected */, 0x5 /* update */, 0x4 /* not selected */,
&i_capmt_size ); &i_capmt_size );
if( i_capmt_size ) if( i_capmt_size )
{ {
APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size ); APDUSend( p_cam, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );
free( p_capmt ); free( p_capmt );
} }
} }
...@@ -1300,12 +1277,11 @@ static void CAPMTDelete( access_t * p_access, int i_session_id, ...@@ -1300,12 +1277,11 @@ static void CAPMTDelete( access_t * p_access, int i_session_id,
/***************************************************************************** /*****************************************************************************
* ConditionalAccessHandle * ConditionalAccessHandle
*****************************************************************************/ *****************************************************************************/
static void ConditionalAccessHandle( access_t * p_access, int i_session_id, static void ConditionalAccessHandle( cam_t * p_cam, int i_session_id,
uint8_t *p_apdu, int i_size ) uint8_t *p_apdu, int i_size )
{ {
access_sys_t *p_sys = p_access->p_sys;
system_ids_t *p_ids = system_ids_t *p_ids =
(system_ids_t *)p_sys->p_sessions[i_session_id - 1].p_sys; (system_ids_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
int i_tag = APDUGetTag( p_apdu, i_size ); int i_tag = APDUGetTag( p_apdu, i_size );
switch ( i_tag ) switch ( i_tag )
...@@ -1315,29 +1291,29 @@ static void ConditionalAccessHandle( access_t * p_access, int i_session_id, ...@@ -1315,29 +1291,29 @@ static void ConditionalAccessHandle( access_t * p_access, int i_session_id,
int i; int i;
int l = 0; int l = 0;
uint8_t *d = APDUGetLength( p_apdu, &l ); uint8_t *d = APDUGetLength( p_apdu, &l );
msg_Dbg( p_access, "CA system IDs supported by the application :" ); msg_Dbg( p_cam->obj, "CA system IDs supported by the application :" );
for ( i = 0; i < l / 2; i++ ) for ( i = 0; i < l / 2; i++ )
{ {
p_ids->pi_system_ids[i] = ((uint16_t)d[0] << 8) | d[1]; p_ids->pi_system_ids[i] = ((uint16_t)d[0] << 8) | d[1];
d += 2; d += 2;
msg_Dbg( p_access, "- 0x%x", p_ids->pi_system_ids[i] ); msg_Dbg( p_cam->obj, "- 0x%x", p_ids->pi_system_ids[i] );
} }
p_ids->pi_system_ids[i] = 0; p_ids->pi_system_ids[i] = 0;
for ( i = 0; i < MAX_PROGRAMS; i++ ) for ( i = 0; i < MAX_PROGRAMS; i++ )
{ {
if ( p_sys->pp_selected_programs[i] != NULL ) if ( p_cam->pp_selected_programs[i] != NULL )
{ {
CAPMTAdd( p_access, i_session_id, CAPMTAdd( p_cam, i_session_id,
p_sys->pp_selected_programs[i] ); p_cam->pp_selected_programs[i] );
} }
} }
break; break;
} }
default: default:
msg_Err( p_access, msg_Err( p_cam->obj,
"unexpected tag in ConditionalAccessHandle (0x%x)", "unexpected tag in ConditionalAccessHandle (0x%x)",
i_tag ); i_tag );
} }
...@@ -1346,29 +1322,25 @@ static void ConditionalAccessHandle( access_t * p_access, int i_session_id, ...@@ -1346,29 +1322,25 @@ static void ConditionalAccessHandle( access_t * p_access, int i_session_id,
/***************************************************************************** /*****************************************************************************
* ConditionalAccessClose * ConditionalAccessClose
*****************************************************************************/ *****************************************************************************/
static void ConditionalAccessClose( access_t * p_access, int i_session_id ) static void ConditionalAccessClose( cam_t * p_cam, int i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_cam->obj, "closing ConditionalAccess session (%d)",
i_session_id );
msg_Dbg( p_access, "closing ConditionalAccess session (%d)", i_session_id ); free( p_cam->p_sessions[i_session_id - 1].p_sys );
free( p_sys->p_sessions[i_session_id - 1].p_sys );
} }
/***************************************************************************** /*****************************************************************************
* ConditionalAccessOpen * ConditionalAccessOpen
*****************************************************************************/ *****************************************************************************/
static void ConditionalAccessOpen( access_t * p_access, int i_session_id ) static void ConditionalAccessOpen( cam_t * p_cam, unsigned i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_cam->obj, "opening ConditionalAccess session (%u)",
i_session_id );
msg_Dbg( p_access, "opening ConditionalAccess session (%d)", i_session_id ); p_cam->p_sessions[i_session_id - 1].pf_handle = ConditionalAccessHandle;
p_cam->p_sessions[i_session_id - 1].pf_close = ConditionalAccessClose;
p_sys->p_sessions[i_session_id - 1].pf_handle = ConditionalAccessHandle; p_cam->p_sessions[i_session_id - 1].p_sys = calloc( 1, sizeof(system_ids_t) );
p_sys->p_sessions[i_session_id - 1].pf_close = ConditionalAccessClose;
p_sys->p_sessions[i_session_id - 1].p_sys = calloc( 1, sizeof(system_ids_t) );
APDUSend( p_access, i_session_id, AOT_CA_INFO_ENQ, NULL, 0 ); APDUSend( p_cam, i_session_id, AOT_CA_INFO_ENQ, NULL, 0 );
} }
/* /*
...@@ -1384,11 +1356,10 @@ typedef struct ...@@ -1384,11 +1356,10 @@ typedef struct
/***************************************************************************** /*****************************************************************************
* DateTimeSend * DateTimeSend
*****************************************************************************/ *****************************************************************************/
static void DateTimeSend( access_t * p_access, int i_session_id ) static void DateTimeSend( cam_t * p_cam, int i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys;
date_time_t *p_date = date_time_t *p_date =
(date_time_t *)p_sys->p_sessions[i_session_id - 1].p_sys; (date_time_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
time_t t = time(NULL); time_t t = time(NULL);
struct tm tm_gmt; struct tm tm_gmt;
...@@ -1412,7 +1383,7 @@ static void DateTimeSend( access_t * p_access, int i_session_id ) ...@@ -1412,7 +1383,7 @@ static void DateTimeSend( access_t * p_access, int i_session_id )
p_response[4] = DEC2BCD(tm_gmt.tm_sec); p_response[4] = DEC2BCD(tm_gmt.tm_sec);
SetWBE( &p_response[5], tm_loc.tm_gmtoff / 60 ); SetWBE( &p_response[5], tm_loc.tm_gmtoff / 60 );
APDUSend( p_access, i_session_id, AOT_DATE_TIME, p_response, 7 ); APDUSend( p_cam, i_session_id, AOT_DATE_TIME, p_response, 7 );
p_date->i_last = mdate(); p_date->i_last = mdate();
} }
...@@ -1421,12 +1392,11 @@ static void DateTimeSend( access_t * p_access, int i_session_id ) ...@@ -1421,12 +1392,11 @@ static void DateTimeSend( access_t * p_access, int i_session_id )
/***************************************************************************** /*****************************************************************************
* DateTimeHandle * DateTimeHandle
*****************************************************************************/ *****************************************************************************/
static void DateTimeHandle( access_t * p_access, int i_session_id, static void DateTimeHandle( cam_t *p_cam, int i_session_id,
uint8_t *p_apdu, int i_size ) uint8_t *p_apdu, int i_size )
{ {
access_sys_t *p_sys = p_access->p_sys;
date_time_t *p_date = date_time_t *p_date =
(date_time_t *)p_sys->p_sessions[i_session_id - 1].p_sys; (date_time_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
int i_tag = APDUGetTag( p_apdu, i_size ); int i_tag = APDUGetTag( p_apdu, i_size );
...@@ -1440,63 +1410,59 @@ static void DateTimeHandle( access_t * p_access, int i_session_id, ...@@ -1440,63 +1410,59 @@ static void DateTimeHandle( access_t * p_access, int i_session_id,
if ( l > 0 ) if ( l > 0 )
{ {
p_date->i_interval = *d; p_date->i_interval = *d;
msg_Dbg( p_access, "DateTimeHandle : interval set to %d", msg_Dbg( p_cam->obj, "DateTimeHandle : interval set to %d",
p_date->i_interval ); p_date->i_interval );
} }
else else
p_date->i_interval = 0; p_date->i_interval = 0;
DateTimeSend( p_access, i_session_id ); DateTimeSend( p_cam, i_session_id );
break; break;
} }
default: default:
msg_Err( p_access, "unexpected tag in DateTimeHandle (0x%x)", i_tag ); msg_Err( p_cam->obj, "unexpected tag in DateTimeHandle (0x%x)",
i_tag );
} }
} }
/***************************************************************************** /*****************************************************************************
* DateTimeManage * DateTimeManage
*****************************************************************************/ *****************************************************************************/
static void DateTimeManage( access_t * p_access, int i_session_id ) static void DateTimeManage( cam_t * p_cam, int i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys;
date_time_t *p_date = date_time_t *p_date =
(date_time_t *)p_sys->p_sessions[i_session_id - 1].p_sys; (date_time_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
if ( p_date->i_interval if ( p_date->i_interval
&& mdate() > p_date->i_last + (mtime_t)p_date->i_interval * 1000000 ) && mdate() > p_date->i_last + (mtime_t)p_date->i_interval * 1000000 )
{ {
DateTimeSend( p_access, i_session_id ); DateTimeSend( p_cam, i_session_id );
} }
} }
/***************************************************************************** /*****************************************************************************
* DateTimeClose * DateTimeClose
*****************************************************************************/ *****************************************************************************/
static void DateTimeClose( access_t * p_access, int i_session_id ) static void DateTimeClose( cam_t * p_cam, int i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_cam->obj, "closing DateTime session (%d)", i_session_id );
msg_Dbg( p_access, "closing DateTime session (%d)", i_session_id );
free( p_sys->p_sessions[i_session_id - 1].p_sys ); free( p_cam->p_sessions[i_session_id - 1].p_sys );
} }
/***************************************************************************** /*****************************************************************************
* DateTimeOpen * DateTimeOpen
*****************************************************************************/ *****************************************************************************/
static void DateTimeOpen( access_t * p_access, int i_session_id ) static void DateTimeOpen( cam_t * p_cam, unsigned i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_cam->obj, "opening DateTime session (%u)", i_session_id );
msg_Dbg( p_access, "opening DateTime session (%d)", i_session_id );
p_sys->p_sessions[i_session_id - 1].pf_handle = DateTimeHandle; p_cam->p_sessions[i_session_id - 1].pf_handle = DateTimeHandle;
p_sys->p_sessions[i_session_id - 1].pf_manage = DateTimeManage; p_cam->p_sessions[i_session_id - 1].pf_manage = DateTimeManage;
p_sys->p_sessions[i_session_id - 1].pf_close = DateTimeClose; p_cam->p_sessions[i_session_id - 1].pf_close = DateTimeClose;
p_sys->p_sessions[i_session_id - 1].p_sys = calloc( 1, sizeof(date_time_t) ); p_cam->p_sessions[i_session_id - 1].p_sys = calloc( 1, sizeof(date_time_t) );
DateTimeSend( p_access, i_session_id ); DateTimeSend( p_cam, i_session_id );
} }
/* /*
...@@ -1545,11 +1511,10 @@ typedef struct ...@@ -1545,11 +1511,10 @@ typedef struct
/***************************************************************************** /*****************************************************************************
* MMISendObject * MMISendObject
*****************************************************************************/ *****************************************************************************/
static void MMISendObject( access_t *p_access, int i_session_id, static void MMISendObject( cam_t *p_cam, int i_session_id,
en50221_mmi_object_t *p_object ) en50221_mmi_object_t *p_object )
{ {
access_sys_t *p_sys = p_access->p_sys; int i_slot = p_cam->p_sessions[i_session_id - 1].i_slot;
int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot;
uint8_t *p_data; uint8_t *p_data;
int i_size, i_tag; int i_size, i_tag;
...@@ -1571,48 +1536,47 @@ static void MMISendObject( access_t *p_access, int i_session_id, ...@@ -1571,48 +1536,47 @@ static void MMISendObject( access_t *p_access, int i_session_id,
break; break;
default: default:
msg_Err( p_access, "unknown MMI object %d", p_object->i_object_type ); msg_Err( p_cam->obj, "unknown MMI object %d", p_object->i_object_type );
return; return;
} }
APDUSend( p_access, i_session_id, i_tag, p_data, i_size ); APDUSend( p_cam, i_session_id, i_tag, p_data, i_size );
free( p_data ); free( p_data );
p_sys->pb_slot_mmi_expected[i_slot] = true; p_cam->pb_slot_mmi_expected[i_slot] = true;
} }
/***************************************************************************** /*****************************************************************************
* MMISendClose * MMISendClose
*****************************************************************************/ *****************************************************************************/
static void MMISendClose( access_t *p_access, int i_session_id ) static void MMISendClose( cam_t *p_cam, int i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys; int i_slot = p_cam->p_sessions[i_session_id - 1].i_slot;
int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot;
APDUSend( p_access, i_session_id, AOT_CLOSE_MMI, NULL, 0 ); APDUSend( p_cam, i_session_id, AOT_CLOSE_MMI, NULL, 0 );
p_sys->pb_slot_mmi_expected[i_slot] = true; p_cam->pb_slot_mmi_expected[i_slot] = true;
} }
/***************************************************************************** /*****************************************************************************
* MMIDisplayReply * MMIDisplayReply
*****************************************************************************/ *****************************************************************************/
static void MMIDisplayReply( access_t *p_access, int i_session_id ) static void MMIDisplayReply( cam_t *p_cam, int i_session_id )
{ {
uint8_t p_response[2]; uint8_t p_response[2];
p_response[0] = DRI_MMI_MODE_ACK; p_response[0] = DRI_MMI_MODE_ACK;
p_response[1] = MM_HIGH_LEVEL; p_response[1] = MM_HIGH_LEVEL;
APDUSend( p_access, i_session_id, AOT_DISPLAY_REPLY, p_response, 2 ); APDUSend( p_cam, i_session_id, AOT_DISPLAY_REPLY, p_response, 2 );
msg_Dbg( p_access, "sending DisplayReply on session (%d)", i_session_id ); msg_Dbg( p_cam->obj, "sending DisplayReply on session (%d)", i_session_id );
} }
/***************************************************************************** /*****************************************************************************
* MMIGetText * MMIGetText
*****************************************************************************/ *****************************************************************************/
static char *MMIGetText( access_t *p_access, uint8_t **pp_apdu, int *pi_size ) static char *MMIGetText( cam_t *p_cam, uint8_t **pp_apdu, int *pi_size )
{ {
int i_tag = APDUGetTag( *pp_apdu, *pi_size ); int i_tag = APDUGetTag( *pp_apdu, *pi_size );
int l; int l;
...@@ -1620,7 +1584,7 @@ static char *MMIGetText( access_t *p_access, uint8_t **pp_apdu, int *pi_size ) ...@@ -1620,7 +1584,7 @@ static char *MMIGetText( access_t *p_access, uint8_t **pp_apdu, int *pi_size )
if ( i_tag != AOT_TEXT_LAST ) if ( i_tag != AOT_TEXT_LAST )
{ {
msg_Err( p_access, "unexpected text tag: %06x", i_tag ); msg_Err( p_cam->obj, "unexpected text tag: %06x", i_tag );
*pi_size = 0; *pi_size = 0;
return strdup( "" ); return strdup( "" );
} }
...@@ -1636,14 +1600,13 @@ static char *MMIGetText( access_t *p_access, uint8_t **pp_apdu, int *pi_size ) ...@@ -1636,14 +1600,13 @@ static char *MMIGetText( access_t *p_access, uint8_t **pp_apdu, int *pi_size )
/***************************************************************************** /*****************************************************************************
* MMIHandleEnq * MMIHandleEnq
*****************************************************************************/ *****************************************************************************/
static void MMIHandleEnq( access_t *p_access, int i_session_id, static void MMIHandleEnq( cam_t *p_cam, int i_session_id,
uint8_t *p_apdu, int i_size ) uint8_t *p_apdu, int i_size )
{ {
VLC_UNUSED( i_size ); VLC_UNUSED( i_size );
access_sys_t *p_sys = p_access->p_sys; mmi_t *p_mmi = (mmi_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
mmi_t *p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys; int i_slot = p_cam->p_sessions[i_session_id - 1].i_slot;
int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot;
int l; int l;
uint8_t *d = APDUGetLength( p_apdu, &l ); uint8_t *d = APDUGetLength( p_apdu, &l );
...@@ -1656,22 +1619,22 @@ static void MMIHandleEnq( access_t *p_access, int i_session_id, ...@@ -1656,22 +1619,22 @@ static void MMIHandleEnq( access_t *p_access, int i_session_id,
strncpy( p_mmi->last_object.u.enq.psz_text, (char *)d, l ); strncpy( p_mmi->last_object.u.enq.psz_text, (char *)d, l );
p_mmi->last_object.u.enq.psz_text[l] = '\0'; p_mmi->last_object.u.enq.psz_text[l] = '\0';
msg_Dbg( p_access, "MMI enq: %s%s", p_mmi->last_object.u.enq.psz_text, msg_Dbg( p_cam->obj, "MMI enq: %s%s", p_mmi->last_object.u.enq.psz_text,
p_mmi->last_object.u.enq.b_blind == true ? " (blind)" : "" ); p_mmi->last_object.u.enq.b_blind == true ? " (blind)" : "" );
p_sys->pb_slot_mmi_expected[i_slot] = false; p_cam->pb_slot_mmi_expected[i_slot] = false;
p_sys->pb_slot_mmi_undisplayed[i_slot] = true; p_cam->pb_slot_mmi_undisplayed[i_slot] = true;
} }
/***************************************************************************** /*****************************************************************************
* MMIHandleMenu * MMIHandleMenu
*****************************************************************************/ *****************************************************************************/
static void MMIHandleMenu( access_t *p_access, int i_session_id, int i_tag, static void MMIHandleMenu( cam_t *p_cam, int i_session_id, int i_tag,
uint8_t *p_apdu, int i_size ) uint8_t *p_apdu, int i_size )
{ {
VLC_UNUSED(i_size); VLC_UNUSED(i_size);
access_sys_t *p_sys = p_access->p_sys;
mmi_t *p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys; mmi_t *p_mmi = (mmi_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot; int i_slot = p_cam->p_sessions[i_session_id - 1].i_slot;
int l; int l;
uint8_t *d = APDUGetLength( p_apdu, &l ); uint8_t *d = APDUGetLength( p_apdu, &l );
...@@ -1689,8 +1652,8 @@ static void MMIHandleMenu( access_t *p_access, int i_session_id, int i_tag, ...@@ -1689,8 +1652,8 @@ static void MMIHandleMenu( access_t *p_access, int i_session_id, int i_tag,
if ( l > 0 ) \ if ( l > 0 ) \
{ \ { \
p_mmi->last_object.u.menu.psz_##x \ p_mmi->last_object.u.menu.psz_##x \
= MMIGetText( p_access, &d, &l ); \ = MMIGetText( p_cam, &d, &l ); \
msg_Dbg( p_access, "MMI " STRINGIFY( x ) ": %s", \ msg_Dbg( p_cam->obj, "MMI " STRINGIFY( x ) ": %s", \
p_mmi->last_object.u.menu.psz_##x ); \ p_mmi->last_object.u.menu.psz_##x ); \
} }
...@@ -1701,21 +1664,21 @@ static void MMIHandleMenu( access_t *p_access, int i_session_id, int i_tag, ...@@ -1701,21 +1664,21 @@ static void MMIHandleMenu( access_t *p_access, int i_session_id, int i_tag,
while ( l > 0 ) while ( l > 0 )
{ {
char *psz_text = MMIGetText( p_access, &d, &l ); char *psz_text = MMIGetText( p_cam, &d, &l );
TAB_APPEND( p_mmi->last_object.u.menu.i_choices, TAB_APPEND( p_mmi->last_object.u.menu.i_choices,
p_mmi->last_object.u.menu.ppsz_choices, p_mmi->last_object.u.menu.ppsz_choices,
psz_text ); psz_text );
msg_Dbg( p_access, "MMI choice: %s", psz_text ); msg_Dbg( p_cam->obj, "MMI choice: %s", psz_text );
} }
} }
p_sys->pb_slot_mmi_expected[i_slot] = false; p_cam->pb_slot_mmi_expected[i_slot] = false;
p_sys->pb_slot_mmi_undisplayed[i_slot] = true; p_cam->pb_slot_mmi_undisplayed[i_slot] = true;
} }
/***************************************************************************** /*****************************************************************************
* MMIHandle * MMIHandle
*****************************************************************************/ *****************************************************************************/
static void MMIHandle( access_t *p_access, int i_session_id, static void MMIHandle( cam_t *p_cam, int i_session_id,
uint8_t *p_apdu, int i_size ) uint8_t *p_apdu, int i_size )
{ {
int i_tag = APDUGetTag( p_apdu, i_size ); int i_tag = APDUGetTag( p_apdu, i_size );
...@@ -1733,13 +1696,13 @@ static void MMIHandle( access_t *p_access, int i_session_id, ...@@ -1733,13 +1696,13 @@ static void MMIHandle( access_t *p_access, int i_session_id,
{ {
case DCC_SET_MMI_MODE: case DCC_SET_MMI_MODE:
if ( l == 2 && d[1] == MM_HIGH_LEVEL ) if ( l == 2 && d[1] == MM_HIGH_LEVEL )
MMIDisplayReply( p_access, i_session_id ); MMIDisplayReply( p_cam, i_session_id );
else else
msg_Err( p_access, "unsupported MMI mode %02x", d[1] ); msg_Err( p_cam->obj, "unsupported MMI mode %02x", d[1] );
break; break;
default: default:
msg_Err( p_access, "unsupported display control command %02x", msg_Err( p_cam->obj, "unsupported display control command %02x",
*d ); *d );
break; break;
} }
...@@ -1748,54 +1711,52 @@ static void MMIHandle( access_t *p_access, int i_session_id, ...@@ -1748,54 +1711,52 @@ static void MMIHandle( access_t *p_access, int i_session_id,
} }
case AOT_ENQ: case AOT_ENQ:
MMIHandleEnq( p_access, i_session_id, p_apdu, i_size ); MMIHandleEnq( p_cam, i_session_id, p_apdu, i_size );
break; break;
case AOT_LIST_LAST: case AOT_LIST_LAST:
case AOT_MENU_LAST: case AOT_MENU_LAST:
MMIHandleMenu( p_access, i_session_id, i_tag, p_apdu, i_size ); MMIHandleMenu( p_cam, i_session_id, i_tag, p_apdu, i_size );
break; break;
case AOT_CLOSE_MMI: case AOT_CLOSE_MMI:
SessionSendClose( p_access, i_session_id ); SessionSendClose( p_cam, i_session_id );
break; break;
default: default:
msg_Err( p_access, "unexpected tag in MMIHandle (0x%x)", i_tag ); msg_Err( p_cam->obj, "unexpected tag in MMIHandle (0x%x)", i_tag );
} }
} }
/***************************************************************************** /*****************************************************************************
* MMIClose * MMIClose
*****************************************************************************/ *****************************************************************************/
static void MMIClose( access_t *p_access, int i_session_id ) static void MMIClose( cam_t *p_cam, int i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys; int i_slot = p_cam->p_sessions[i_session_id - 1].i_slot;
int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot; mmi_t *p_mmi = (mmi_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
mmi_t *p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys;
en50221_MMIFree( &p_mmi->last_object ); en50221_MMIFree( &p_mmi->last_object );
free( p_sys->p_sessions[i_session_id - 1].p_sys ); free( p_cam->p_sessions[i_session_id - 1].p_sys );
msg_Dbg( p_access, "closing MMI session (%d)", i_session_id ); msg_Dbg( p_cam->obj, "closing MMI session (%d)", i_session_id );
p_sys->pb_slot_mmi_expected[i_slot] = false; p_cam->pb_slot_mmi_expected[i_slot] = false;
p_sys->pb_slot_mmi_undisplayed[i_slot] = true; p_cam->pb_slot_mmi_undisplayed[i_slot] = true;
} }
/***************************************************************************** /*****************************************************************************
* MMIOpen * MMIOpen
*****************************************************************************/ *****************************************************************************/
static void MMIOpen( access_t *p_access, int i_session_id ) static void MMIOpen( cam_t *p_cam, unsigned i_session_id )
{ {
access_sys_t *p_sys = p_access->p_sys;
mmi_t *p_mmi; mmi_t *p_mmi;
msg_Dbg( p_access, "opening MMI session (%d)", i_session_id ); msg_Dbg( p_cam->obj, "opening MMI session (%u)", i_session_id );
p_sys->p_sessions[i_session_id - 1].pf_handle = MMIHandle; p_cam->p_sessions[i_session_id - 1].pf_handle = MMIHandle;
p_sys->p_sessions[i_session_id - 1].pf_close = MMIClose; p_cam->p_sessions[i_session_id - 1].pf_close = MMIClose;
p_sys->p_sessions[i_session_id - 1].p_sys = xmalloc(sizeof(mmi_t)); p_cam->p_sessions[i_session_id - 1].p_sys = xmalloc(sizeof(mmi_t));
p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys; p_mmi = (mmi_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
p_mmi->last_object.i_object_type = EN50221_MMI_NONE; p_mmi->last_object.i_object_type = EN50221_MMI_NONE;
} }
...@@ -1809,43 +1770,39 @@ static void MMIOpen( access_t *p_access, int i_session_id ) ...@@ -1809,43 +1770,39 @@ static void MMIOpen( access_t *p_access, int i_session_id )
*****************************************************************************/ *****************************************************************************/
#define MAX_TC_RETRIES 20 #define MAX_TC_RETRIES 20
static int InitSlot( access_t * p_access, int i_slot ) static int InitSlot( cam_t * p_cam, int i_slot )
{ {
access_sys_t *p_sys = p_access->p_sys; if ( TPDUSend( p_cam, i_slot, T_CREATE_TC, NULL, 0 ) != VLC_SUCCESS )
int i;
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_cam->obj, "en50221_Init: couldn't send TPDU on slot %d",
i_slot ); i_slot );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* This is out of the spec */ /* This is out of the spec */
for ( i = 0; i < MAX_TC_RETRIES; i++ ) for ( int i = 0; i < MAX_TC_RETRIES; i++ )
{ {
uint8_t i_tag; uint8_t i_tag;
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) == VLC_SUCCESS if ( TPDURecv( p_cam, i_slot, &i_tag, NULL, NULL ) == VLC_SUCCESS
&& i_tag == T_CTC_REPLY ) && i_tag == T_CTC_REPLY )
{ {
p_sys->pb_active_slot[i_slot] = true; p_cam->pb_active_slot[i_slot] = true;
break; break;
} }
if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 ) if ( TPDUSend( p_cam, i_slot, T_CREATE_TC, NULL, 0 )
!= VLC_SUCCESS ) != VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"en50221_Init: couldn't send TPDU on slot %d", "en50221_Init: couldn't send TPDU on slot %d",
i_slot ); i_slot );
continue; continue;
} }
} }
if ( p_sys->pb_active_slot[i_slot] ) if ( p_cam->pb_active_slot[i_slot] )
{ {
p_sys->i_ca_timeout = 100000; p_cam->i_timeout = CLOCK_FREQ / 10;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -1860,25 +1817,22 @@ static int InitSlot( access_t * p_access, int i_slot ) ...@@ -1860,25 +1817,22 @@ static int InitSlot( access_t * p_access, int i_slot )
/***************************************************************************** /*****************************************************************************
* en50221_Init : Initialize the CAM for en50221 * en50221_Init : Initialize the CAM for en50221
*****************************************************************************/ *****************************************************************************/
int en50221_Init( access_t * p_access ) int en50221_Init( cam_t * p_cam )
{ {
access_sys_t *p_sys = p_access->p_sys; if( p_cam->i_ca_type & CA_CI_LINK )
if( p_sys->i_ca_type & CA_CI_LINK )
{ {
int i_slot; for ( unsigned i_slot = 0; i_slot < p_cam->i_nb_slots; i_slot++ )
for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ )
{ {
if ( ioctl( p_sys->i_ca_handle, CA_RESET, 1 << i_slot) != 0 ) if ( ioctl( p_cam->fd, CA_RESET, 1 << i_slot) != 0 )
{ {
msg_Err( p_access, "en50221_Init: couldn't reset slot %d", msg_Err( p_cam->obj, "en50221_Init: couldn't reset slot %d",
i_slot ); i_slot );
} }
} }
p_sys->i_ca_timeout = 100000; p_cam->i_timeout = CLOCK_FREQ / 10;
/* Wait a bit otherwise it doesn't initialize properly... */ /* Wait a bit otherwise it doesn't initialize properly... */
msleep( 1000000 ); msleep( CLOCK_FREQ / 10 );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -1889,23 +1843,23 @@ int en50221_Init( access_t * p_access ) ...@@ -1889,23 +1843,23 @@ int en50221_Init( access_t * p_access )
/* We don't reset the CAM in that case because it's done by the /* We don't reset the CAM in that case because it's done by the
* ASIC. */ * ASIC. */
if ( ioctl( p_sys->i_ca_handle, CA_GET_SLOT_INFO, &info ) < 0 ) if ( ioctl( p_cam->fd, CA_GET_SLOT_INFO, &info ) < 0 )
{ {
msg_Err( p_access, "en50221_Init: couldn't get slot info" ); msg_Err( p_cam->obj, "en50221_Init: couldn't get slot info" );
close( p_sys->i_ca_handle ); close( p_cam->fd );
p_sys->i_ca_handle = 0; p_cam->fd = -1;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( info.flags == 0 ) if( info.flags == 0 )
{ {
msg_Err( p_access, "en50221_Init: no CAM inserted" ); msg_Err( p_cam->obj, "en50221_Init: no CAM inserted" );
close( p_sys->i_ca_handle ); close( p_cam->fd );
p_sys->i_ca_handle = 0; p_cam->fd = -1;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* Allocate a dummy sessions */ /* Allocate a dummy sessions */
p_sys->p_sessions[ 0 ].i_resource_id = RI_CONDITIONAL_ACCESS_SUPPORT; p_cam->p_sessions[ 0 ].i_resource_id = RI_CONDITIONAL_ACCESS_SUPPORT;
/* Get application info to find out which cam we are using and make /* Get application info to find out which cam we are using and make
sure everything is ready to play */ sure everything is ready to play */
...@@ -1915,40 +1869,40 @@ int en50221_Init( access_t * p_access ) ...@@ -1915,40 +1869,40 @@ int en50221_Init( access_t * p_access )
ca_msg.msg[1] = ( AOT_APPLICATION_INFO & 0x00FF00 ) >> 8; ca_msg.msg[1] = ( AOT_APPLICATION_INFO & 0x00FF00 ) >> 8;
ca_msg.msg[2] = ( AOT_APPLICATION_INFO & 0x0000FF ) >> 0; ca_msg.msg[2] = ( AOT_APPLICATION_INFO & 0x0000FF ) >> 0;
memset( &ca_msg.msg[3], 0, 253 ); memset( &ca_msg.msg[3], 0, 253 );
APDUSend( p_access, 1, AOT_APPLICATION_INFO_ENQ, NULL, 0 ); APDUSend( p_cam, 1, AOT_APPLICATION_INFO_ENQ, NULL, 0 );
if ( ioctl( p_sys->i_ca_handle, CA_GET_MSG, &ca_msg ) < 0 ) if ( ioctl( p_cam->fd, CA_GET_MSG, &ca_msg ) < 0 )
{ {
msg_Err( p_access, "en50221_Init: failed getting message" ); msg_Err( p_cam->obj, "en50221_Init: failed getting message" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
#if HLCI_WAIT_CAM_READY #if HLCI_WAIT_CAM_READY
while( ca_msg.msg[8] == 0xff && ca_msg.msg[9] == 0xff ) while( ca_msg.msg[8] == 0xff && ca_msg.msg[9] == 0xff )
{ {
if( !vlc_object_alive (p_access) ) return VLC_EGENERIC; if( !vlc_object_alive (p_cam) ) return VLC_EGENERIC;
msleep(1); msleep(1);
msg_Dbg( p_access, "CAM: please wait" ); msg_Dbg( p_cam->obj, "CAM: please wait" );
APDUSend( p_access, 1, AOT_APPLICATION_INFO_ENQ, NULL, 0 ); APDUSend( p_cam, 1, AOT_APPLICATION_INFO_ENQ, NULL, 0 );
ca_msg.length=3; ca_msg.length=3;
ca_msg.msg[0] = ( AOT_APPLICATION_INFO & 0xFF0000 ) >> 16; ca_msg.msg[0] = ( AOT_APPLICATION_INFO & 0xFF0000 ) >> 16;
ca_msg.msg[1] = ( AOT_APPLICATION_INFO & 0x00FF00 ) >> 8; ca_msg.msg[1] = ( AOT_APPLICATION_INFO & 0x00FF00 ) >> 8;
ca_msg.msg[2] = ( AOT_APPLICATION_INFO & 0x0000FF ) >> 0; ca_msg.msg[2] = ( AOT_APPLICATION_INFO & 0x0000FF ) >> 0;
memset( &ca_msg.msg[3], 0, 253 ); memset( &ca_msg.msg[3], 0, 253 );
if ( ioctl( p_sys->i_ca_handle, CA_GET_MSG, &ca_msg ) < 0 ) if ( ioctl( p_cam->fd, CA_GET_MSG, &ca_msg ) < 0 )
{ {
msg_Err( p_access, "en50221_Init: failed getting message" ); msg_Err( p_cam->obj, "en50221_Init: failed getting message" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
msg_Dbg( p_access, "en50221_Init: Got length: %d, tag: 0x%x", ca_msg.length, APDUGetTag( ca_msg.msg, ca_msg.length ) ); msg_Dbg( p_cam->obj, "en50221_Init: Got length: %d, tag: 0x%x", ca_msg.length, APDUGetTag( ca_msg.msg, ca_msg.length ) );
} }
#else #else
if( ca_msg.msg[8] == 0xff && ca_msg.msg[9] == 0xff ) if( ca_msg.msg[8] == 0xff && ca_msg.msg[9] == 0xff )
{ {
msg_Err( p_access, "CAM returns garbage as application info!" ); msg_Err( p_cam->obj, "CAM returns garbage as application info!" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
#endif #endif
msg_Dbg( p_access, "found CAM %s using id 0x%x", &ca_msg.msg[12], msg_Dbg( p_cam->obj, "found CAM %s using id 0x%x", &ca_msg.msg[12],
(ca_msg.msg[8]<<8)|ca_msg.msg[9] ); (ca_msg.msg[8]<<8)|ca_msg.msg[9] );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -1957,113 +1911,105 @@ int en50221_Init( access_t * p_access ) ...@@ -1957,113 +1911,105 @@ int en50221_Init( access_t * p_access )
/***************************************************************************** /*****************************************************************************
* en50221_Poll : Poll the CAM for TPDUs * en50221_Poll : Poll the CAM for TPDUs
*****************************************************************************/ *****************************************************************************/
int en50221_Poll( access_t * p_access ) int en50221_Poll( cam_t * p_cam )
{ {
access_sys_t *p_sys = p_access->p_sys; for ( unsigned i_slot = 0; i_slot < p_cam->i_nb_slots; i_slot++ )
int i_slot;
int i_session_id;
for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ )
{ {
uint8_t i_tag; uint8_t i_tag;
ca_slot_info_t sinfo; ca_slot_info_t sinfo;
sinfo.num = i_slot; sinfo.num = i_slot;
if ( ioctl( p_sys->i_ca_handle, CA_GET_SLOT_INFO, &sinfo ) != 0 ) if ( ioctl( p_cam->fd, CA_GET_SLOT_INFO, &sinfo ) != 0 )
{ {
msg_Err( p_access, "en50221_Poll: couldn't get info on slot %d", msg_Err( p_cam->obj, "en50221_Poll: couldn't get info on slot %d",
i_slot ); i_slot );
continue; continue;
} }
if ( !(sinfo.flags & CA_CI_MODULE_READY) ) if ( !(sinfo.flags & CA_CI_MODULE_READY) )
{ {
if ( p_sys->pb_active_slot[i_slot] ) if ( p_cam->pb_active_slot[i_slot] )
{ {
msg_Dbg( p_access, "en50221_Poll: slot %d has been removed", msg_Dbg( p_cam->obj, "en50221_Poll: slot %d has been removed",
i_slot ); i_slot );
p_sys->pb_active_slot[i_slot] = false; p_cam->pb_active_slot[i_slot] = false;
p_sys->pb_slot_mmi_expected[i_slot] = false; p_cam->pb_slot_mmi_expected[i_slot] = false;
p_sys->pb_slot_mmi_undisplayed[i_slot] = false; p_cam->pb_slot_mmi_undisplayed[i_slot] = false;
/* Close all sessions for this slot. */ /* Close all sessions for this slot. */
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; for ( unsigned i = 1; i <= MAX_SESSIONS; i++ )
i_session_id++ )
{ {
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id if ( p_cam->p_sessions[i - 1].i_resource_id
&& p_sys->p_sessions[i_session_id - 1].i_slot && p_cam->p_sessions[i - 1].i_slot == i_slot )
== i_slot )
{ {
if ( p_sys->p_sessions[i_session_id - 1].pf_close if ( p_cam->p_sessions[i - 1].pf_close != NULL )
!= NULL )
{ {
p_sys->p_sessions[i_session_id - 1].pf_close( p_cam->p_sessions[i - 1].pf_close( p_cam, i );
p_access, i_session_id );
} }
p_sys->p_sessions[i_session_id - 1].i_resource_id = 0; p_cam->p_sessions[i - 1].i_resource_id = 0;
} }
} }
} }
continue; continue;
} }
else if ( !p_sys->pb_active_slot[i_slot] ) else if ( !p_cam->pb_active_slot[i_slot] )
{ {
InitSlot( p_access, i_slot ); InitSlot( p_cam, i_slot );
if ( !p_sys->pb_active_slot[i_slot] ) if ( !p_cam->pb_active_slot[i_slot] )
{ {
msg_Dbg( p_access, "en50221_Poll: resetting slot %d", i_slot ); msg_Dbg( p_cam->obj, "en50221_Poll: resetting slot %d", i_slot );
if ( ioctl( p_sys->i_ca_handle, CA_RESET, 1 << i_slot) != 0 ) if ( ioctl( p_cam->fd, CA_RESET, 1 << i_slot) != 0 )
{ {
msg_Err( p_access, "en50221_Poll: couldn't reset slot %d", msg_Err( p_cam->obj, "en50221_Poll: couldn't reset slot %d",
i_slot ); i_slot );
} }
continue; continue;
} }
msg_Dbg( p_access, "en50221_Poll: slot %d is active", msg_Dbg( p_cam->obj, "en50221_Poll: slot %d is active",
i_slot ); i_slot );
} }
if ( !p_sys->pb_tc_has_data[i_slot] ) if ( !p_cam->pb_tc_has_data[i_slot] )
{ {
if ( TPDUSend( p_access, i_slot, T_DATA_LAST, NULL, 0 ) != if ( TPDUSend( p_cam, i_slot, T_DATA_LAST, NULL, 0 ) !=
VLC_SUCCESS ) VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"en50221_Poll: couldn't send TPDU on slot %d", "en50221_Poll: couldn't send TPDU on slot %d",
i_slot ); i_slot );
continue; continue;
} }
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != if ( TPDURecv( p_cam, i_slot, &i_tag, NULL, NULL ) !=
VLC_SUCCESS ) VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"en50221_Poll: couldn't recv TPDU on slot %d", "en50221_Poll: couldn't recv TPDU on slot %d",
i_slot ); i_slot );
continue; continue;
} }
} }
while ( p_sys->pb_tc_has_data[i_slot] ) while ( p_cam->pb_tc_has_data[i_slot] )
{ {
uint8_t p_tpdu[MAX_TPDU_SIZE]; uint8_t p_tpdu[MAX_TPDU_SIZE];
int i_size, i_session_size; int i_size, i_session_size;
uint8_t *p_session; uint8_t *p_session;
if ( TPDUSend( p_access, i_slot, T_RCV, NULL, 0 ) != VLC_SUCCESS ) if ( TPDUSend( p_cam, i_slot, T_RCV, NULL, 0 ) != VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"en50221_Poll: couldn't send TPDU on slot %d", "en50221_Poll: couldn't send TPDU on slot %d",
i_slot ); i_slot );
continue; continue;
} }
if ( TPDURecv( p_access, i_slot, &i_tag, p_tpdu, &i_size ) != if ( TPDURecv( p_cam, i_slot, &i_tag, p_tpdu, &i_size ) !=
VLC_SUCCESS ) VLC_SUCCESS )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"en50221_Poll: couldn't recv TPDU on slot %d", "en50221_Poll: couldn't recv TPDU on slot %d",
i_slot ); i_slot );
continue; continue;
...@@ -2078,21 +2024,21 @@ int en50221_Poll( access_t * p_access ) ...@@ -2078,21 +2024,21 @@ int en50221_Poll( access_t * p_access )
if ( i_tag != T_DATA_LAST ) if ( i_tag != T_DATA_LAST )
{ {
msg_Err( p_access, msg_Err( p_cam->obj,
"en50221_Poll: fragmented TPDU not supported" ); "en50221_Poll: fragmented TPDU not supported" );
break; break;
} }
SPDUHandle( p_access, i_slot, p_session, i_session_size ); SPDUHandle( p_cam, i_slot, p_session, i_session_size );
} }
} }
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ ) for ( int i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{ {
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id if ( p_cam->p_sessions[i_session_id - 1].i_resource_id
&& p_sys->p_sessions[i_session_id - 1].pf_manage ) && p_cam->p_sessions[i_session_id - 1].pf_manage )
{ {
p_sys->p_sessions[i_session_id - 1].pf_manage( p_access, p_cam->p_sessions[i_session_id - 1].pf_manage( p_cam,
i_session_id ); i_session_id );
} }
} }
...@@ -2104,17 +2050,15 @@ int en50221_Poll( access_t * p_access ) ...@@ -2104,17 +2050,15 @@ int en50221_Poll( access_t * p_access )
/***************************************************************************** /*****************************************************************************
* en50221_SetCAPMT : * en50221_SetCAPMT :
*****************************************************************************/ *****************************************************************************/
int en50221_SetCAPMT( access_t * p_access, dvbpsi_pmt_t *p_pmt ) int en50221_SetCAPMT( cam_t * p_cam, dvbpsi_pmt_t *p_pmt )
{ {
access_sys_t *p_sys = p_access->p_sys;
int i, i_session_id;
bool b_update = false; bool b_update = false;
bool b_needs_descrambling = CAPMTNeedsDescrambling( p_pmt ); bool b_needs_descrambling = CAPMTNeedsDescrambling( p_pmt );
for ( i = 0; i < MAX_PROGRAMS; i++ ) for ( unsigned i = 0; i < MAX_PROGRAMS; i++ )
{ {
if ( p_sys->pp_selected_programs[i] != NULL if ( p_cam->pp_selected_programs[i] != NULL
&& p_sys->pp_selected_programs[i]->i_program_number && p_cam->pp_selected_programs[i]->i_program_number
== p_pmt->i_program_number ) == p_pmt->i_program_number )
{ {
b_update = true; b_update = true;
...@@ -2122,13 +2066,13 @@ int en50221_SetCAPMT( access_t * p_access, dvbpsi_pmt_t *p_pmt ) ...@@ -2122,13 +2066,13 @@ int en50221_SetCAPMT( access_t * p_access, dvbpsi_pmt_t *p_pmt )
if ( !b_needs_descrambling ) if ( !b_needs_descrambling )
{ {
dvbpsi_DeletePMT( p_pmt ); dvbpsi_DeletePMT( p_pmt );
p_pmt = p_sys->pp_selected_programs[i]; p_pmt = p_cam->pp_selected_programs[i];
p_sys->pp_selected_programs[i] = NULL; p_cam->pp_selected_programs[i] = NULL;
} }
else if( p_pmt != p_sys->pp_selected_programs[i] ) else if( p_pmt != p_cam->pp_selected_programs[i] )
{ {
dvbpsi_DeletePMT( p_sys->pp_selected_programs[i] ); dvbpsi_DeletePMT( p_cam->pp_selected_programs[i] );
p_sys->pp_selected_programs[i] = p_pmt; p_cam->pp_selected_programs[i] = p_pmt;
} }
break; break;
...@@ -2137,11 +2081,11 @@ int en50221_SetCAPMT( access_t * p_access, dvbpsi_pmt_t *p_pmt ) ...@@ -2137,11 +2081,11 @@ int en50221_SetCAPMT( access_t * p_access, dvbpsi_pmt_t *p_pmt )
if ( !b_update && b_needs_descrambling ) if ( !b_update && b_needs_descrambling )
{ {
for ( i = 0; i < MAX_PROGRAMS; i++ ) for ( unsigned i = 0; i < MAX_PROGRAMS; i++ )
{ {
if ( p_sys->pp_selected_programs[i] == NULL ) if ( p_cam->pp_selected_programs[i] == NULL )
{ {
p_sys->pp_selected_programs[i] = p_pmt; p_cam->pp_selected_programs[i] = p_pmt;
break; break;
} }
} }
...@@ -2149,17 +2093,17 @@ int en50221_SetCAPMT( access_t * p_access, dvbpsi_pmt_t *p_pmt ) ...@@ -2149,17 +2093,17 @@ int en50221_SetCAPMT( access_t * p_access, dvbpsi_pmt_t *p_pmt )
if ( b_update || b_needs_descrambling ) if ( b_update || b_needs_descrambling )
{ {
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ ) for ( unsigned i = 1; i <= MAX_SESSIONS; i++ )
{ {
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id if ( p_cam->p_sessions[i - 1].i_resource_id
== RI_CONDITIONAL_ACCESS_SUPPORT ) == RI_CONDITIONAL_ACCESS_SUPPORT )
{ {
if ( b_update && b_needs_descrambling ) if ( b_update && b_needs_descrambling )
CAPMTUpdate( p_access, i_session_id, p_pmt ); CAPMTUpdate( p_cam, i, p_pmt );
else if ( b_update ) else if ( b_update )
CAPMTDelete( p_access, i_session_id, p_pmt ); CAPMTDelete( p_cam, i, p_pmt );
else else
CAPMTAdd( p_access, i_session_id, p_pmt ); CAPMTAdd( p_cam, i, p_pmt );
} }
} }
} }
...@@ -2175,42 +2119,39 @@ int en50221_SetCAPMT( access_t * p_access, dvbpsi_pmt_t *p_pmt ) ...@@ -2175,42 +2119,39 @@ int en50221_SetCAPMT( access_t * p_access, dvbpsi_pmt_t *p_pmt )
/***************************************************************************** /*****************************************************************************
* en50221_OpenMMI : * en50221_OpenMMI :
*****************************************************************************/ *****************************************************************************/
int en50221_OpenMMI( access_t * p_access, int i_slot ) int en50221_OpenMMI( cam_t * p_cam, unsigned i_slot )
{ {
access_sys_t *p_sys = p_access->p_sys; if( p_cam->i_ca_type & CA_CI_LINK )
if( p_sys->i_ca_type & CA_CI_LINK )
{ {
int i_session_id; for ( unsigned i = 1; i <= MAX_SESSIONS; i++ )
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{ {
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id == RI_MMI if ( p_cam->p_sessions[i - 1].i_resource_id == RI_MMI
&& p_sys->p_sessions[i_session_id - 1].i_slot == i_slot ) && p_cam->p_sessions[i - 1].i_slot == i_slot )
{ {
msg_Dbg( p_access, msg_Dbg( p_cam->obj,
"MMI menu is already opened on slot %d (session=%d)", "MMI menu is already opened on slot %d (session=%u)",
i_slot, i_session_id ); i_slot, i );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
} }
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ ) for ( unsigned i = 1; i <= MAX_SESSIONS; i++ )
{ {
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id if ( p_cam->p_sessions[i - 1].i_resource_id
== RI_APPLICATION_INFORMATION == RI_APPLICATION_INFORMATION
&& p_sys->p_sessions[i_session_id - 1].i_slot == i_slot ) && p_cam->p_sessions[i - 1].i_slot == i_slot )
{ {
ApplicationInformationEnterMenu( p_access, i_session_id ); ApplicationInformationEnterMenu( p_cam, i );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
} }
msg_Err( p_access, "no application information on slot %d", i_slot ); msg_Err( p_cam->obj, "no application information on slot %d", i_slot );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
else else
{ {
msg_Err( p_access, "MMI menu not supported" ); msg_Err( p_cam->obj, "MMI menu not supported" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
} }
...@@ -2218,30 +2159,27 @@ int en50221_OpenMMI( access_t * p_access, int i_slot ) ...@@ -2218,30 +2159,27 @@ int en50221_OpenMMI( access_t * p_access, int i_slot )
/***************************************************************************** /*****************************************************************************
* en50221_CloseMMI : * en50221_CloseMMI :
*****************************************************************************/ *****************************************************************************/
int en50221_CloseMMI( access_t * p_access, int i_slot ) int en50221_CloseMMI( cam_t * p_cam, unsigned i_slot )
{ {
access_sys_t *p_sys = p_access->p_sys; if( p_cam->i_ca_type & CA_CI_LINK )
if( p_sys->i_ca_type & CA_CI_LINK )
{ {
int i_session_id; for( unsigned i = 1; i <= MAX_SESSIONS; i++ )
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{ {
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id == RI_MMI if ( p_cam->p_sessions[i - 1].i_resource_id == RI_MMI
&& p_sys->p_sessions[i_session_id - 1].i_slot == i_slot ) && p_cam->p_sessions[i - 1].i_slot == i_slot )
{ {
MMISendClose( p_access, i_session_id ); MMISendClose( p_cam, i );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
} }
msg_Warn( p_access, "closing a non-existing MMI session on slot %d", msg_Warn( p_cam->obj, "closing a non-existing MMI session on slot %d",
i_slot ); i_slot );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
else else
{ {
msg_Err( p_access, "MMI menu not supported" ); msg_Err( p_cam->obj, "MMI menu not supported" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
} }
...@@ -2249,22 +2187,18 @@ int en50221_CloseMMI( access_t * p_access, int i_slot ) ...@@ -2249,22 +2187,18 @@ int en50221_CloseMMI( access_t * p_access, int i_slot )
/***************************************************************************** /*****************************************************************************
* en50221_GetMMIObject : * en50221_GetMMIObject :
*****************************************************************************/ *****************************************************************************/
en50221_mmi_object_t *en50221_GetMMIObject( access_t * p_access, en50221_mmi_object_t *en50221_GetMMIObject( cam_t * p_cam, unsigned i_slot )
int i_slot )
{ {
access_sys_t *p_sys = p_access->p_sys; if( p_cam->pb_slot_mmi_expected[i_slot] == true )
int i_session_id;
if ( p_sys->pb_slot_mmi_expected[i_slot] == true )
return NULL; /* should not happen */ return NULL; /* should not happen */
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ ) for( unsigned i = 1; i <= MAX_SESSIONS; i++ )
{ {
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id == RI_MMI if ( p_cam->p_sessions[i - 1].i_resource_id == RI_MMI
&& p_sys->p_sessions[i_session_id - 1].i_slot == i_slot ) && p_cam->p_sessions[i - 1].i_slot == i_slot )
{ {
mmi_t *p_mmi = mmi_t *p_mmi =
(mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys; (mmi_t *)p_cam->p_sessions[i - 1].p_sys;
if ( p_mmi == NULL ) if ( p_mmi == NULL )
return NULL; /* should not happen */ return NULL; /* should not happen */
return &p_mmi->last_object; return &p_mmi->last_object;
...@@ -2278,48 +2212,41 @@ en50221_mmi_object_t *en50221_GetMMIObject( access_t * p_access, ...@@ -2278,48 +2212,41 @@ en50221_mmi_object_t *en50221_GetMMIObject( access_t * p_access,
/***************************************************************************** /*****************************************************************************
* en50221_SendMMIObject : * en50221_SendMMIObject :
*****************************************************************************/ *****************************************************************************/
void en50221_SendMMIObject( access_t * p_access, int i_slot, void en50221_SendMMIObject( cam_t * p_cam, unsigned i_slot,
en50221_mmi_object_t *p_object ) en50221_mmi_object_t *p_object )
{ {
access_sys_t *p_sys = p_access->p_sys; for( unsigned i = 1; i <= MAX_SESSIONS; i++ )
int i_session_id;
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{ {
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id == RI_MMI if ( p_cam->p_sessions[i - 1].i_resource_id == RI_MMI
&& p_sys->p_sessions[i_session_id - 1].i_slot == i_slot ) && p_cam->p_sessions[i - 1].i_slot == i_slot )
{ {
MMISendObject( p_access, i_session_id, p_object ); MMISendObject( p_cam, i, p_object );
return; return;
} }
} }
msg_Err( p_access, "SendMMIObject when no MMI session is opened !" ); msg_Err( p_cam->obj, "SendMMIObject when no MMI session is opened !" );
} }
/***************************************************************************** /*****************************************************************************
* en50221_End : * en50221_End :
*****************************************************************************/ *****************************************************************************/
void en50221_End( access_t * p_access ) void en50221_End( cam_t * p_cam )
{ {
access_sys_t *p_sys = p_access->p_sys; for( unsigned i = 0; i < MAX_PROGRAMS; i++ )
int i_session_id, i;
for ( i = 0; i < MAX_PROGRAMS; i++ )
{ {
if ( p_sys->pp_selected_programs[i] != NULL ) if( p_cam->pp_selected_programs[i] != NULL )
{ {
dvbpsi_DeletePMT( p_sys->pp_selected_programs[i] ); dvbpsi_DeletePMT( p_cam->pp_selected_programs[i] );
} }
} }
for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ ) for( unsigned i = 1; i <= MAX_SESSIONS; i++ )
{ {
if ( p_sys->p_sessions[i_session_id - 1].i_resource_id if( p_cam->p_sessions[i - 1].i_resource_id
&& p_sys->p_sessions[i_session_id - 1].pf_close != NULL ) && p_cam->p_sessions[i - 1].pf_close != NULL )
{ {
p_sys->p_sessions[i_session_id - 1].pf_close( p_access, p_cam->p_sessions[i - 1].pf_close( p_cam, i );
i_session_id );
} }
} }
......
/*****************************************************************************
* en50221.h:
*****************************************************************************
* Copyright (C) 1998-2010 the VideoLAN team
*
* Authors: Johan Bilien <jobi@via.ecp.fr>
* Jean-Paul Saman <jpsaman _at_ videolan _dot_ org>
* Christopher Ross <chris@tebibyte.org>
* Christophe Massiot <massiot@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
typedef struct cam cam_t;
typedef struct en50221_session_t
{
unsigned i_slot;
int i_resource_id;
void (* pf_handle)( cam_t *, int, uint8_t *, int );
void (* pf_close)( cam_t *, int );
void (* pf_manage)( cam_t *, int );
void *p_sys;
} en50221_session_t;
#define EN50221_MMI_NONE 0
#define EN50221_MMI_ENQ 1
#define EN50221_MMI_ANSW 2
#define EN50221_MMI_MENU 3
#define EN50221_MMI_MENU_ANSW 4
#define EN50221_MMI_LIST 5
typedef struct en50221_mmi_object_t
{
int i_object_type;
union
{
struct
{
bool b_blind;
char *psz_text;
} enq;
struct
{
bool b_ok;
char *psz_answ;
} answ;
struct
{
char *psz_title, *psz_subtitle, *psz_bottom;
char **ppsz_choices;
int i_choices;
} menu; /* menu and list are the same */
struct
{
int i_choice;
} menu_answ;
} u;
} en50221_mmi_object_t;
static inline void en50221_MMIFree( en50221_mmi_object_t *p_object )
{
int i;
switch ( p_object->i_object_type )
{
case EN50221_MMI_ENQ:
FREENULL( p_object->u.enq.psz_text );
break;
case EN50221_MMI_ANSW:
if ( p_object->u.answ.b_ok )
{
FREENULL( p_object->u.answ.psz_answ );
}
break;
case EN50221_MMI_MENU:
case EN50221_MMI_LIST:
FREENULL( p_object->u.menu.psz_title );
FREENULL( p_object->u.menu.psz_subtitle );
FREENULL( p_object->u.menu.psz_bottom );
for ( i = 0; i < p_object->u.menu.i_choices; i++ )
{
free( p_object->u.menu.ppsz_choices[i] );
}
FREENULL( p_object->u.menu.ppsz_choices );
break;
default:
break;
}
}
/* CA management */
#define MAX_CI_SLOTS 16
#define MAX_SESSIONS 32
#define MAX_PROGRAMS 24
struct cam
{
vlc_object_t *obj;
int i_ca_type;
int fd;
mtime_t i_timeout, i_next_event;
unsigned i_nb_slots;
bool pb_active_slot[MAX_CI_SLOTS];
bool pb_tc_has_data[MAX_CI_SLOTS];
bool pb_slot_mmi_expected[MAX_CI_SLOTS];
bool pb_slot_mmi_undisplayed[MAX_CI_SLOTS];
en50221_session_t p_sessions[MAX_SESSIONS];
dvbpsi_pmt_t *pp_selected_programs[MAX_PROGRAMS];
int i_selected_programs;
};
int en50221_Init( cam_t * );
int en50221_Poll( cam_t * );
int en50221_SetCAPMT( cam_t *, dvbpsi_pmt_t * );
int en50221_OpenMMI( cam_t *, unsigned i_slot );
int en50221_CloseMMI( cam_t *, unsigned i_slot );
en50221_mmi_object_t *en50221_GetMMIObject( cam_t *, unsigned i_slot );
void en50221_SendMMIObject( cam_t *, unsigned i_slot, en50221_mmi_object_t * );
void en50221_End( cam_t * );
char *dvbsi_to_utf8( const char *psz_instring, size_t i_length );
...@@ -242,7 +242,7 @@ static int HttpCallback( httpd_file_sys_t *p_args, ...@@ -242,7 +242,7 @@ static int HttpCallback( httpd_file_sys_t *p_args,
p_sys->i_httpd_timeout = mdate() + INT64_C(3000000); /* 3 s */ p_sys->i_httpd_timeout = mdate() + INT64_C(3000000); /* 3 s */
p_sys->psz_request = psz_request; p_sys->psz_request = psz_request;
p_sys->b_request_frontend_info = true; p_sys->b_request_frontend_info = true;
if ( p_sys->i_ca_handle ) if ( p_sys->cam.fd != -1 )
{ {
p_sys->b_request_mmi_info = true; p_sys->b_request_mmi_info = true;
} }
......
...@@ -1462,11 +1462,13 @@ void DVRClose( access_t * p_access ) ...@@ -1462,11 +1462,13 @@ void DVRClose( access_t * p_access )
*****************************************************************************/ *****************************************************************************/
int CAMOpen( access_t *p_access ) int CAMOpen( access_t *p_access )
{ {
access_sys_t *p_sys = p_access->p_sys; cam_t *p_cam = &p_access->p_sys->cam;
char ca[128]; char ca[128];
int i_adapter, i_device; int i_adapter, i_device;
ca_caps_t caps; ca_caps_t caps;
p_cam->obj = VLC_OBJECT(p_access);
i_adapter = var_GetInteger( p_access, "dvb-adapter" ); i_adapter = var_GetInteger( p_access, "dvb-adapter" );
i_device = var_GetInteger( p_access, "dvb-device" ); i_device = var_GetInteger( p_access, "dvb-device" );
...@@ -1478,19 +1480,17 @@ int CAMOpen( access_t *p_access ) ...@@ -1478,19 +1480,17 @@ int CAMOpen( access_t *p_access )
memset( &caps, 0, sizeof( ca_caps_t )); memset( &caps, 0, sizeof( ca_caps_t ));
msg_Dbg( p_access, "Opening device %s", ca ); msg_Dbg( p_access, "Opening device %s", ca );
if( (p_sys->i_ca_handle = vlc_open(ca, O_RDWR | O_NONBLOCK)) < 0 ) p_cam->fd = vlc_open(ca, O_RDWR | O_NONBLOCK);
if( p_cam->fd == -1 )
{ {
msg_Warn( p_access, "CAMInit: opening CAM device failed (%m)" ); msg_Warn( p_access, "CAMInit: opening CAM device failed (%m)" );
p_sys->i_ca_handle = 0;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if ( ioctl( p_sys->i_ca_handle, CA_GET_CAP, &caps ) != 0 ) if ( ioctl( p_cam->fd, CA_GET_CAP, &caps ) < 0 )
{ {
msg_Err( p_access, "CAMInit: ioctl() error getting CAM capabilities" ); msg_Err( p_access, "CAMInit: ioctl() error getting CAM capabilities" );
close( p_sys->i_ca_handle ); goto error;
p_sys->i_ca_handle = 0;
return VLC_EGENERIC;
} }
/* Output CA capabilities */ /* Output CA capabilities */
...@@ -1519,35 +1519,35 @@ int CAMOpen( access_t *p_access ) ...@@ -1519,35 +1519,35 @@ int CAMOpen( access_t *p_access )
if ( caps.slot_num == 0 ) if ( caps.slot_num == 0 )
{ {
msg_Err( p_access, "CAMInit: CAM module with no slots" ); msg_Err( p_access, "CAMInit: CAM module with no slots" );
close( p_sys->i_ca_handle ); goto error;
p_sys->i_ca_handle = 0;
return VLC_EGENERIC;
} }
if( caps.slot_type & CA_CI_LINK ) if( caps.slot_type & CA_CI_LINK )
{ {
p_sys->i_ca_type = CA_CI_LINK; p_cam->i_ca_type = CA_CI_LINK;
} }
else if( caps.slot_type & CA_CI ) else if( caps.slot_type & CA_CI )
{ {
p_sys->i_ca_type = CA_CI; p_cam->i_ca_type = CA_CI;
} }
else else
{ {
p_sys->i_ca_type = -1; p_cam->i_ca_type = -1;
msg_Err( p_access, "CAMInit: incompatible CAM interface" ); msg_Err( p_access, "CAMInit: incompatible CAM interface" );
close( p_sys->i_ca_handle ); goto error;
p_sys->i_ca_handle = 0;
return VLC_EGENERIC;
} }
p_sys->i_nb_slots = caps.slot_num; p_cam->i_nb_slots = caps.slot_num;
memset( p_sys->pb_active_slot, 0, sizeof(bool) * MAX_CI_SLOTS ); memset( p_cam->pb_active_slot, 0, sizeof(bool) * MAX_CI_SLOTS );
memset( p_sys->pb_slot_mmi_expected, 0, sizeof(bool) * MAX_CI_SLOTS ); memset( p_cam->pb_slot_mmi_expected, 0, sizeof(bool) * MAX_CI_SLOTS );
memset( p_sys->pb_slot_mmi_undisplayed, 0, memset( p_cam->pb_slot_mmi_undisplayed, 0,
sizeof(bool) * MAX_CI_SLOTS ); sizeof(bool) * MAX_CI_SLOTS );
return en50221_Init( p_access ); return en50221_Init( p_cam );
error:
close( p_cam->fd );
p_cam->fd = -1;
return VLC_EGENERIC;
} }
/***************************************************************************** /*****************************************************************************
...@@ -1555,28 +1555,25 @@ int CAMOpen( access_t *p_access ) ...@@ -1555,28 +1555,25 @@ int CAMOpen( access_t *p_access )
*****************************************************************************/ *****************************************************************************/
int CAMPoll( access_t * p_access ) int CAMPoll( access_t * p_access )
{ {
access_sys_t *p_sys = p_access->p_sys; cam_t *p_cam = &p_access->p_sys->cam;
int i_ret = VLC_EGENERIC;
if ( p_sys->i_ca_handle == 0 ) if ( p_cam->fd == -1 )
{
return VLC_EGENERIC; return VLC_EGENERIC;
}
switch( p_sys->i_ca_type ) switch( p_cam->i_ca_type )
{ {
case CA_CI_LINK: case CA_CI_LINK:
i_ret = en50221_Poll( p_access ); if ( mdate() > p_cam->i_next_event )
break; {
int ret = en50221_Poll( p_cam );
p_cam->i_next_event = mdate() + p_cam->i_timeout;
return ret;
}
case CA_CI: case CA_CI:
i_ret = VLC_SUCCESS; return VLC_SUCCESS;
break;
default:
msg_Err( p_access, "CAMPoll: This should not happen" );
break;
} }
msg_Err( p_access, "CAMPoll: This should not happen" );
return i_ret; return VLC_EGENERIC;;
} }
#ifdef ENABLE_HTTPD #ifdef ENABLE_HTTPD
...@@ -1586,17 +1583,18 @@ int CAMPoll( access_t * p_access ) ...@@ -1586,17 +1583,18 @@ int CAMPoll( access_t * p_access )
void CAMStatus( access_t * p_access ) void CAMStatus( access_t * p_access )
{ {
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
cam_t *p_cam = &p_sys->cam;
char *p; char *p;
ca_caps_t caps; ca_caps_t caps;
int i_slot, i; int i;
if ( p_sys->psz_request != NULL && *p_sys->psz_request ) if ( p_sys->psz_request != NULL && *p_sys->psz_request )
{ {
/* Check if we have an undisplayed MMI message : in that case we ignore /* Check if we have an undisplayed MMI message : in that case we ignore
* the user input to avoid confusing the CAM. */ * the user input to avoid confusing the CAM. */
for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ ) for ( unsigned i_slot = 0; i_slot < p_cam->i_nb_slots; i_slot++ )
{ {
if ( p_sys->pb_slot_mmi_undisplayed[i_slot] == true ) if ( p_cam->pb_slot_mmi_undisplayed[i_slot] == true )
{ {
p_sys->psz_request = NULL; p_sys->psz_request = NULL;
msg_Dbg( p_access, msg_Dbg( p_access,
...@@ -1628,14 +1626,14 @@ void CAMStatus( access_t * p_access ) ...@@ -1628,14 +1626,14 @@ void CAMStatus( access_t * p_access )
if ( HTTPExtractValue( psz_request, "open", psz_value, if ( HTTPExtractValue( psz_request, "open", psz_value,
sizeof(psz_value) ) != NULL ) sizeof(psz_value) ) != NULL )
{ {
en50221_OpenMMI( p_access, i_slot ); en50221_OpenMMI( p_cam, i_slot );
return; return;
} }
if ( HTTPExtractValue( psz_request, "close", psz_value, if ( HTTPExtractValue( psz_request, "close", psz_value,
sizeof(psz_value) ) != NULL ) sizeof(psz_value) ) != NULL )
{ {
en50221_CloseMMI( p_access, i_slot ); en50221_CloseMMI( p_cam, i_slot );
return; return;
} }
...@@ -1689,20 +1687,20 @@ void CAMStatus( access_t * p_access ) ...@@ -1689,20 +1687,20 @@ void CAMStatus( access_t * p_access )
} }
} }
en50221_SendMMIObject( p_access, i_slot, &mmi_object ); en50221_SendMMIObject( p_cam, i_slot, &mmi_object );
return; return;
} }
/* Check that we have all necessary MMI information. */ /* Check that we have all necessary MMI information. */
for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ ) for( unsigned i_slot = 0; i_slot < p_cam->i_nb_slots; i_slot++ )
{ {
if ( p_sys->pb_slot_mmi_expected[i_slot] == true ) if ( p_cam->pb_slot_mmi_expected[i_slot] == true )
return; return;
} }
p = p_sys->psz_mmi_info = malloc( 10000 ); p = p_sys->psz_mmi_info = malloc( 10000 );
if ( ioctl( p_sys->i_ca_handle, CA_GET_CAP, &caps ) != 0 ) if ( ioctl( p_cam->fd, CA_GET_CAP, &caps ) != 0 )
{ {
char buf[1000]; char buf[1000];
strerror_r( errno, buf, sizeof( buf ) ); strerror_r( errno, buf, sizeof( buf ) );
...@@ -1737,15 +1735,15 @@ void CAMStatus( access_t * p_access ) ...@@ -1737,15 +1735,15 @@ void CAMStatus( access_t * p_access )
p += sprintf( p, "</table>" ); p += sprintf( p, "</table>" );
for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ ) for( unsigned i_slot = 0; i_slot < p_cam->i_nb_slots; i_slot++ )
{ {
ca_slot_info_t sinfo; ca_slot_info_t sinfo;
p_sys->pb_slot_mmi_undisplayed[i_slot] = false; p_cam->pb_slot_mmi_undisplayed[i_slot] = false;
p += sprintf( p, "<p>CA slot #%d: ", i_slot ); p += sprintf( p, "<p>CA slot #%d: ", i_slot );
sinfo.num = i_slot; sinfo.num = i_slot;
if ( ioctl( p_sys->i_ca_handle, CA_GET_SLOT_INFO, &sinfo ) != 0 ) if ( ioctl( p_cam->fd, CA_GET_SLOT_INFO, &sinfo ) != 0 )
{ {
char buf[1000]; char buf[1000];
strerror_r( errno, buf, sizeof( buf ) ); strerror_r( errno, buf, sizeof( buf ) );
...@@ -1764,7 +1762,7 @@ void CAMStatus( access_t * p_access ) ...@@ -1764,7 +1762,7 @@ void CAMStatus( access_t * p_access )
if ( sinfo.flags & CA_CI_MODULE_READY ) if ( sinfo.flags & CA_CI_MODULE_READY )
{ {
en50221_mmi_object_t *p_object = en50221_GetMMIObject( p_access, en50221_mmi_object_t *p_object = en50221_GetMMIObject( p_cam,
i_slot ); i_slot );
p += sprintf( p, "module present and ready<p>\n" ); p += sprintf( p, "module present and ready<p>\n" );
...@@ -1845,15 +1843,15 @@ out: ...@@ -1845,15 +1843,15 @@ out:
*****************************************************************************/ *****************************************************************************/
int CAMSet( access_t * p_access, dvbpsi_pmt_t *p_pmt ) int CAMSet( access_t * p_access, dvbpsi_pmt_t *p_pmt )
{ {
access_sys_t *p_sys = p_access->p_sys; cam_t *p_cam = &p_access->p_sys->cam;
if( p_sys->i_ca_handle == 0 ) if( p_cam->fd == -1 )
{ {
dvbpsi_DeletePMT( p_pmt ); dvbpsi_DeletePMT( p_pmt );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
en50221_SetCAPMT( p_access, p_pmt ); en50221_SetCAPMT( p_cam, p_pmt );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -1863,13 +1861,11 @@ int CAMSet( access_t * p_access, dvbpsi_pmt_t *p_pmt ) ...@@ -1863,13 +1861,11 @@ int CAMSet( access_t * p_access, dvbpsi_pmt_t *p_pmt )
*****************************************************************************/ *****************************************************************************/
void CAMClose( access_t * p_access ) void CAMClose( access_t * p_access )
{ {
access_sys_t *p_sys = p_access->p_sys; cam_t *p_cam = &p_access->p_sys->cam;
en50221_End( p_access ); if ( p_cam->fd == -1 )
return;
if ( p_sys->i_ca_handle ) en50221_End( p_cam );
{ close( p_cam->fd );
close( p_sys->i_ca_handle );
}
} }
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