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

DVB: separate CA management

parent cc4cb782
SOURCES_dvb = \
access.c \
scan.c \
scan.h \
scan.c scan.h \
linux_dvb.c \
en50221.c \
en50221.c en50221.h \
http.c \
dvb.h \
$(NULL)
......@@ -473,11 +473,7 @@ static block_t *Block( access_t *p_access )
return NULL;
}
if ( p_sys->i_ca_handle && mdate() > p_sys->i_ca_next_event )
{
CAMPoll( p_access );
p_sys->i_ca_next_event = mdate() + p_sys->i_ca_timeout;
}
CAMPoll( p_access );
if ( ufds[1].revents )
{
......
......@@ -51,113 +51,19 @@ typedef struct
typedef struct scan_parameter_t scan_parameter_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_CI_SLOTS 16
#define MAX_SESSIONS 32
#define MAX_PROGRAMS 24
#include "en50221.h"
struct access_sys_t
{
int i_handle, i_frontend_handle;
demux_handle_t p_demux_handles[MAX_DEMUX];
frontend_t *p_frontend;
mtime_t i_frontend_timeout;
bool b_budget_mode;
/* CA management */
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;
cam_t cam;
/* */
int i_read_once;
......@@ -220,19 +126,6 @@ void CAMClose( access_t * );
void CAMStatus( access_t * );
#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
int HTTPOpen( access_t *p_access );
void HTTPClose( access_t *p_access );
......
This diff is collapsed.
/*****************************************************************************
* 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,
p_sys->i_httpd_timeout = mdate() + INT64_C(3000000); /* 3 s */
p_sys->psz_request = psz_request;
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;
}
......
......@@ -1462,11 +1462,13 @@ void DVRClose( 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];
int i_adapter, i_device;
ca_caps_t caps;
p_cam->obj = VLC_OBJECT(p_access);
i_adapter = var_GetInteger( p_access, "dvb-adapter" );
i_device = var_GetInteger( p_access, "dvb-device" );
......@@ -1478,19 +1480,17 @@ int CAMOpen( access_t *p_access )
memset( &caps, 0, sizeof( ca_caps_t ));
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)" );
p_sys->i_ca_handle = 0;
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" );
close( p_sys->i_ca_handle );
p_sys->i_ca_handle = 0;
return VLC_EGENERIC;
goto error;
}
/* Output CA capabilities */
......@@ -1519,35 +1519,35 @@ int CAMOpen( access_t *p_access )
if ( caps.slot_num == 0 )
{
msg_Err( p_access, "CAMInit: CAM module with no slots" );
close( p_sys->i_ca_handle );
p_sys->i_ca_handle = 0;
return VLC_EGENERIC;
goto error;
}
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 )
{
p_sys->i_ca_type = CA_CI;
p_cam->i_ca_type = CA_CI;
}
else
{
p_sys->i_ca_type = -1;
p_cam->i_ca_type = -1;
msg_Err( p_access, "CAMInit: incompatible CAM interface" );
close( p_sys->i_ca_handle );
p_sys->i_ca_handle = 0;
return VLC_EGENERIC;
goto error;
}
p_sys->i_nb_slots = caps.slot_num;
memset( p_sys->pb_active_slot, 0, sizeof(bool) * MAX_CI_SLOTS );
memset( p_sys->pb_slot_mmi_expected, 0, sizeof(bool) * MAX_CI_SLOTS );
memset( p_sys->pb_slot_mmi_undisplayed, 0,
p_cam->i_nb_slots = caps.slot_num;
memset( p_cam->pb_active_slot, 0, sizeof(bool) * MAX_CI_SLOTS );
memset( p_cam->pb_slot_mmi_expected, 0, sizeof(bool) * MAX_CI_SLOTS );
memset( p_cam->pb_slot_mmi_undisplayed, 0,
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 )
*****************************************************************************/
int CAMPoll( access_t * p_access )
{
access_sys_t *p_sys = p_access->p_sys;
int i_ret = VLC_EGENERIC;
cam_t *p_cam = &p_access->p_sys->cam;
if ( p_sys->i_ca_handle == 0 )
{
if ( p_cam->fd == -1 )
return VLC_EGENERIC;
}
switch( p_sys->i_ca_type )
switch( p_cam->i_ca_type )
{
case CA_CI_LINK:
i_ret = en50221_Poll( p_access );
break;
if ( mdate() > p_cam->i_next_event )
{
int ret = en50221_Poll( p_cam );
p_cam->i_next_event = mdate() + p_cam->i_timeout;
return ret;
}
case CA_CI:
i_ret = VLC_SUCCESS;
break;
default:
msg_Err( p_access, "CAMPoll: This should not happen" );
break;
return VLC_SUCCESS;
}
return i_ret;
msg_Err( p_access, "CAMPoll: This should not happen" );
return VLC_EGENERIC;;
}
#ifdef ENABLE_HTTPD
......@@ -1586,17 +1583,18 @@ int CAMPoll( access_t * p_access )
void CAMStatus( access_t * p_access )
{
access_sys_t *p_sys = p_access->p_sys;
cam_t *p_cam = &p_sys->cam;
char *p;
ca_caps_t caps;
int i_slot, i;
int i;
if ( p_sys->psz_request != NULL && *p_sys->psz_request )
{
/* Check if we have an undisplayed MMI message : in that case we ignore
* 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;
msg_Dbg( p_access,
......@@ -1628,14 +1626,14 @@ void CAMStatus( access_t * p_access )
if ( HTTPExtractValue( psz_request, "open", psz_value,
sizeof(psz_value) ) != NULL )
{
en50221_OpenMMI( p_access, i_slot );
en50221_OpenMMI( p_cam, i_slot );
return;
}
if ( HTTPExtractValue( psz_request, "close", psz_value,
sizeof(psz_value) ) != NULL )
{
en50221_CloseMMI( p_access, i_slot );
en50221_CloseMMI( p_cam, i_slot );
return;
}
......@@ -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;
}
/* 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;
}
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];
strerror_r( errno, buf, sizeof( buf ) );
......@@ -1737,15 +1735,15 @@ void CAMStatus( access_t * p_access )
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;
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 );
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];
strerror_r( errno, buf, sizeof( buf ) );
......@@ -1764,8 +1762,8 @@ void CAMStatus( access_t * p_access )
if ( sinfo.flags & CA_CI_MODULE_READY )
{
en50221_mmi_object_t *p_object = en50221_GetMMIObject( p_access,
i_slot );
en50221_mmi_object_t *p_object = en50221_GetMMIObject( p_cam,
i_slot );
p += sprintf( p, "module present and ready<p>\n" );
p += sprintf( p, "<form action=index.html method=get>\n" );
......@@ -1845,15 +1843,15 @@ out:
*****************************************************************************/
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 );
return VLC_EGENERIC;
}
en50221_SetCAPMT( p_access, p_pmt );
en50221_SetCAPMT( p_cam, p_pmt );
return VLC_SUCCESS;
}
......@@ -1863,13 +1861,11 @@ int CAMSet( access_t * p_access, dvbpsi_pmt_t *p_pmt )
*****************************************************************************/
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 )
{
close( p_sys->i_ca_handle );
}
en50221_End( p_cam );
close( p_cam->fd );
}
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