Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
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
Hide 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
(
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
;
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 ( 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