Commit 23f5aa02 authored by Christophe Massiot's avatar Christophe Massiot

* modules/access/dvb: Full support for DVB MMI menus via an optional HTTP

   server.
parent 88aa4077
...@@ -2,5 +2,6 @@ SOURCES_dvb = \ ...@@ -2,5 +2,6 @@ SOURCES_dvb = \
access.c \ access.c \
linux_dvb.c \ linux_dvb.c \
en50221.c \ en50221.c \
http.c \
dvb.h \ dvb.h \
$(NULL) $(NULL)
/***************************************************************************** /*****************************************************************************
* access.c: DVB card input v4l2 only * access.c: DVB card input v4l2 only
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2004 the VideoLAN team * Copyright (C) 1998-2005 the VideoLAN team
* *
* Authors: Johan Bilien <jobi@via.ecp.fr> * Authors: Johan Bilien <jobi@via.ecp.fr>
* Jean-Paul Saman <jpsaman@wxs.nl> * Jean-Paul Saman <jpsaman@wxs.nl>
...@@ -56,6 +56,10 @@ ...@@ -56,6 +56,10 @@
# include "psi.h" # include "psi.h"
#endif #endif
#ifdef ENABLE_HTTPD
# include "vlc_httpd.h"
#endif
#include "dvb.h" #include "dvb.h"
/***************************************************************************** /*****************************************************************************
...@@ -139,6 +143,40 @@ static void Close( vlc_object_t *p_this ); ...@@ -139,6 +143,40 @@ static void Close( vlc_object_t *p_this );
#define HIERARCHY_TEXT N_("Terrestrial hierarchy mode") #define HIERARCHY_TEXT N_("Terrestrial hierarchy mode")
#define HIERARCHY_LONGTEXT "" #define HIERARCHY_LONGTEXT ""
#define HOST_TEXT N_( "HTTP Host address" )
#define HOST_LONGTEXT N_( \
"To enable the internal HTTP server, set its address and port here." )
#define USER_TEXT N_( "HTTP user name" )
#define USER_LONGTEXT N_( \
"You can set the user name the administrator will use to log into " \
"the internal HTTP server." )
#define PASSWORD_TEXT N_( "HTTP password" )
#define PASSWORD_LONGTEXT N_( \
"You can set the password the administrator will use to log into " \
"the internal HTTP server." )
#define ACL_TEXT N_( "HTTP ACL" )
#define ACL_LONGTEXT N_( \
"You can set the access control list (equivalent to .hosts) file path, " \
"which will limit the range of IPs entitled to log into the internal " \
"HTTP server." )
#define CERT_TEXT N_( "Certificate file" )
#define CERT_LONGTEXT N_( "HTTP interface x509 PEM certificate file " \
"(enables SSL)" )
#define KEY_TEXT N_( "Private key file" )
#define KEY_LONGTEXT N_( "HTTP interface x509 PEM private key file" )
#define CA_TEXT N_( "Root CA file" )
#define CA_LONGTEXT N_( "HTTP interface x509 PEM trusted root CA " \
"certificates file" )
#define CRL_TEXT N_( "CRL file" )
#define CRL_LONGTEXT N_( "HTTP interface Certificates Revocation List file" )
vlc_module_begin(); vlc_module_begin();
set_shortname( _("DVB") ); set_shortname( _("DVB") );
set_description( N_("DVB input with v4l2 support") ); set_description( N_("DVB input with v4l2 support") );
...@@ -191,6 +229,26 @@ vlc_module_begin(); ...@@ -191,6 +229,26 @@ vlc_module_begin();
TRANSMISSION_LONGTEXT, VLC_TRUE ); TRANSMISSION_LONGTEXT, VLC_TRUE );
add_integer( "dvb-hierarchy", 0, NULL, HIERARCHY_TEXT, HIERARCHY_LONGTEXT, add_integer( "dvb-hierarchy", 0, NULL, HIERARCHY_TEXT, HIERARCHY_LONGTEXT,
VLC_TRUE ); VLC_TRUE );
#ifdef ENABLE_HTTPD
/* MMI HTTP interface */
set_section( N_("HTTP server" ), 0 );
add_string( "dvb-http-host", NULL, NULL, HOST_TEXT, HOST_LONGTEXT,
VLC_TRUE );
add_string( "dvb-http-user", NULL, NULL, USER_TEXT, USER_LONGTEXT,
VLC_TRUE );
add_string( "dvb-http-password", NULL, NULL, PASSWORD_TEXT,
PASSWORD_LONGTEXT, VLC_TRUE );
add_string( "dvb-http-acl", NULL, NULL, ACL_TEXT, ACL_LONGTEXT,
VLC_TRUE );
add_string( "dvb-http-intf-cert", NULL, NULL, CERT_TEXT, CERT_LONGTEXT,
VLC_TRUE );
add_string( "dvb-http-intf-key", NULL, NULL, KEY_TEXT, KEY_LONGTEXT,
VLC_TRUE );
add_string( "dvb-http-intf-ca", NULL, NULL, CA_TEXT, CA_LONGTEXT,
VLC_TRUE );
add_string( "dvb-http-intf-crl", NULL, NULL, CRL_TEXT, CRL_LONGTEXT,
VLC_TRUE );
#endif
set_capability( "access2", 0 ); set_capability( "access2", 0 );
add_shortcut( "dvb" ); add_shortcut( "dvb" );
...@@ -303,6 +361,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -303,6 +361,10 @@ static int Open( vlc_object_t *p_this )
else else
p_sys->i_read_once = DVB_READ_ONCE_START; p_sys->i_read_once = DVB_READ_ONCE_START;
#ifdef ENABLE_HTTPD
E_(HTTPOpen)( p_access );
#endif
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -320,6 +382,10 @@ static void Close( vlc_object_t *p_this ) ...@@ -320,6 +382,10 @@ static void Close( vlc_object_t *p_this )
E_(FrontendClose)( p_access ); E_(FrontendClose)( p_access );
E_(CAMClose)( p_access ); E_(CAMClose)( p_access );
#ifdef ENABLE_HTTPD
E_(HTTPClose)( p_access );
#endif
free( p_sys ); free( p_sys );
} }
...@@ -376,6 +442,37 @@ static block_t *Block( access_t *p_access ) ...@@ -376,6 +442,37 @@ static block_t *Block( access_t *p_access )
E_(FrontendPoll)( p_access ); E_(FrontendPoll)( p_access );
} }
#ifdef ENABLE_HTTPD
if ( p_sys->i_httpd_timeout && mdate() > p_sys->i_httpd_timeout )
{
vlc_mutex_lock( &p_sys->httpd_mutex );
if ( p_sys->b_request_frontend_info )
{
msg_Warn( p_access, "frontend timeout for HTTP interface" );
p_sys->b_request_frontend_info = VLC_FALSE;
p_sys->psz_frontend_info = strdup( "Timeout getting info\n" );
}
if ( p_sys->b_request_mmi_info )
{
msg_Warn( p_access, "MMI timeout for HTTP interface" );
p_sys->b_request_mmi_info = VLC_FALSE;
p_sys->psz_mmi_info = strdup( "Timeout getting info\n" );
}
vlc_cond_signal( &p_sys->httpd_cond );
vlc_mutex_unlock( &p_sys->httpd_mutex );
}
if ( p_sys->b_request_frontend_info )
{
E_(FrontendStatus)( p_access );
}
if ( p_sys->b_request_mmi_info )
{
E_(CAMStatus)( p_access );
}
#endif
if ( p_sys->i_frontend_timeout && mdate() > p_sys->i_frontend_timeout ) if ( p_sys->i_frontend_timeout && mdate() > p_sys->i_frontend_timeout )
{ {
msg_Warn( p_access, "no lock, tuning again" ); msg_Warn( p_access, "no lock, tuning again" );
...@@ -577,6 +674,17 @@ static void VarInit( access_t *p_access ) ...@@ -577,6 +674,17 @@ static void VarInit( access_t *p_access )
var_Create( p_access, "dvb-transmission", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_access, "dvb-transmission", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Create( p_access, "dvb-guard", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_access, "dvb-guard", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Create( p_access, "dvb-hierarchy", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_access, "dvb-hierarchy", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
#ifdef ENABLE_HTTPD
var_Create( p_access, "dvb-http-host", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_access, "dvb-http-user", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_access, "dvb-http-password", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_access, "dvb-http-acl", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_access, "dvb-http-intf-cert", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_access, "dvb-http-intf-key", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_access, "dvb-http-intf-ca", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_access, "dvb-http-intf-crl", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
#endif
} }
/* */ /* */
......
/***************************************************************************** /*****************************************************************************
* dvb.h : functions to control a DVB card under Linux with v4l2 * dvb.h : functions to control a DVB card under Linux with v4l2
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2004 the VideoLAN team * Copyright (C) 1998-2005 the VideoLAN team
* *
* Authors: Johan Bilien <jobi@via.ecp.fr> * Authors: Johan Bilien <jobi@via.ecp.fr>
* Jean-Paul Saman <jpsaman@saman> * Jean-Paul Saman <jpsaman@saman>
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
/***************************************************************************** /*****************************************************************************
* Local structures * Local structures
*****************************************************************************/ *****************************************************************************/
typedef struct typedef struct demux_handle_t
{ {
int i_pid; int i_pid;
int i_handle; int i_handle;
...@@ -44,7 +44,7 @@ typedef struct ...@@ -44,7 +44,7 @@ typedef struct
typedef struct frontend_t frontend_t; typedef struct frontend_t frontend_t;
typedef struct typedef struct en50221_session_t
{ {
int i_slot; int i_slot;
int i_resource_id; int i_resource_id;
...@@ -54,6 +54,84 @@ typedef struct ...@@ -54,6 +54,84 @@ typedef struct
void *p_sys; void *p_sys;
} en50221_session_t; } 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
{
vlc_bool_t b_blind;
char *psz_text;
} enq;
struct
{
vlc_bool_t 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;
#define FREE( x ) \
if ( x != NULL ) \
free( x );
switch ( p_object->i_object_type )
{
case EN50221_MMI_ENQ:
FREE( p_object->u.enq.psz_text );
break;
case EN50221_MMI_ANSW:
if ( p_object->u.answ.b_ok )
{
FREE( p_object->u.answ.psz_answ );
}
break;
case EN50221_MMI_MENU:
case EN50221_MMI_LIST:
FREE( p_object->u.menu.psz_title );
FREE( p_object->u.menu.psz_subtitle );
FREE( 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] );
}
FREE( p_object->u.menu.ppsz_choices );
break;
default:
break;
}
#undef FREE
}
#define MAX_DEMUX 256 #define MAX_DEMUX 256
#define MAX_CI_SLOTS 16 #define MAX_CI_SLOTS 16
#define MAX_SESSIONS 32 #define MAX_SESSIONS 32
...@@ -72,6 +150,8 @@ struct access_sys_t ...@@ -72,6 +150,8 @@ struct access_sys_t
int i_nb_slots; int i_nb_slots;
vlc_bool_t pb_active_slot[MAX_CI_SLOTS]; vlc_bool_t pb_active_slot[MAX_CI_SLOTS];
vlc_bool_t pb_tc_has_data[MAX_CI_SLOTS]; vlc_bool_t pb_tc_has_data[MAX_CI_SLOTS];
vlc_bool_t pb_slot_mmi_expected[MAX_CI_SLOTS];
vlc_bool_t pb_slot_mmi_undisplayed[MAX_CI_SLOTS];
en50221_session_t p_sessions[MAX_SESSIONS]; en50221_session_t p_sessions[MAX_SESSIONS];
mtime_t i_ca_timeout, i_ca_next_event, i_frontend_timeout; mtime_t i_ca_timeout, i_ca_next_event, i_frontend_timeout;
dvbpsi_pmt_t *pp_selected_programs[MAX_PROGRAMS]; dvbpsi_pmt_t *pp_selected_programs[MAX_PROGRAMS];
...@@ -79,6 +159,20 @@ struct access_sys_t ...@@ -79,6 +159,20 @@ struct access_sys_t
/* */ /* */
int i_read_once; int i_read_once;
#ifdef ENABLE_HTTPD
/* Local HTTP server */
httpd_host_t *p_httpd_host;
httpd_file_sys_t *p_httpd_file;
httpd_redirect_t *p_httpd_redir;
vlc_mutex_t httpd_mutex;
vlc_cond_t httpd_cond;
mtime_t i_httpd_timeout;
vlc_bool_t b_request_frontend_info, b_request_mmi_info;
char *psz_frontend_info, *psz_mmi_info;
char *psz_request;
#endif
}; };
#define VIDEO0_TYPE 1 #define VIDEO0_TYPE 1
...@@ -96,6 +190,9 @@ int E_(FrontendOpen)( access_t * ); ...@@ -96,6 +190,9 @@ int E_(FrontendOpen)( access_t * );
void E_(FrontendPoll)( access_t *p_access ); void E_(FrontendPoll)( access_t *p_access );
int E_(FrontendSet)( access_t * ); int E_(FrontendSet)( access_t * );
void E_(FrontendClose)( access_t * ); void E_(FrontendClose)( access_t * );
#ifdef ENABLE_HTTPD
void E_(FrontendStatus)( access_t * );
#endif
int E_(DMXSetFilter)( access_t *, int i_pid, int * pi_fd, int i_type ); int E_(DMXSetFilter)( access_t *, int i_pid, int * pi_fd, int i_type );
int E_(DMXUnsetFilter)( access_t *, int i_fd ); int E_(DMXUnsetFilter)( access_t *, int i_fd );
...@@ -107,9 +204,25 @@ int E_(CAMOpen)( access_t * ); ...@@ -107,9 +204,25 @@ int E_(CAMOpen)( access_t * );
int E_(CAMPoll)( access_t * ); int E_(CAMPoll)( access_t * );
int E_(CAMSet)( access_t *, dvbpsi_pmt_t * ); int E_(CAMSet)( access_t *, dvbpsi_pmt_t * );
void E_(CAMClose)( access_t * ); void E_(CAMClose)( access_t * );
#ifdef ENABLE_HTTPD
void E_(CAMStatus)( access_t * );
#endif
int E_(en50221_Init)( access_t * ); int E_(en50221_Init)( access_t * );
int E_(en50221_Poll)( access_t * ); int E_(en50221_Poll)( access_t * );
int E_(en50221_SetCAPMT)( access_t *, dvbpsi_pmt_t * ); int E_(en50221_SetCAPMT)( access_t *, dvbpsi_pmt_t * );
int E_(en50221_OpenMMI)( access_t * p_access, int i_slot );
int E_(en50221_CloseMMI)( access_t * p_access, int i_slot );
en50221_mmi_object_t *E_(en50221_GetMMIObject)( access_t * p_access,
int i_slot );
void E_(en50221_SendMMIObject)( access_t * p_access, int i_slot,
en50221_mmi_object_t *p_object );
void E_(en50221_End)( access_t * ); void E_(en50221_End)( access_t * );
#ifdef ENABLE_HTTPD
int E_(HTTPOpen)( access_t *p_access );
void E_(HTTPClose)( access_t *p_access );
char *E_(HTTPExtractValue)( char *psz_uri, const char *psz_name,
char *psz_value, int i_value_max );
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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