Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
23f5aa02
Commit
23f5aa02
authored
Dec 27, 2005
by
Christophe Massiot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* modules/access/dvb: Full support for DVB MMI menus via an optional HTTP
server.
parent
88aa4077
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1479 additions
and
56 deletions
+1479
-56
modules/access/dvb/Modules.am
modules/access/dvb/Modules.am
+1
-0
modules/access/dvb/access.c
modules/access/dvb/access.c
+109
-1
modules/access/dvb/dvb.h
modules/access/dvb/dvb.h
+116
-3
modules/access/dvb/en50221.c
modules/access/dvb/en50221.c
+469
-42
modules/access/dvb/http.c
modules/access/dvb/http.c
+366
-0
modules/access/dvb/linux_dvb.c
modules/access/dvb/linux_dvb.c
+418
-10
No files found.
modules/access/dvb/Modules.am
View file @
23f5aa02
...
...
@@ -2,5 +2,6 @@ SOURCES_dvb = \
access.c \
linux_dvb.c \
en50221.c \
http.c \
dvb.h \
$(NULL)
modules/access/dvb/access.c
View file @
23f5aa02
/*****************************************************************************
* access.c: DVB card input v4l2 only
*****************************************************************************
* Copyright (C) 1998-200
4
the VideoLAN team
* Copyright (C) 1998-200
5
the VideoLAN team
*
* Authors: Johan Bilien <jobi@via.ecp.fr>
* Jean-Paul Saman <jpsaman@wxs.nl>
...
...
@@ -56,6 +56,10 @@
# include "psi.h"
#endif
#ifdef ENABLE_HTTPD
# include "vlc_httpd.h"
#endif
#include "dvb.h"
/*****************************************************************************
...
...
@@ -139,6 +143,40 @@ static void Close( vlc_object_t *p_this );
#define HIERARCHY_TEXT N_("Terrestrial hierarchy mode")
#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
();
set_shortname
(
_
(
"DVB"
)
);
set_description
(
N_
(
"DVB input with v4l2 support"
)
);
...
...
@@ -191,6 +229,26 @@ vlc_module_begin();
TRANSMISSION_LONGTEXT
,
VLC_TRUE
);
add_integer
(
"dvb-hierarchy"
,
0
,
NULL
,
HIERARCHY_TEXT
,
HIERARCHY_LONGTEXT
,
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
);
add_shortcut
(
"dvb"
);
...
...
@@ -303,6 +361,10 @@ static int Open( vlc_object_t *p_this )
else
p_sys
->
i_read_once
=
DVB_READ_ONCE_START
;
#ifdef ENABLE_HTTPD
E_
(
HTTPOpen
)(
p_access
);
#endif
return
VLC_SUCCESS
;
}
...
...
@@ -320,6 +382,10 @@ static void Close( vlc_object_t *p_this )
E_
(
FrontendClose
)(
p_access
);
E_
(
CAMClose
)(
p_access
);
#ifdef ENABLE_HTTPD
E_
(
HTTPClose
)(
p_access
);
#endif
free
(
p_sys
);
}
...
...
@@ -376,6 +442,37 @@ static block_t *Block( access_t *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
)
{
msg_Warn
(
p_access
,
"no lock, tuning again"
);
...
...
@@ -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-guard"
,
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
}
/* */
...
...
modules/access/dvb/dvb.h
View file @
23f5aa02
/*****************************************************************************
* dvb.h : functions to control a DVB card under Linux with v4l2
*****************************************************************************
* Copyright (C) 1998-200
4
the VideoLAN team
* Copyright (C) 1998-200
5
the VideoLAN team
*
* Authors: Johan Bilien <jobi@via.ecp.fr>
* Jean-Paul Saman <jpsaman@saman>
...
...
@@ -35,7 +35,7 @@
/*****************************************************************************
* Local structures
*****************************************************************************/
typedef
struct
typedef
struct
demux_handle_t
{
int
i_pid
;
int
i_handle
;
...
...
@@ -44,7 +44,7 @@ typedef struct
typedef
struct
frontend_t
frontend_t
;
typedef
struct
typedef
struct
en50221_session_t
{
int
i_slot
;
int
i_resource_id
;
...
...
@@ -54,6 +54,84 @@ typedef struct
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
{
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_CI_SLOTS 16
#define MAX_SESSIONS 32
...
...
@@ -72,6 +150,8 @@ struct access_sys_t
int
i_nb_slots
;
vlc_bool_t
pb_active_slot
[
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
];
mtime_t
i_ca_timeout
,
i_ca_next_event
,
i_frontend_timeout
;
dvbpsi_pmt_t
*
pp_selected_programs
[
MAX_PROGRAMS
];
...
...
@@ -79,6 +159,20 @@ struct access_sys_t
/* */
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
...
...
@@ -96,6 +190,9 @@ int E_(FrontendOpen)( access_t * );
void
E_
(
FrontendPoll
)(
access_t
*
p_access
);
int
E_
(
FrontendSet
)(
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_
(
DMXUnsetFilter
)(
access_t
*
,
int
i_fd
);
...
...
@@ -107,9 +204,25 @@ int E_(CAMOpen)( access_t * );
int
E_
(
CAMPoll
)(
access_t
*
);
int
E_
(
CAMSet
)(
access_t
*
,
dvbpsi_pmt_t
*
);
void
E_
(
CAMClose
)(
access_t
*
);
#ifdef ENABLE_HTTPD
void
E_
(
CAMStatus
)(
access_t
*
);
#endif
int
E_
(
en50221_Init
)(
access_t
*
);
int
E_
(
en50221_Poll
)(
access_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
*
);
#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
modules/access/dvb/en50221.c
View file @
23f5aa02
...
...
@@ -2,7 +2,7 @@
* en50221.c : implementation of the transport, session and applications
* layers of EN 50 221
*****************************************************************************
* Copyright (C) 2004 the VideoLAN team
* Copyright (C) 2004
-2005
the VideoLAN team
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Based on code from libdvbci Copyright (C) 2000 Klaus Schmidinger
...
...
@@ -59,6 +59,10 @@
# include "psi.h"
#endif
#ifdef ENABLE_HTTPD
# include "vlc_httpd.h"
#endif
#include "dvb.h"
#undef DEBUG_TPDU
...
...
@@ -471,6 +475,99 @@ static void SessionOpen( access_t * p_access, uint8_t i_slot,
}
}
#if 0
/* unused code for the moment - commented out to keep gcc happy */
/*****************************************************************************
* SessionCreate
*****************************************************************************/
static void SessionCreate( access_t * p_access, int i_slot, int i_resource_id )
{
access_sys_t *p_sys = p_access->p_sys;
uint8_t p_response[16];
uint8_t i_tag;
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 )
break;
}
if ( i_session_id == MAX_SESSIONS )
{
msg_Err( p_access, "too many sessions !" );
return;
}
p_sys->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_sys->p_sessions[i_session_id - 1].pf_close = NULL;
p_sys->p_sessions[i_session_id - 1].pf_manage = NULL;
p_sys->p_sessions[i_session_id - 1].p_sys = NULL;
p_response[0] = ST_CREATE_SESSION;
p_response[1] = 0x6;
p_response[2] = i_resource_id >> 24;
p_response[3] = (i_resource_id >> 16) & 0xff;
p_response[4] = (i_resource_id >> 8) & 0xff;
p_response[5] = i_resource_id & 0xff;
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 )
{
msg_Err( p_access,
"SessionCreate: couldn't send TPDU on slot %d", i_slot );
return;
}
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS )
{
msg_Err( p_access,
"SessionCreate: couldn't recv TPDU on slot %d", i_slot );
return;
}
}
#endif
/*****************************************************************************
* SessionCreateResponse
*****************************************************************************/
static
void
SessionCreateResponse
(
access_t
*
p_access
,
uint8_t
i_slot
,
uint8_t
*
p_spdu
,
int
i_size
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
i_status
=
p_spdu
[
2
];
int
i_resource_id
=
ResourceIdToInt
(
&
p_spdu
[
3
]
);
int
i_session_id
=
((
int
)
p_spdu
[
7
]
<<
8
)
|
p_spdu
[
8
];
if
(
i_status
!=
SS_OK
)
{
msg_Err
(
p_access
,
"SessionCreateResponse: failed to open session %d"
" resource=0x%x status=0x%x"
,
i_session_id
,
i_resource_id
,
i_status
);
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_resource_id
=
0
;
return
;
}
switch
(
i_resource_id
)
{
case
RI_RESOURCE_MANAGER
:
ResourceManagerOpen
(
p_access
,
i_session_id
);
break
;
case
RI_APPLICATION_INFORMATION
:
ApplicationInformationOpen
(
p_access
,
i_session_id
);
break
;
case
RI_CONDITIONAL_ACCESS_SUPPORT
:
ConditionalAccessOpen
(
p_access
,
i_session_id
);
break
;
case
RI_DATE_TIME
:
DateTimeOpen
(
p_access
,
i_session_id
);
break
;
case
RI_MMI
:
MMIOpen
(
p_access
,
i_session_id
);
break
;
case
RI_HOST_CONTROL
:
default:
msg_Err
(
p_access
,
"unknown resource id (0x%x)"
,
i_resource_id
);
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_resource_id
=
0
;
}
}
/*****************************************************************************
* SessionSendClose
*****************************************************************************/
...
...
@@ -561,20 +658,39 @@ static void SPDUHandle( access_t * p_access, uint8_t i_slot,
SessionOpen
(
p_access
,
i_slot
,
p_spdu
,
i_size
);
break
;
case
ST_CREATE_SESSION_RESPONSE
:
if
(
i_size
!=
9
||
p_spdu
[
1
]
!=
0x7
)
return
;
SessionCreateResponse
(
p_access
,
i_slot
,
p_spdu
,
i_size
);
break
;
case
ST_CLOSE_SESSION_REQUEST
:
if
(
i_size
!=
4
||
p_spdu
[
1
]
!=
0x2
)
return
;
i_session_id
=
((
int
)
p_spdu
[
2
]
<<
8
)
|
p_spdu
[
3
];
SessionClose
(
p_access
,
i_session_id
);
break
;
case
ST_CLOSE_SESSION_RESPONSE
:
i_session_id
=
((
int
)
p_spdu
[
2
]
<<
8
)
|
p_spdu
[
3
];
if
(
i_size
!=
5
||
p_spdu
[
1
]
!=
0x3
)
return
;
i_session_id
=
((
int
)
p_spdu
[
3
]
<<
8
)
|
p_spdu
[
4
];
if
(
p_spdu
[
2
]
)
{
msg_Err
(
p_access
,
"closing a session which is not allocated (%d)"
,
i_session_id
);
}
else
{
if
(
p_sys
->
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_sys
->
p_sessions
[
i_session_id
-
1
].
i_resource_id
=
0
;
}
break
;
default:
msg_Err
(
p_access
,
"unexpected tag in SPDUHandle (%x)"
,
p_spdu
[
0
]
);
break
;
}
}
...
...
@@ -675,13 +791,13 @@ static int APDUSend( access_t * p_access, int i_session_id, int i_tag,
p
=
SetLength
(
p
,
i_size
);
if
(
i_size
)
memcpy
(
p
,
p_data
,
i_size
);
if
(
p_sys
->
i_ca_type
==
CA_CI_LINK
)
if
(
p_sys
->
i_ca_type
==
CA_CI_LINK
)
{
i_ret
=
SPDUSend
(
p_access
,
i_session_id
,
p_apdu
,
i_size
+
p
-
p_apdu
);
}
else
{
if
(
i_size
+
p
-
p_apdu
>
256
)
if
(
i_size
+
p
-
p_apdu
>
256
)
{
msg_Err
(
p_access
,
"CAM: apdu overflow"
);
i_ret
=
VLC_EGENERIC
;
...
...
@@ -690,11 +806,11 @@ static int APDUSend( access_t * p_access, int i_session_id, int i_tag,
{
char
*
psz_hex
;
ca_msg
.
length
=
i_size
+
p
-
p_apdu
;
if
(
i_size
==
0
)
ca_msg
.
length
=
3
;
if
(
i_size
==
0
)
ca_msg
.
length
=
3
;
psz_hex
=
(
char
*
)
malloc
(
ca_msg
.
length
*
3
+
1
);
memcpy
(
ca_msg
.
msg
,
p_apdu
,
i_size
+
p
-
p_apdu
);
i_ret
=
ioctl
(
p_sys
->
i_ca_handle
,
CA_SEND_MSG
,
&
ca_msg
);
if
(
i_ret
<
0
)
if
(
i_ret
<
0
)
{
msg_Err
(
p_access
,
"Error sending to CAM: %s"
,
strerror
(
errno
)
);
i_ret
=
VLC_EGENERIC
;
...
...
@@ -759,6 +875,20 @@ static void ResourceManagerOpen( access_t * p_access, int i_session_id )
* Application Information
*/
/*****************************************************************************
* ApplicationInformationEnterMenu
*****************************************************************************/
static
void
ApplicationInformationEnterMenu
(
access_t
*
p_access
,
int
i_session_id
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
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
);
APDUSend
(
p_access
,
i_session_id
,
AOT_ENTER_MENU
,
NULL
,
0
);
p_sys
->
pb_slot_mmi_expected
[
i_slot
]
=
VLC_TRUE
;
}
/*****************************************************************************
* ApplicationInformationHandle
*****************************************************************************/
...
...
@@ -1190,6 +1320,18 @@ static void ConditionalAccessHandle( access_t * p_access, int i_session_id,
}
}
/*****************************************************************************
* ConditionalAccessClose
*****************************************************************************/
static
void
ConditionalAccessClose
(
access_t
*
p_access
,
int
i_session_id
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
msg_Dbg
(
p_access
,
"closing ConditionalAccess session (%d)"
,
i_session_id
);
free
(
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
);
}
/*****************************************************************************
* ConditionalAccessOpen
*****************************************************************************/
...
...
@@ -1200,6 +1342,7 @@ static void ConditionalAccessOpen( access_t * p_access, int i_session_id )
msg_Dbg
(
p_access
,
"opening ConditionalAccess session (%d)"
,
i_session_id
);
p_sys
->
p_sessions
[
i_session_id
-
1
].
pf_handle
=
ConditionalAccessHandle
;
p_sys
->
p_sessions
[
i_session_id
-
1
].
pf_close
=
ConditionalAccessClose
;
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
=
malloc
(
sizeof
(
system_ids_t
));
memset
(
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
,
0
,
sizeof
(
system_ids_t
)
);
...
...
@@ -1308,6 +1451,18 @@ static void DateTimeManage( access_t * p_access, int i_session_id )
}
}
/*****************************************************************************
* DateTimeClose
*****************************************************************************/
static
void
DateTimeClose
(
access_t
*
p_access
,
int
i_session_id
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
msg_Dbg
(
p_access
,
"closing DateTime session (%d)"
,
i_session_id
);
free
(
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
);
}
/*****************************************************************************
* DateTimeOpen
*****************************************************************************/
...
...
@@ -1319,6 +1474,7 @@ static void DateTimeOpen( access_t * p_access, int i_session_id )
p_sys
->
p_sessions
[
i_session_id
-
1
].
pf_handle
=
DateTimeHandle
;
p_sys
->
p_sessions
[
i_session_id
-
1
].
pf_manage
=
DateTimeManage
;
p_sys
->
p_sessions
[
i_session_id
-
1
].
pf_close
=
DateTimeClose
;
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
=
malloc
(
sizeof
(
date_time_t
));
memset
(
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
,
0
,
sizeof
(
date_time_t
)
);
...
...
@@ -1363,6 +1519,63 @@ static void DateTimeOpen( access_t * p_access, int i_session_id )
#define AI_CANCEL 0x00
#define AI_ANSWER 0x01
typedef
struct
{
en50221_mmi_object_t
last_object
;
}
mmi_t
;
/*****************************************************************************
* MMISendObject
*****************************************************************************/
static
void
MMISendObject
(
access_t
*
p_access
,
int
i_session_id
,
en50221_mmi_object_t
*
p_object
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
i_slot
=
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
;
uint8_t
*
p_data
;
int
i_size
,
i_tag
;
switch
(
p_object
->
i_object_type
)
{
case
EN50221_MMI_ANSW
:
i_tag
=
AOT_ANSW
;
i_size
=
1
+
strlen
(
p_object
->
u
.
answ
.
psz_answ
);
p_data
=
malloc
(
i_size
);
p_data
[
0
]
=
(
p_object
->
u
.
answ
.
b_ok
==
VLC_TRUE
)
?
0x1
:
0x0
;
strncpy
(
&
p_data
[
1
],
p_object
->
u
.
answ
.
psz_answ
,
i_size
-
1
);
break
;
case
EN50221_MMI_MENU_ANSW
:
i_tag
=
AOT_MENU_ANSW
;
i_size
=
1
;
p_data
=
malloc
(
i_size
);
p_data
[
0
]
=
p_object
->
u
.
menu_answ
.
i_choice
;
break
;
default:
msg_Err
(
p_access
,
"unknown MMI object %d"
,
p_object
->
i_object_type
);
return
;
}
APDUSend
(
p_access
,
i_session_id
,
i_tag
,
p_data
,
i_size
);
free
(
p_data
);
p_sys
->
pb_slot_mmi_expected
[
i_slot
]
=
VLC_TRUE
;
}
/*****************************************************************************
* MMISendClose
*****************************************************************************/
static
void
MMISendClose
(
access_t
*
p_access
,
int
i_session_id
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
i_slot
=
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
;
APDUSend
(
p_access
,
i_session_id
,
AOT_CLOSE_MMI
,
NULL
,
0
);
p_sys
->
pb_slot_mmi_expected
[
i_slot
]
=
VLC_TRUE
;
}
/*****************************************************************************
* MMIDisplayReply
*****************************************************************************/
...
...
@@ -1381,22 +1594,22 @@ static void MMIDisplayReply( access_t *p_access, int i_session_id )
/*****************************************************************************
* MMIGetText
*****************************************************************************/
static
char
*
MMIGetText
(
access_t
*
p_access
,
char
*
psz_text
,
uint8_t
**
pp_apdu
,
int
*
pi_size
)
static
char
*
MMIGetText
(
access_t
*
p_access
,
uint8_t
**
pp_apdu
,
int
*
pi_size
)
{
int
i_tag
=
APDUGetTag
(
*
pp_apdu
,
*
pi_size
);
char
*
psz_text
;
int
l
;
uint8_t
*
d
;
if
(
i_tag
!=
AOT_TEXT_LAST
)
{
msg_Err
(
p_access
,
"unexpected text tag: %06x"
,
i_tag
);
psz_text
[
0
]
=
'\0'
;
*
pi_size
=
0
;
return
psz_text
;
return
strdup
(
""
)
;
}
d
=
APDUGetLength
(
*
pp_apdu
,
&
l
);
psz_text
=
malloc
(
l
+
1
);
strncpy
(
psz_text
,
(
char
*
)
d
,
l
);
psz_text
[
l
]
=
'\0'
;
...
...
@@ -1405,6 +1618,82 @@ static char *MMIGetText( access_t *p_access, char *psz_text,
return
psz_text
;
}
/*****************************************************************************
* MMIHandleEnq
*****************************************************************************/
static
void
MMIHandleEnq
(
access_t
*
p_access
,
int
i_session_id
,
uint8_t
*
p_apdu
,
int
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
;
int
i_slot
=
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
;
int
l
;
uint8_t
*
d
=
APDUGetLength
(
p_apdu
,
&
l
);
en50221_MMIFree
(
&
p_mmi
->
last_object
);
p_mmi
->
last_object
.
i_object_type
=
EN50221_MMI_ENQ
;
p_mmi
->
last_object
.
u
.
enq
.
b_blind
=
(
*
d
&
0x1
)
?
VLC_TRUE
:
VLC_FALSE
;
d
+=
2
;
/* skip answer_text_length because it is not mandatory */
l
-=
2
;
p_mmi
->
last_object
.
u
.
enq
.
psz_text
=
malloc
(
l
+
1
);
strncpy
(
p_mmi
->
last_object
.
u
.
enq
.
psz_text
,
(
char
*
)
d
,
l
);
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
,
p_mmi
->
last_object
.
u
.
enq
.
b_blind
==
VLC_TRUE
?
" (blind)"
:
""
);
p_sys
->
pb_slot_mmi_expected
[
i_slot
]
=
VLC_FALSE
;
p_sys
->
pb_slot_mmi_undisplayed
[
i_slot
]
=
VLC_TRUE
;
}
/*****************************************************************************
* MMIHandleMenu
*****************************************************************************/
static
void
MMIHandleMenu
(
access_t
*
p_access
,
int
i_session_id
,
int
i_tag
,
uint8_t
*
p_apdu
,
int
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
;
int
i_slot
=
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
;
int
l
;
uint8_t
*
d
=
APDUGetLength
(
p_apdu
,
&
l
);
en50221_MMIFree
(
&
p_mmi
->
last_object
);
p_mmi
->
last_object
.
i_object_type
=
(
i_tag
==
AOT_MENU_LAST
)
?
EN50221_MMI_MENU
:
EN50221_MMI_LIST
;
p_mmi
->
last_object
.
u
.
menu
.
i_choices
=
0
;
p_mmi
->
last_object
.
u
.
menu
.
ppsz_choices
=
NULL
;
if
(
l
>
0
)
{
l
--
;
d
++
;
/* choice_nb */
#define GET_FIELD( x ) \
if ( l > 0 ) \
{ \
p_mmi->last_object.u.menu.psz_##x \
= MMIGetText( p_access, &d, &l ); \
msg_Dbg( p_access, "MMI " STRINGIFY( x ) ": %s", \
p_mmi->last_object.u.menu.psz_##x ); \
}
GET_FIELD
(
title
);
GET_FIELD
(
subtitle
);
GET_FIELD
(
bottom
);
#undef GET_FIELD
while
(
l
>
0
)
{
char
*
psz_text
=
MMIGetText
(
p_access
,
&
d
,
&
l
);
TAB_APPEND
(
p_mmi
->
last_object
.
u
.
menu
.
i_choices
,
p_mmi
->
last_object
.
u
.
menu
.
ppsz_choices
,
psz_text
);
msg_Dbg
(
p_access
,
"MMI choice: %s"
,
psz_text
);
}
}
p_sys
->
pb_slot_mmi_expected
[
i_slot
]
=
VLC_FALSE
;
p_sys
->
pb_slot_mmi_undisplayed
[
i_slot
]
=
VLC_TRUE
;
}
/*****************************************************************************
* MMIHandle
*****************************************************************************/
...
...
@@ -1440,38 +1729,17 @@ static void MMIHandle( access_t *p_access, int i_session_id,
break
;
}
case
AOT_ENQ
:
MMIHandleEnq
(
p_access
,
i_session_id
,
p_apdu
,
i_size
);
break
;
case
AOT_LIST_LAST
:
case
AOT_MENU_LAST
:
{
int
l
;
uint8_t
*
d
=
APDUGetLength
(
p_apdu
,
&
l
);
char
psz_text
[
255
];
if
(
l
>
0
)
{
l
--
;
d
++
;
/* choice_nb */
if
(
l
>
0
)
msg_Info
(
p_access
,
"MMI title: %s"
,
MMIGetText
(
p_access
,
psz_text
,
&
d
,
&
l
)
);
if
(
l
>
0
)
msg_Info
(
p_access
,
"MMI subtitle: %s"
,
MMIGetText
(
p_access
,
psz_text
,
&
d
,
&
l
)
);
if
(
l
>
0
)
msg_Info
(
p_access
,
"MMI bottom: %s"
,
MMIGetText
(
p_access
,
psz_text
,
&
d
,
&
l
)
);
while
(
l
>
0
)
{
msg_Info
(
p_access
,
"MMI: %s"
,
MMIGetText
(
p_access
,
psz_text
,
&
d
,
&
l
)
);
}
}
MMIHandleMenu
(
p_access
,
i_session_id
,
i_tag
,
p_apdu
,
i_size
);
break
;
}
case
AOT_CLOSE_MMI
:
SessionSendClose
(
p_access
,
i_session_id
);
msg_Dbg
(
p_access
,
"closing MMI session (%d)"
,
i_session_id
);
break
;
default:
...
...
@@ -1479,16 +1747,38 @@ static void MMIHandle( access_t *p_access, int i_session_id,
}
}
/*****************************************************************************
* MMIClose
*****************************************************************************/
static
void
MMIClose
(
access_t
*
p_access
,
int
i_session_id
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
i_slot
=
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
;
mmi_t
*
p_mmi
=
(
mmi_t
*
)
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
;
en50221_MMIFree
(
&
p_mmi
->
last_object
);
free
(
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
);
msg_Dbg
(
p_access
,
"closing MMI session (%d)"
,
i_session_id
);
p_sys
->
pb_slot_mmi_expected
[
i_slot
]
=
VLC_FALSE
;
p_sys
->
pb_slot_mmi_undisplayed
[
i_slot
]
=
VLC_TRUE
;
}
/*****************************************************************************
* MMIOpen
*****************************************************************************/
static
void
MMIOpen
(
access_t
*
p_access
,
int
i_session_id
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
mmi_t
*
p_mmi
;
msg_Dbg
(
p_access
,
"opening MMI session (%d)"
,
i_session_id
);
p_sys
->
p_sessions
[
i_session_id
-
1
].
pf_handle
=
MMIHandle
;
p_sys
->
p_sessions
[
i_session_id
-
1
].
pf_close
=
MMIClose
;
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
=
malloc
(
sizeof
(
mmi_t
));
p_mmi
=
(
mmi_t
*
)
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
;
p_mmi
->
last_object
.
i_object_type
=
EN50221_MMI_NONE
;
}
...
...
@@ -1824,13 +2114,138 @@ int E_(en50221_SetCAPMT)( access_t * p_access, dvbpsi_pmt_t *p_pmt )
return
VLC_SUCCESS
;
}
/*****************************************************************************
* en50221_OpenMMI :
*****************************************************************************/
int
E_
(
en50221_OpenMMI
)(
access_t
*
p_access
,
int
i_slot
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
if
(
p_sys
->
i_ca_type
&
CA_CI_LINK
)
{
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
&&
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
==
i_slot
)
{
msg_Dbg
(
p_access
,
"MMI menu is already opened on slot %d (session=%d)"
,
i_slot
,
i_session_id
);
return
VLC_SUCCESS
;
}
}
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_APPLICATION_INFORMATION
&&
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
==
i_slot
)
{
ApplicationInformationEnterMenu
(
p_access
,
i_session_id
);
return
VLC_SUCCESS
;
}
}
msg_Err
(
p_access
,
"no application information on slot %d"
,
i_slot
);
return
VLC_EGENERIC
;
}
else
{
msg_Err
(
p_access
,
"MMI menu not supported"
);
return
VLC_EGENERIC
;
}
}
/*****************************************************************************
* en50221_CloseMMI :
*****************************************************************************/
int
E_
(
en50221_CloseMMI
)(
access_t
*
p_access
,
int
i_slot
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
if
(
p_sys
->
i_ca_type
&
CA_CI_LINK
)
{
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
&&
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
==
i_slot
)
{
MMISendClose
(
p_access
,
i_session_id
);
return
VLC_SUCCESS
;
}
}
msg_Warn
(
p_access
,
"closing a non-existing MMI session on slot %d"
,
i_slot
);
return
VLC_EGENERIC
;
}
else
{
msg_Err
(
p_access
,
"MMI menu not supported"
);
return
VLC_EGENERIC
;
}
}
/*****************************************************************************
* en50221_GetMMIObject :
*****************************************************************************/
en50221_mmi_object_t
*
E_
(
en50221_GetMMIObject
)(
access_t
*
p_access
,
int
i_slot
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
i_session_id
;
if
(
p_sys
->
pb_slot_mmi_expected
[
i_slot
]
==
VLC_TRUE
)
return
NULL
;
/* should not happen */
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
&&
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
==
i_slot
)
{
mmi_t
*
p_mmi
=
(
mmi_t
*
)
p_sys
->
p_sessions
[
i_session_id
-
1
].
p_sys
;
if
(
p_mmi
==
NULL
)
return
NULL
;
/* should not happen */
return
&
p_mmi
->
last_object
;
}
}
return
NULL
;
}
/*****************************************************************************
* en50221_SendMMIObject :
*****************************************************************************/
void
E_
(
en50221_SendMMIObject
)(
access_t
*
p_access
,
int
i_slot
,
en50221_mmi_object_t
*
p_object
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
i_session_id
;
for
(
i_session_id
=
1
;
i_session_id
<=
MAX_SESSIONS
;
i_session_id
++
)
{
if
(
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_resource_id
==
RI_MMI
&&
p_sys
->
p_sessions
[
i_session_id
-
1
].
i_slot
==
i_slot
)
{
MMISendObject
(
p_access
,
i_session_id
,
p_object
);
return
;
}
}
msg_Err
(
p_access
,
"SendMMIObject when no MMI session is opened !"
);
}
/*****************************************************************************
* en50221_End :
*****************************************************************************/
void
E_
(
en50221_End
)(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
i
;
int
i
_session_id
,
i
;
for
(
i
=
0
;
i
<
MAX_PROGRAMS
;
i
++
)
{
...
...
@@ -1840,5 +2255,17 @@ void E_(en50221_End)( access_t * p_access )
}
}
/* TODO */
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
&&
p_sys
->
p_sessions
[
i_session_id
-
1
].
pf_close
!=
NULL
)
{
p_sys
->
p_sessions
[
i_session_id
-
1
].
pf_close
(
p_access
,
i_session_id
);
}
}
/* Leave the CAM configured, so that it can be reused in another
* program. */
}
modules/access/dvb/http.c
0 → 100644
View file @
23f5aa02
/*****************************************************************************
* http.c: HTTP interface
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/input.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <errno.h>
/* Include dvbpsi headers */
#ifdef HAVE_DVBPSI_DR_H
# include <dvbpsi/dvbpsi.h>
# include <dvbpsi/descriptor.h>
# include <dvbpsi/pat.h>
# include <dvbpsi/pmt.h>
# include <dvbpsi/dr.h>
# include <dvbpsi/psi.h>
#else
# include "dvbpsi.h"
# include "descriptor.h"
# include "tables/pat.h"
# include "tables/pmt.h"
# include "descriptors/dr.h"
# include "psi.h"
#endif
#ifdef ENABLE_HTTPD
# include "vlc_httpd.h"
# include "vlc_acl.h"
#endif
#include "dvb.h"
#ifdef ENABLE_HTTPD
struct
httpd_file_sys_t
{
access_t
*
p_access
;
httpd_file_t
*
p_file
;
};
static
int
HttpCallback
(
httpd_file_sys_t
*
p_args
,
httpd_file_t
*
p_file
,
uint8_t
*
_p_request
,
uint8_t
**
_pp_data
,
int
*
pi_data
);
/*****************************************************************************
* HTTPOpen: Start the internal HTTP server
*****************************************************************************/
int
E_
(
HTTPOpen
)(
access_t
*
p_access
)
{
#define FREE( x ) \
if ( (x) != NULL ) \
free( x );
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
char
*
psz_address
,
*
psz_cert
=
NULL
,
*
psz_key
=
NULL
,
*
psz_ca
=
NULL
,
*
psz_crl
=
NULL
,
*
psz_user
=
NULL
,
*
psz_password
=
NULL
,
*
psz_acl
=
NULL
;
int
i_port
=
0
;
char
psz_tmp
[
10
];
vlc_acl_t
*
p_acl
=
NULL
;
httpd_file_sys_t
*
f
;
vlc_mutex_init
(
p_access
,
&
p_sys
->
httpd_mutex
);
vlc_cond_init
(
p_access
,
&
p_sys
->
httpd_cond
);
p_sys
->
b_request_frontend_info
=
p_sys
->
b_request_mmi_info
=
VLC_FALSE
;
p_sys
->
i_httpd_timeout
=
0
;
psz_address
=
var_GetString
(
p_access
,
"dvb-http-host"
);
if
(
psz_address
!=
NULL
&&
*
psz_address
)
{
char
*
psz_parser
=
strchr
(
psz_address
,
':'
);
if
(
psz_parser
)
{
*
psz_parser
++
=
'\0'
;
i_port
=
atoi
(
psz_parser
);
}
}
else
{
if
(
psz_address
!=
NULL
)
free
(
psz_address
);
return
VLC_SUCCESS
;
}
/* determine SSL configuration */
psz_cert
=
var_GetString
(
p_access
,
"dvb-http-intf-cert"
);
if
(
psz_cert
!=
NULL
&&
*
psz_cert
)
{
msg_Dbg
(
p_access
,
"enabling TLS for HTTP interface (cert file: %s)"
,
psz_cert
);
psz_key
=
config_GetPsz
(
p_access
,
"dvb-http-intf-key"
);
psz_ca
=
config_GetPsz
(
p_access
,
"dvb-http-intf-ca"
);
psz_crl
=
config_GetPsz
(
p_access
,
"dvb-http-intf-crl"
);
if
(
i_port
<=
0
)
i_port
=
8443
;
}
else
{
if
(
!*
psz_cert
)
{
free
(
psz_cert
);
psz_cert
=
NULL
;
}
if
(
i_port
<=
0
)
i_port
=
8082
;
}
/* Ugly hack to allow to run several HTTP servers on different ports. */
sprintf
(
psz_tmp
,
":%d"
,
i_port
+
1
);
config_PutPsz
(
p_access
,
"dvb-http-host"
,
psz_tmp
);
msg_Dbg
(
p_access
,
"base %s:%d"
,
psz_address
,
i_port
);
p_sys
->
p_httpd_host
=
httpd_TLSHostNew
(
VLC_OBJECT
(
p_access
),
psz_address
,
i_port
,
psz_cert
,
psz_key
,
psz_ca
,
psz_crl
);
FREE
(
psz_cert
);
FREE
(
psz_key
);
FREE
(
psz_ca
);
FREE
(
psz_crl
);
if
(
p_sys
->
p_httpd_host
==
NULL
)
{
msg_Err
(
p_access
,
"cannot listen on %s:%d"
,
psz_address
,
i_port
);
free
(
psz_address
);
return
VLC_EGENERIC
;
}
free
(
psz_address
);
psz_user
=
var_GetString
(
p_access
,
"dvb-http-user"
);
psz_password
=
var_GetString
(
p_access
,
"dvb-http-password"
);
psz_acl
=
var_GetString
(
p_access
,
"dvb-http-acl"
);
if
(
psz_acl
!=
NULL
)
{
p_acl
=
ACL_Create
(
p_access
,
VLC_FALSE
);
if
(
ACL_LoadFile
(
p_acl
,
psz_acl
)
)
{
ACL_Destroy
(
p_acl
);
p_acl
=
NULL
;
}
}
/* Declare an index.html file. */
f
=
malloc
(
sizeof
(
httpd_file_sys_t
)
);
f
->
p_access
=
p_access
;
f
->
p_file
=
httpd_FileNew
(
p_sys
->
p_httpd_host
,
"/index.html"
,
"text/html; charset=UTF-8"
,
psz_user
,
psz_password
,
p_acl
,
HttpCallback
,
f
);
FREE
(
psz_user
);
FREE
(
psz_password
);
FREE
(
psz_acl
);
if
(
p_acl
!=
NULL
)
ACL_Destroy
(
p_acl
);
if
(
f
->
p_file
==
NULL
)
{
free
(
f
);
p_sys
->
p_httpd_file
=
NULL
;
return
VLC_EGENERIC
;
}
p_sys
->
p_httpd_file
=
f
;
p_sys
->
p_httpd_redir
=
httpd_RedirectNew
(
p_sys
->
p_httpd_host
,
"/index.html"
,
"/"
);
#undef FREE
return
VLC_SUCCESS
;
}
/*****************************************************************************
* HTTPClose: Stop the internal HTTP server
*****************************************************************************/
void
E_
(
HTTPClose
)(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
if
(
p_sys
->
p_httpd_host
!=
NULL
)
{
if
(
p_sys
->
p_httpd_file
!=
NULL
)
{
/* Unlock the thread if it is stuck in HttpCallback */
vlc_mutex_lock
(
&
p_sys
->
httpd_mutex
);
if
(
p_sys
->
b_request_frontend_info
==
VLC_TRUE
)
{
p_sys
->
b_request_frontend_info
=
VLC_FALSE
;
p_sys
->
psz_frontend_info
=
strdup
(
""
);
}
if
(
p_sys
->
b_request_mmi_info
==
VLC_TRUE
)
{
p_sys
->
b_request_mmi_info
=
VLC_FALSE
;
p_sys
->
psz_mmi_info
=
strdup
(
""
);
}
vlc_cond_signal
(
&
p_sys
->
httpd_cond
);
vlc_mutex_unlock
(
&
p_sys
->
httpd_mutex
);
httpd_FileDelete
(
p_sys
->
p_httpd_file
->
p_file
);
httpd_RedirectDelete
(
p_sys
->
p_httpd_redir
);
}
httpd_HostDelete
(
p_sys
->
p_httpd_host
);
}
vlc_mutex_destroy
(
&
p_sys
->
httpd_mutex
);
vlc_cond_destroy
(
&
p_sys
->
httpd_cond
);
}
static
const
char
*
psz_constant_header
=
"<html>
\n
"
"<head><title>VLC DVB monitoring interface</title></head>
\n
"
"<body><a href=
\"
index.html
\"
>Reload this page</a>
\n
"
"<h1>CAM info</h1>
\n
"
;
static
const
char
*
psz_constant_middle
=
"<hr><h1>Frontend Info</h1>
\n
"
;
static
const
char
*
psz_constant_footer
=
"</body></html>
\n
"
;
/****************************************************************************
* HttpCallback: Return the index.html file
****************************************************************************/
static
int
HttpCallback
(
httpd_file_sys_t
*
p_args
,
httpd_file_t
*
p_file
,
uint8_t
*
_psz_request
,
uint8_t
**
_pp_data
,
int
*
pi_data
)
{
access_sys_t
*
p_sys
=
p_args
->
p_access
->
p_sys
;
char
*
psz_request
=
(
char
*
)
_psz_request
;
char
**
pp_data
=
(
char
**
)
_pp_data
;
vlc_mutex_lock
(
&
p_sys
->
httpd_mutex
);
p_sys
->
i_httpd_timeout
=
mdate
()
+
I64C
(
3000000
);
/* 3 s */
p_sys
->
psz_request
=
psz_request
;
p_sys
->
b_request_frontend_info
=
VLC_TRUE
;
if
(
p_sys
->
i_ca_handle
)
{
p_sys
->
b_request_mmi_info
=
VLC_TRUE
;
}
else
{
p_sys
->
psz_mmi_info
=
strdup
(
"No available CAM interface
\n
"
);
}
do
{
vlc_cond_wait
(
&
p_sys
->
httpd_cond
,
&
p_sys
->
httpd_mutex
);
}
while
(
p_sys
->
b_request_frontend_info
||
p_sys
->
b_request_mmi_info
);
p_sys
->
i_httpd_timeout
=
0
;
vlc_mutex_unlock
(
&
p_sys
->
httpd_mutex
);
*
pi_data
=
strlen
(
psz_constant_header
)
+
strlen
(
p_sys
->
psz_mmi_info
)
+
strlen
(
psz_constant_middle
)
+
strlen
(
p_sys
->
psz_frontend_info
)
+
strlen
(
psz_constant_footer
)
+
1
;
*
pp_data
=
malloc
(
*
pi_data
);
sprintf
(
*
pp_data
,
"%s%s%s%s%s"
,
psz_constant_header
,
p_sys
->
psz_mmi_info
,
psz_constant_middle
,
p_sys
->
psz_frontend_info
,
psz_constant_footer
);
free
(
p_sys
->
psz_frontend_info
);
free
(
p_sys
->
psz_mmi_info
);
return
VLC_SUCCESS
;
}
/****************************************************************************
* HTTPExtractValue: Extract a GET variable from psz_request
****************************************************************************/
char
*
E_
(
HTTPExtractValue
)(
char
*
psz_uri
,
const
char
*
psz_name
,
char
*
psz_value
,
int
i_value_max
)
{
char
*
p
=
psz_uri
;
while
(
(
p
=
strstr
(
p
,
psz_name
))
)
{
/* Verify that we are dealing with a post/get argument */
if
(
(
p
==
psz_uri
||
*
(
p
-
1
)
==
'&'
||
*
(
p
-
1
)
==
'\n'
)
&&
p
[
strlen
(
psz_name
)]
==
'='
)
break
;
p
++
;
}
if
(
p
)
{
int
i_len
;
p
+=
strlen
(
psz_name
);
if
(
*
p
==
'='
)
p
++
;
if
(
strchr
(
p
,
'&'
)
)
{
i_len
=
strchr
(
p
,
'&'
)
-
p
;
}
else
{
/* for POST method */
if
(
strchr
(
p
,
'\n'
)
)
{
i_len
=
strchr
(
p
,
'\n'
)
-
p
;
if
(
i_len
&&
*
(
p
+
i_len
-
1
)
==
'\r'
)
i_len
--
;
}
else
{
i_len
=
strlen
(
p
);
}
}
i_len
=
__MIN
(
i_value_max
-
1
,
i_len
);
if
(
i_len
>
0
)
{
strncpy
(
psz_value
,
p
,
i_len
);
psz_value
[
i_len
]
=
'\0'
;
}
else
{
strncpy
(
psz_value
,
""
,
i_value_max
);
}
p
+=
i_len
;
}
else
{
strncpy
(
psz_value
,
""
,
i_value_max
);
}
return
p
;
}
#endif
/* ENABLE_HTTPD */
modules/access/dvb/linux_dvb.c
View file @
23f5aa02
/*****************************************************************************
* linux_dvb.c : functions to control a DVB card under Linux with v4l2
*****************************************************************************
* Copyright (C) 1998-200
4
the VideoLAN team
* Copyright (C) 1998-200
5
the VideoLAN team
*
* Authors: Damien Lucas <nitrox@via.ecp.fr>
* Johan Bilien <jobi@via.ecp.fr>
...
...
@@ -61,6 +61,10 @@
# include "psi.h"
#endif
#ifdef ENABLE_HTTPD
# include "vlc_httpd.h"
#endif
#include "dvb.h"
/*
...
...
@@ -268,24 +272,24 @@ void E_(FrontendPoll)( access_t *p_access )
if
(
i_ret
<
0
)
{
if
(
errno
==
EWOULDBLOCK
)
return
;
return
;
/* no more events */
msg_Err
(
p_access
,
"reading frontend
status
failed (%d) %s"
,
msg_Err
(
p_access
,
"reading frontend
event
failed (%d) %s"
,
i_ret
,
strerror
(
errno
)
);
continue
;
return
;
}
i_status
=
event
.
status
;
i_diff
=
i_status
^
p_frontend
->
i_last_status
;
p_frontend
->
i_last_status
=
i_status
;
{
#define IF_UP( x ) \
} \
if ( i_diff & (x) ) \
{ \
if ( i_status & (x) )
{
IF_UP
(
FE_HAS_SIGNAL
)
msg_Dbg
(
p_access
,
"frontend has acquired signal"
);
else
...
...
@@ -333,8 +337,153 @@ void E_(FrontendPoll)( access_t *p_access )
E_
(
FrontendSet
)(
p_access
);
}
}
#undef IF_UP
}
}
#ifdef ENABLE_HTTPD
/*****************************************************************************
* FrontendStatus : Read frontend status
*****************************************************************************/
void
E_
(
FrontendStatus
)(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
frontend_t
*
p_frontend
=
p_sys
->
p_frontend
;
char
*
p
=
p_sys
->
psz_frontend_info
=
malloc
(
10000
);
fe_status_t
i_status
;
int
i_ret
;
/* Determine type of frontend */
if
(
(
i_ret
=
ioctl
(
p_sys
->
i_frontend_handle
,
FE_GET_INFO
,
&
p_frontend
->
info
))
<
0
)
{
p
+=
sprintf
(
p
,
"ioctl FE_GET_INFO failed (%d) %s
\n
"
,
i_ret
,
strerror
(
errno
)
);
goto
out
;
}
/* Print out frontend capabilities. */
p
+=
sprintf
(
p
,
"<table border=1><tr><th>name</th><td>%s</td></tr>
\n
"
,
p_frontend
->
info
.
name
);
switch
(
p_frontend
->
info
.
type
)
{
case
FE_QPSK
:
p
+=
sprintf
(
p
,
"<tr><th>type</th><td>QPSK (DVB-S)</td></tr>
\n
"
);
break
;
case
FE_QAM
:
p
+=
sprintf
(
p
,
"<tr><th>type</th><td>QAM (DVB-C)</td></tr>
\n
"
);
break
;
case
FE_OFDM
:
p
+=
sprintf
(
p
,
"<tr><th>type</th><td>OFDM (DVB-T)</td></tr>
\n
"
);
break
;
#if 0 /* DVB_API_VERSION == 3 */
case FE_MEMORY:
p += sprintf( p, "<tr><th>type</th><td>MEMORY</td></tr>\n" );
break;
case FE_NET:
p += sprintf( p, "<tr><th>type</th><td>NETWORK</td></tr>\n" );
break;
#endif
default:
p
+=
sprintf
(
p
,
"<tr><th>type</th><td>UNKNOWN (%d)</td></tr>
\n
"
,
p_frontend
->
info
.
type
);
goto
out
;
}
#define CHECK_INFO( x ) \
p += sprintf( p, \
"<tr><th>" STRINGIFY(x) "</th><td>%u</td></tr>\n", \
p_frontend->info.x );
CHECK_INFO
(
frequency_min
);
CHECK_INFO
(
frequency_max
);
CHECK_INFO
(
frequency_stepsize
);
CHECK_INFO
(
frequency_tolerance
);
CHECK_INFO
(
symbol_rate_min
);
CHECK_INFO
(
symbol_rate_max
);
CHECK_INFO
(
symbol_rate_tolerance
);
CHECK_INFO
(
notifier_delay
);
#undef CHECK_INFO
p
+=
sprintf
(
p
,
"</table><p>Frontend capability list:
\n
<table border=1>"
);
#define CHECK_CAPS( x ) \
if ( p_frontend->info.caps & (FE_##x) ) \
p += sprintf( p, "<tr><td>" STRINGIFY(x) "</td></tr>\n" );
CHECK_CAPS
(
IS_STUPID
);
CHECK_CAPS
(
CAN_INVERSION_AUTO
);
CHECK_CAPS
(
CAN_FEC_1_2
);
CHECK_CAPS
(
CAN_FEC_2_3
);
CHECK_CAPS
(
CAN_FEC_3_4
);
CHECK_CAPS
(
CAN_FEC_4_5
);
CHECK_CAPS
(
CAN_FEC_5_6
);
CHECK_CAPS
(
CAN_FEC_6_7
);
CHECK_CAPS
(
CAN_FEC_7_8
);
CHECK_CAPS
(
CAN_FEC_8_9
);
CHECK_CAPS
(
CAN_FEC_AUTO
);
CHECK_CAPS
(
CAN_QPSK
);
CHECK_CAPS
(
CAN_QAM_16
);
CHECK_CAPS
(
CAN_QAM_32
);
CHECK_CAPS
(
CAN_QAM_64
);
CHECK_CAPS
(
CAN_QAM_128
);
CHECK_CAPS
(
CAN_QAM_256
);
CHECK_CAPS
(
CAN_QAM_AUTO
);
CHECK_CAPS
(
CAN_TRANSMISSION_MODE_AUTO
);
CHECK_CAPS
(
CAN_BANDWIDTH_AUTO
);
CHECK_CAPS
(
CAN_GUARD_INTERVAL_AUTO
);
CHECK_CAPS
(
CAN_HIERARCHY_AUTO
);
CHECK_CAPS
(
CAN_MUTE_TS
);
CHECK_CAPS
(
CAN_RECOVER
);
CHECK_CAPS
(
CAN_CLEAN_SETUP
);
#undef CHECK_CAPS
p
+=
sprintf
(
p
,
"</table><p>Current frontend status:
\n
<table border=1>"
);
if
(
(
i_ret
=
ioctl
(
p_sys
->
i_frontend_handle
,
FE_READ_STATUS
,
&
i_status
))
<
0
)
{
p
+=
sprintf
(
p
,
"</table>ioctl FE_READ_STATUS failed (%d) %s
\n
"
,
i_ret
,
strerror
(
errno
)
);
goto
out
;
}
#define CHECK_STATUS( x ) \
if ( i_status & (FE_##x) ) \
p += sprintf( p, "<tr><td>" STRINGIFY(x) "</td></tr>\n" );
CHECK_STATUS
(
HAS_SIGNAL
);
CHECK_STATUS
(
HAS_CARRIER
);
CHECK_STATUS
(
HAS_VITERBI
);
CHECK_STATUS
(
HAS_SYNC
);
CHECK_STATUS
(
HAS_LOCK
);
CHECK_STATUS
(
REINIT
);
#undef CHECK_STATUS
if
(
i_status
&
FE_HAS_LOCK
)
{
int32_t
i_value
;
p
+=
sprintf
(
p
,
"</table><p>Signal status:
\n
<table border=1>"
);
if
(
ioctl
(
p_sys
->
i_frontend_handle
,
FE_READ_BER
,
&
i_value
)
>=
0
)
p
+=
sprintf
(
p
,
"<tr><th>Bit error rate</th><td>%d</td></tr>
\n
"
,
i_value
);
if
(
ioctl
(
p_sys
->
i_frontend_handle
,
FE_READ_SIGNAL_STRENGTH
,
&
i_value
)
>=
0
)
p
+=
sprintf
(
p
,
"<tr><th>Signal strength</th><td>%d</td></tr>
\n
"
,
i_value
);
if
(
ioctl
(
p_sys
->
i_frontend_handle
,
FE_READ_SNR
,
&
i_value
)
>=
0
)
p
+=
sprintf
(
p
,
"<tr><th>SNR</th><td>%d</td></tr>
\n
"
,
i_value
);
}
p
+=
sprintf
(
p
,
"</table>"
);
out:
vlc_mutex_lock
(
&
p_sys
->
httpd_mutex
);
p_sys
->
b_request_frontend_info
=
VLC_FALSE
;
vlc_cond_signal
(
&
p_sys
->
httpd_cond
);
vlc_mutex_unlock
(
&
p_sys
->
httpd_mutex
);
}
#endif
/*****************************************************************************
* FrontendInfo : Return information about given frontend
*****************************************************************************/
...
...
@@ -1242,7 +1391,7 @@ int E_(CAMOpen)( access_t *p_access )
msg_Dbg
(
p_access
,
"CAMInit: CA interface with %d %s"
,
caps
.
slot_num
,
caps
.
slot_num
==
1
?
"slot"
:
"slots"
);
if
(
caps
.
slot_type
&
CA_CI
)
msg_Dbg
(
p_access
,
"CAMInit: CI high level interface type
(not supported)
"
);
msg_Dbg
(
p_access
,
"CAMInit: CI high level interface type"
);
if
(
caps
.
slot_type
&
CA_CI_LINK
)
msg_Dbg
(
p_access
,
"CAMInit: CI link layer level interface type"
);
if
(
caps
.
slot_type
&
CA_CI_PHYS
)
...
...
@@ -1314,6 +1463,265 @@ int E_(CAMPoll)( access_t * p_access )
return
i_ret
;
}
#ifdef ENABLE_HTTPD
/*****************************************************************************
* CAMStatus :
*****************************************************************************/
void
E_
(
CAMStatus
)(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
char
*
p
;
ca_caps_t
caps
;
int
i_slot
,
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
++
)
{
if
(
p_sys
->
pb_slot_mmi_undisplayed
[
i_slot
]
==
VLC_TRUE
)
{
p_sys
->
psz_request
=
NULL
;
msg_Dbg
(
p_access
,
"ignoring user request because of a new MMI object"
);
break
;
}
}
}
if
(
p_sys
->
psz_request
!=
NULL
&&
*
p_sys
->
psz_request
)
{
/* We have a mission to accomplish. */
en50221_mmi_object_t
mmi_object
;
char
*
psz_request
=
p_sys
->
psz_request
;
char
psz_value
[
255
];
int
i_slot
;
vlc_bool_t
b_ok
=
VLC_FALSE
;
p_sys
->
psz_request
=
NULL
;
if
(
E_
(
HTTPExtractValue
)(
psz_request
,
"slot"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
{
p_sys
->
psz_mmi_info
=
strdup
(
"invalid request parameter
\n
"
);
goto
out
;
}
i_slot
=
atoi
(
psz_value
);
if
(
E_
(
HTTPExtractValue
)(
psz_request
,
"open"
,
psz_value
,
sizeof
(
psz_value
)
)
!=
NULL
)
{
E_
(
en50221_OpenMMI
)(
p_access
,
i_slot
);
return
;
}
if
(
E_
(
HTTPExtractValue
)(
psz_request
,
"close"
,
psz_value
,
sizeof
(
psz_value
)
)
!=
NULL
)
{
E_
(
en50221_CloseMMI
)(
p_access
,
i_slot
);
return
;
}
if
(
E_
(
HTTPExtractValue
)(
psz_request
,
"cancel"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
{
b_ok
=
VLC_TRUE
;
}
if
(
E_
(
HTTPExtractValue
)(
psz_request
,
"type"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
{
p_sys
->
psz_mmi_info
=
strdup
(
"invalid request parameter
\n
"
);
goto
out
;
}
if
(
!
strcmp
(
psz_value
,
"enq"
)
)
{
mmi_object
.
i_object_type
=
EN50221_MMI_ANSW
;
mmi_object
.
u
.
answ
.
b_ok
=
b_ok
;
if
(
b_ok
==
VLC_FALSE
)
{
mmi_object
.
u
.
answ
.
psz_answ
=
strdup
(
""
);
}
else
{
if
(
E_
(
HTTPExtractValue
)(
psz_request
,
"answ"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
{
p_sys
->
psz_mmi_info
=
strdup
(
"invalid request parameter
\n
"
);
goto
out
;
}
mmi_object
.
u
.
answ
.
psz_answ
=
strdup
(
psz_value
);
}
}
else
{
mmi_object
.
i_object_type
=
EN50221_MMI_MENU_ANSW
;
if
(
b_ok
==
VLC_FALSE
)
{
mmi_object
.
u
.
menu_answ
.
i_choice
=
0
;
}
else
{
if
(
E_
(
HTTPExtractValue
)(
psz_request
,
"choice"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
mmi_object
.
u
.
menu_answ
.
i_choice
=
0
;
else
mmi_object
.
u
.
menu_answ
.
i_choice
=
atoi
(
psz_value
);
}
}
E_
(
en50221_SendMMIObject
)(
p_access
,
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
++
)
{
if
(
p_sys
->
pb_slot_mmi_expected
[
i_slot
]
==
VLC_TRUE
)
return
;
}
p
=
p_sys
->
psz_mmi_info
=
malloc
(
10000
);
if
(
ioctl
(
p_sys
->
i_ca_handle
,
CA_GET_CAP
,
&
caps
)
!=
0
)
{
p
+=
sprintf
(
p
,
"ioctl CA_GET_CAP failed (%s)
\n
"
,
strerror
(
errno
)
);
goto
out
;
}
/* Output CA capabilities */
p
+=
sprintf
(
p
,
"CA interface with %d %s, type:
\n
<table>"
,
caps
.
slot_num
,
caps
.
slot_num
==
1
?
"slot"
:
"slots"
);
#define CHECK_CAPS( x, s ) \
if ( caps.slot_type & (CA_##x) ) \
p += sprintf( p, "<tr><td>" s "</td></tr>\n" );
CHECK_CAPS
(
CI
,
"CI high level interface"
);
CHECK_CAPS
(
CI_LINK
,
"CI link layer level interface"
);
CHECK_CAPS
(
CI_PHYS
,
"CI physical layer level interface (not supported)"
);
CHECK_CAPS
(
DESCR
,
"built-in descrambler"
);
CHECK_CAPS
(
SC
,
"simple smartcard interface"
);
#undef CHECK_CAPS
p
+=
sprintf
(
p
,
"</table>%d available %s
\n
<table>"
,
caps
.
descr_num
,
caps
.
descr_num
==
1
?
"descrambler (key)"
:
"descramblers (keys)"
);
#define CHECK_DESC( x ) \
if ( caps.descr_type & (CA_##x) ) \
p += sprintf( p, "<tr><td>" STRINGIFY(x) "</td></tr>\n" );
CHECK_DESC
(
ECD
);
CHECK_DESC
(
NDS
);
CHECK_DESC
(
DSS
);
#undef CHECK_DESC
p
+=
sprintf
(
p
,
"</table>"
);
for
(
i_slot
=
0
;
i_slot
<
p_sys
->
i_nb_slots
;
i_slot
++
)
{
ca_slot_info_t
sinfo
;
p_sys
->
pb_slot_mmi_undisplayed
[
i_slot
]
=
VLC_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
)
{
p
+=
sprintf
(
p
,
"ioctl CA_GET_SLOT_INFO failed (%s)<br>
\n
"
,
strerror
(
errno
)
);
continue
;
}
#define CHECK_TYPE( x, s ) \
if ( sinfo.type & (CA_##x) ) \
p += sprintf( p, s );
CHECK_TYPE
(
CI
,
"high level, "
);
CHECK_TYPE
(
CI_LINK
,
"link layer level, "
);
CHECK_TYPE
(
CI_PHYS
,
"physical layer level, "
);
#undef CHECK_TYPE
if
(
sinfo
.
flags
&
CA_CI_MODULE_READY
)
{
en50221_mmi_object_t
*
p_object
=
E_
(
en50221_GetMMIObject
)(
p_access
,
i_slot
);
p
+=
sprintf
(
p
,
"module present and ready<p>
\n
"
);
p
+=
sprintf
(
p
,
"<form action=index.html method=get>
\n
"
);
p
+=
sprintf
(
p
,
"<input type=hidden name=slot value=
\"
%d
\"
>
\n
"
,
i_slot
);
if
(
p_object
==
NULL
)
{
p
+=
sprintf
(
p
,
"<input type=submit name=open value=
\"
Open session
\"
>
\n
"
);
}
else
{
switch
(
p_object
->
i_object_type
)
{
case
EN50221_MMI_ENQ
:
p
+=
sprintf
(
p
,
"<input type=hidden name=type value=enq>
\n
"
);
p
+=
sprintf
(
p
,
"<table border=1><tr><th>%s</th></tr>
\n
"
,
p_object
->
u
.
enq
.
psz_text
);
if
(
p_object
->
u
.
enq
.
b_blind
==
VLC_FALSE
)
p
+=
sprintf
(
p
,
"<tr><td><input type=text name=answ></td></tr>
\n
"
);
else
p
+=
sprintf
(
p
,
"<tr><td><input type=password name=answ></td></tr>
\n
"
);
break
;
case
EN50221_MMI_MENU
:
p
+=
sprintf
(
p
,
"<input type=hidden name=type value=menu>
\n
"
);
p
+=
sprintf
(
p
,
"<table border=1><tr><th>%s</th></tr>
\n
"
,
p_object
->
u
.
menu
.
psz_title
);
p
+=
sprintf
(
p
,
"<tr><td>%s</td></tr><tr><td>
\n
"
,
p_object
->
u
.
menu
.
psz_subtitle
);
for
(
i
=
0
;
i
<
p_object
->
u
.
menu
.
i_choices
;
i
++
)
p
+=
sprintf
(
p
,
"<input type=radio name=choice value=
\"
%d
\"
>%s<br>
\n
"
,
i
+
1
,
p_object
->
u
.
menu
.
ppsz_choices
[
i
]
);
p
+=
sprintf
(
p
,
"</td></tr><tr><td>%s</td></tr>
\n
"
,
p_object
->
u
.
menu
.
psz_bottom
);
break
;
case
EN50221_MMI_LIST
:
p
+=
sprintf
(
p
,
"<input type=hidden name=type value=menu>
\n
"
);
p
+=
sprintf
(
p
,
"<input type=hidden name=choice value=0>
\n
"
);
p
+=
sprintf
(
p
,
"<table border=1><tr><th>%s</th></tr>
\n
"
,
p_object
->
u
.
menu
.
psz_title
);
p
+=
sprintf
(
p
,
"<tr><td>%s</td></tr><tr><td>
\n
"
,
p_object
->
u
.
menu
.
psz_subtitle
);
for
(
i
=
0
;
i
<
p_object
->
u
.
menu
.
i_choices
;
i
++
)
p
+=
sprintf
(
p
,
"%s<br>
\n
"
,
p_object
->
u
.
menu
.
ppsz_choices
[
i
]
);
p
+=
sprintf
(
p
,
"</td></tr><tr><td>%s</td></tr>
\n
"
,
p_object
->
u
.
menu
.
psz_bottom
);
break
;
default:
p
+=
sprintf
(
p
,
"<table><tr><th>Unknown MMI object type</th></tr>
\n
"
);
}
p
+=
sprintf
(
p
,
"</table><p><input type=submit name=ok value=
\"
OK
\"
>
\n
"
);
p
+=
sprintf
(
p
,
"<input type=submit name=cancel value=
\"
Cancel
\"
>
\n
"
);
p
+=
sprintf
(
p
,
"<input type=submit name=close value=
\"
Close Session
\"
>
\n
"
);
}
p
+=
sprintf
(
p
,
"</form>
\n
"
);
}
else
if
(
sinfo
.
flags
&
CA_CI_MODULE_PRESENT
)
p
+=
sprintf
(
p
,
"module present, not ready<br>
\n
"
);
else
p
+=
sprintf
(
p
,
"module not present<br>
\n
"
);
}
out:
vlc_mutex_lock
(
&
p_sys
->
httpd_mutex
);
p_sys
->
b_request_mmi_info
=
VLC_FALSE
;
vlc_cond_signal
(
&
p_sys
->
httpd_cond
);
vlc_mutex_unlock
(
&
p_sys
->
httpd_mutex
);
}
#endif
/*****************************************************************************
* CAMSet :
*****************************************************************************/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment