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
dacadc6e
Commit
dacadc6e
authored
Mar 21, 2011
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DVB: merge all CAM stuff in a single file (untested)
parent
d9720721
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
500 additions
and
536 deletions
+500
-536
modules/access/dvb/dvb.h
modules/access/dvb/dvb.h
+2
-9
modules/access/dvb/en50221.c
modules/access/dvb/en50221.c
+464
-60
modules/access/dvb/en50221.h
modules/access/dvb/en50221.h
+6
-112
modules/access/dvb/http.c
modules/access/dvb/http.c
+1
-1
modules/access/dvb/linux_dvb.c
modules/access/dvb/linux_dvb.c
+27
-354
No files found.
modules/access/dvb/dvb.h
View file @
dacadc6e
...
...
@@ -50,7 +50,6 @@ typedef struct
#define MAX_DEMUX 256
#include "en50221.h"
struct
scan_t
;
struct
scan_parameter_t
;
...
...
@@ -62,7 +61,7 @@ struct access_sys_t
mtime_t
i_frontend_timeout
;
bool
b_budget_mode
;
cam_t
cam
;
struct
cam
*
p_
cam
;
/* */
int
i_read_once
;
...
...
@@ -118,7 +117,7 @@ int DVROpen( access_t * );
void
DVRClose
(
access_t
*
);
int
CAMOpen
(
access_t
*
);
int
CAMPoll
(
access_t
*
);
void
CAMPoll
(
access_t
*
);
int
CAMSet
(
access_t
*
,
dvbpsi_pmt_t
*
);
void
CAMClose
(
access_t
*
);
#ifdef ENABLE_HTTPD
...
...
@@ -131,9 +130,3 @@ void HTTPClose( access_t *p_access );
const
char
*
HTTPExtractValue
(
const
char
*
psz_uri
,
const
char
*
psz_name
,
char
*
psz_value
,
int
i_value_max
);
#endif
/*****************************************************************************
* Hacks
*****************************************************************************/
#define STRINGIFY( z ) UGLY_KLUDGE( z )
#define UGLY_KLUDGE( z ) #z
modules/access/dvb/en50221.c
View file @
dacadc6e
...
...
@@ -31,6 +31,7 @@
#include <errno.h>
#include <time.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <poll.h>
...
...
@@ -55,6 +56,57 @@
#include "dvb.h"
#include "../../demux/dvb-text.h"
#include "en50221.h"
typedef
struct
en50221_session_t
{
unsigned
i_slot
;
int
i_resource_id
;
void
(
*
pf_handle
)(
cam_t
*
,
int
,
uint8_t
*
,
int
);
void
(
*
pf_close
)(
cam_t
*
,
int
);
void
(
*
pf_manage
)(
cam_t
*
,
int
);
void
*
p_sys
;
}
en50221_session_t
;
#define EN50221_MMI_NONE 0
#define EN50221_MMI_ENQ 1
#define EN50221_MMI_ANSW 2
#define EN50221_MMI_MENU 3
#define EN50221_MMI_MENU_ANSW 4
#define EN50221_MMI_LIST 5
typedef
struct
en50221_mmi_object_t
{
int
i_object_type
;
union
{
struct
{
bool
b_blind
;
char
*
psz_text
;
}
enq
;
struct
{
bool
b_ok
;
char
*
psz_answ
;
}
answ
;
struct
{
char
*
psz_title
,
*
psz_subtitle
,
*
psz_bottom
;
char
**
ppsz_choices
;
int
i_choices
;
}
menu
;
/* menu and list are the same */
struct
{
int
i_choice
;
}
menu_answ
;
}
u
;
}
mmi_t
;
#undef DEBUG_TPDU
#define HLCI_WAIT_CAM_READY 0
...
...
@@ -67,6 +119,28 @@ static void ConditionalAccessOpen( cam_t *, unsigned i_session_id );
static
void
DateTimeOpen
(
cam_t
*
,
unsigned
i_session_id
);
static
void
MMIOpen
(
cam_t
*
,
unsigned
i_session_id
);
#define MAX_CI_SLOTS 16
#define MAX_SESSIONS 32
#define MAX_PROGRAMS 24
struct
cam
{
vlc_object_t
*
obj
;
int
fd
;
int
i_ca_type
;
mtime_t
i_timeout
,
i_next_event
;
unsigned
i_nb_slots
;
bool
pb_active_slot
[
MAX_CI_SLOTS
];
bool
pb_tc_has_data
[
MAX_CI_SLOTS
];
bool
pb_slot_mmi_expected
[
MAX_CI_SLOTS
];
bool
pb_slot_mmi_undisplayed
[
MAX_CI_SLOTS
];
en50221_session_t
p_sessions
[
MAX_SESSIONS
];
dvbpsi_pmt_t
*
pp_selected_programs
[
MAX_PROGRAMS
];
int
i_selected_programs
;
};
/*****************************************************************************
* Utility functions
*****************************************************************************/
...
...
@@ -1504,16 +1578,44 @@ static void DateTimeOpen( cam_t * p_cam, unsigned i_session_id )
#define AI_CANCEL 0x00
#define AI_ANSWER 0x01
typedef
struct
static
void
MMIFree
(
mmi_t
*
p_object
)
{
en50221_mmi_object_t
last_object
;
}
mmi_t
;
switch
(
p_object
->
i_object_type
)
{
case
EN50221_MMI_ENQ
:
FREENULL
(
p_object
->
u
.
enq
.
psz_text
);
break
;
case
EN50221_MMI_ANSW
:
if
(
p_object
->
u
.
answ
.
b_ok
)
{
FREENULL
(
p_object
->
u
.
answ
.
psz_answ
);
}
break
;
case
EN50221_MMI_MENU
:
case
EN50221_MMI_LIST
:
FREENULL
(
p_object
->
u
.
menu
.
psz_title
);
FREENULL
(
p_object
->
u
.
menu
.
psz_subtitle
);
FREENULL
(
p_object
->
u
.
menu
.
psz_bottom
);
for
(
int
i
=
0
;
i
<
p_object
->
u
.
menu
.
i_choices
;
i
++
)
{
free
(
p_object
->
u
.
menu
.
ppsz_choices
[
i
]
);
}
FREENULL
(
p_object
->
u
.
menu
.
ppsz_choices
);
break
;
default:
break
;
}
}
/*****************************************************************************
* MMISendObject
*****************************************************************************/
static
void
MMISendObject
(
cam_t
*
p_cam
,
int
i_session_id
,
en50221_mmi_object
_t
*
p_object
)
mmi
_t
*
p_object
)
{
int
i_slot
=
p_cam
->
p_sessions
[
i_session_id
-
1
].
i_slot
;
uint8_t
*
p_data
;
...
...
@@ -1611,17 +1713,17 @@ static void MMIHandleEnq( cam_t *p_cam, int i_session_id,
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
)
?
true
:
false
;
MMIFree
(
p_mmi
);
p_mmi
->
i_object_type
=
EN50221_MMI_ENQ
;
p_mmi
->
u
.
enq
.
b_blind
=
(
*
d
&
0x1
)
?
true
:
false
;
d
+=
2
;
/* skip answer_text_length because it is not mandatory */
l
-=
2
;
p_mmi
->
last_object
.
u
.
enq
.
psz_text
=
xmalloc
(
l
+
1
);
strncpy
(
p_mmi
->
last_object
.
u
.
enq
.
psz_text
,
(
char
*
)
d
,
l
);
p_mmi
->
last_object
.
u
.
enq
.
psz_text
[
l
]
=
'\0'
;
p_mmi
->
u
.
enq
.
psz_text
=
xmalloc
(
l
+
1
);
strncpy
(
p_mmi
->
u
.
enq
.
psz_text
,
(
char
*
)
d
,
l
);
p_mmi
->
u
.
enq
.
psz_text
[
l
]
=
'\0'
;
msg_Dbg
(
p_cam
->
obj
,
"MMI enq: %s%s"
,
p_mmi
->
last_object
.
u
.
enq
.
psz_text
,
p_mmi
->
last_object
.
u
.
enq
.
b_blind
==
true
?
" (blind)"
:
""
);
msg_Dbg
(
p_cam
->
obj
,
"MMI enq: %s%s"
,
p_mmi
->
u
.
enq
.
psz_text
,
p_mmi
->
u
.
enq
.
b_blind
==
true
?
" (blind)"
:
""
);
p_cam
->
pb_slot_mmi_expected
[
i_slot
]
=
false
;
p_cam
->
pb_slot_mmi_undisplayed
[
i_slot
]
=
true
;
}
...
...
@@ -1639,11 +1741,11 @@ static void MMIHandleMenu( cam_t *p_cam, int i_session_id, int i_tag,
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
)
?
MMIFree
(
p_mmi
);
p_mmi
->
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
;
p_mmi
->
u
.
menu
.
i_choices
=
0
;
p_mmi
->
u
.
menu
.
ppsz_choices
=
NULL
;
if
(
l
>
0
)
{
...
...
@@ -1652,10 +1754,9 @@ static void MMIHandleMenu( cam_t *p_cam, int i_session_id, int i_tag,
#define GET_FIELD( x ) \
if ( l > 0 ) \
{ \
p_mmi->last_object.u.menu.psz_##x \
= MMIGetText( p_cam, &d, &l ); \
msg_Dbg( p_cam->obj, "MMI " STRINGIFY( x ) ": %s", \
p_mmi->last_object.u.menu.psz_##x ); \
p_mmi->u.menu.psz_##x = MMIGetText( p_cam, &d, &l ); \
msg_Dbg( p_cam->obj, "MMI " STRINGIFY( x ) ": %s", \
p_mmi->u.menu.psz_##x ); \
}
GET_FIELD
(
title
);
...
...
@@ -1666,8 +1767,8 @@ static void MMIHandleMenu( cam_t *p_cam, int i_session_id, int i_tag,
while
(
l
>
0
)
{
char
*
psz_text
=
MMIGetText
(
p_cam
,
&
d
,
&
l
);
TAB_APPEND
(
p_mmi
->
last_object
.
u
.
menu
.
i_choices
,
p_mmi
->
last_object
.
u
.
menu
.
ppsz_choices
,
TAB_APPEND
(
p_mmi
->
u
.
menu
.
i_choices
,
p_mmi
->
u
.
menu
.
ppsz_choices
,
psz_text
);
msg_Dbg
(
p_cam
->
obj
,
"MMI choice: %s"
,
psz_text
);
}
...
...
@@ -1737,7 +1838,7 @@ static void MMIClose( cam_t *p_cam, int i_session_id )
int
i_slot
=
p_cam
->
p_sessions
[
i_session_id
-
1
].
i_slot
;
mmi_t
*
p_mmi
=
(
mmi_t
*
)
p_cam
->
p_sessions
[
i_session_id
-
1
].
p_sys
;
en50221_MMIFree
(
&
p_mmi
->
last_object
);
MMIFree
(
p_mmi
);
free
(
p_cam
->
p_sessions
[
i_session_id
-
1
].
p_sys
);
msg_Dbg
(
p_cam
->
obj
,
"closing MMI session (%d)"
,
i_session_id
);
...
...
@@ -1758,7 +1859,7 @@ static void MMIOpen( cam_t *p_cam, unsigned i_session_id )
p_cam
->
p_sessions
[
i_session_id
-
1
].
pf_close
=
MMIClose
;
p_cam
->
p_sessions
[
i_session_id
-
1
].
p_sys
=
xmalloc
(
sizeof
(
mmi_t
));
p_mmi
=
(
mmi_t
*
)
p_cam
->
p_sessions
[
i_session_id
-
1
].
p_sys
;
p_mmi
->
last_object
.
i_object_type
=
EN50221_MMI_NONE
;
p_mmi
->
i_object_type
=
EN50221_MMI_NONE
;
}
...
...
@@ -1818,10 +1919,55 @@ static int InitSlot( cam_t * p_cam, int i_slot )
/*****************************************************************************
* en50221_Init : Initialize the CAM for en50221
*****************************************************************************/
int
en50221_Init
(
cam_t
*
p_cam
)
cam_t
*
en50221_Init
(
vlc_object_t
*
obj
,
int
fd
)
{
if
(
p_cam
->
i_ca_type
&
CA_CI_LINK
)
ca_caps_t
caps
;
memset
(
&
caps
,
0
,
sizeof
(
caps
));
if
(
ioctl
(
fd
,
CA_GET_CAP
,
&
caps
)
<
0
)
{
msg_Err
(
obj
,
"CAMInit: ioctl() error getting CAM capabilities"
);
return
NULL
;
}
/* Output CA capabilities */
msg_Dbg
(
obj
,
"CA interface with %d slot(s)"
,
caps
.
slot_num
);
if
(
caps
.
slot_type
&
CA_CI
)
msg_Dbg
(
obj
,
" CI high level interface type"
);
if
(
caps
.
slot_type
&
CA_CI_LINK
)
msg_Dbg
(
obj
,
" CI link layer level interface type"
);
if
(
caps
.
slot_type
&
CA_CI_PHYS
)
msg_Dbg
(
obj
,
" CI physical layer level interface type (not supported) "
);
if
(
caps
.
slot_type
&
CA_DESCR
)
msg_Dbg
(
obj
,
" built-in descrambler detected"
);
if
(
caps
.
slot_type
&
CA_SC
)
msg_Dbg
(
obj
,
" simple smart card interface"
);
msg_Dbg
(
obj
,
"%d available descrambler(s) (keys)"
,
caps
.
descr_num
);
if
(
caps
.
descr_type
&
CA_ECD
)
msg_Dbg
(
obj
,
" ECD scrambling system supported"
);
if
(
caps
.
descr_type
&
CA_NDS
)
msg_Dbg
(
obj
,
" NDS scrambling system supported"
);
if
(
caps
.
descr_type
&
CA_DSS
)
msg_Dbg
(
obj
,
" DSS scrambling system supported"
);
if
(
caps
.
slot_num
==
0
)
{
msg_Err
(
obj
,
"CAM module without slots"
);
return
NULL
;
}
cam_t
*
p_cam
=
malloc
(
sizeof
(
*
p_cam
)
);
if
(
unlikely
(
p_cam
==
NULL
)
)
goto
error
;
p_cam
->
obj
=
obj
;
p_cam
->
fd
=
fd
;
if
(
caps
.
slot_type
&
CA_CI_LINK
)
{
p_cam
->
i_ca_type
=
CA_CI_LINK
;
for
(
unsigned
i_slot
=
0
;
i_slot
<
p_cam
->
i_nb_slots
;
i_slot
++
)
{
if
(
ioctl
(
p_cam
->
fd
,
CA_RESET
,
1
<<
i_slot
)
!=
0
)
...
...
@@ -1834,29 +1980,25 @@ int en50221_Init( cam_t * p_cam )
p_cam
->
i_timeout
=
CLOCK_FREQ
/
10
;
/* Wait a bit otherwise it doesn't initialize properly... */
msleep
(
CLOCK_FREQ
/
10
);
return
VLC_SUCCESS
;
}
else
if
(
caps
.
slot_type
&
CA_CI
)
{
p_cam
->
i_ca_type
=
CA_CI
;
struct
ca_slot_info
info
;
info
.
num
=
0
;
/* We don't reset the CAM in that case because it's done by the
* ASIC. */
if
(
ioctl
(
p_cam
->
fd
,
CA_GET_SLOT_INFO
,
&
info
)
<
0
)
if
(
ioctl
(
fd
,
CA_GET_SLOT_INFO
,
&
info
)
<
0
)
{
msg_Err
(
p_cam
->
obj
,
"en50221_Init: couldn't get slot info"
);
close
(
p_cam
->
fd
);
p_cam
->
fd
=
-
1
;
return
VLC_EGENERIC
;
msg_Err
(
obj
,
"cannot get slot info: %m"
);
goto
error
;
}
if
(
info
.
flags
==
0
)
{
msg_Err
(
p_cam
->
obj
,
"en50221_Init: no CAM inserted"
);
close
(
p_cam
->
fd
);
p_cam
->
fd
=
-
1
;
return
VLC_EGENERIC
;
msg_Err
(
obj
,
"no CAM inserted"
);
goto
error
;
}
/* Allocate a dummy sessions */
...
...
@@ -1871,49 +2013,71 @@ int en50221_Init( cam_t * p_cam )
ca_msg
.
msg
[
2
]
=
(
AOT_APPLICATION_INFO
&
0x0000FF
)
>>
0
;
memset
(
&
ca_msg
.
msg
[
3
],
0
,
253
);
APDUSend
(
p_cam
,
1
,
AOT_APPLICATION_INFO_ENQ
,
NULL
,
0
);
if
(
ioctl
(
p_cam
->
fd
,
CA_GET_MSG
,
&
ca_msg
)
<
0
)
if
(
ioctl
(
fd
,
CA_GET_MSG
,
&
ca_msg
)
<
0
)
{
msg_Err
(
p_cam
->
obj
,
"en50221_Init: failed getting message"
);
return
VLC_EGENERIC
;
msg_Err
(
obj
,
"en50221_Init: failed getting message"
);
goto
error
;
}
#if HLCI_WAIT_CAM_READY
while
(
ca_msg
.
msg
[
8
]
==
0xff
&&
ca_msg
.
msg
[
9
]
==
0xff
)
{
if
(
!
vlc_object_alive
(
p_cam
)
)
return
VLC_EGENERIC
;
if
(
!
vlc_object_alive
(
obj
)
)
goto
error
;
msleep
(
1
);
msg_Dbg
(
p_cam
->
obj
,
"CAM: please wait"
);
msg_Dbg
(
obj
,
"CAM: please wait"
);
APDUSend
(
p_cam
,
1
,
AOT_APPLICATION_INFO_ENQ
,
NULL
,
0
);
ca_msg
.
length
=
3
;
ca_msg
.
msg
[
0
]
=
(
AOT_APPLICATION_INFO
&
0xFF0000
)
>>
16
;
ca_msg
.
msg
[
1
]
=
(
AOT_APPLICATION_INFO
&
0x00FF00
)
>>
8
;
ca_msg
.
msg
[
2
]
=
(
AOT_APPLICATION_INFO
&
0x0000FF
)
>>
0
;
memset
(
&
ca_msg
.
msg
[
3
],
0
,
253
);
if
(
ioctl
(
p_cam
->
fd
,
CA_GET_MSG
,
&
ca_msg
)
<
0
)
if
(
ioctl
(
fd
,
CA_GET_MSG
,
&
ca_msg
)
<
0
)
{
msg_Err
(
p_cam
->
obj
,
"en50221_Init: failed getting message"
);
return
VLC_EGENERIC
;
msg_Err
(
obj
,
"en50221_Init: failed getting message"
);
goto
error
;
}
msg_Dbg
(
p_cam
->
obj
,
"en50221_Init: Got length: %d, tag: 0x%x"
,
ca_msg
.
length
,
APDUGetTag
(
ca_msg
.
msg
,
ca_msg
.
length
)
);
}
#else
if
(
ca_msg
.
msg
[
8
]
==
0xff
&&
ca_msg
.
msg
[
9
]
==
0xff
)
{
msg_Err
(
p_cam
->
obj
,
"CAM returns garbage as application info!"
);
return
VLC_EGENERIC
;
msg_Err
(
obj
,
"CAM returns garbage as application info!"
);
goto
error
;
}
#endif
msg_Dbg
(
p_cam
->
obj
,
"found CAM %s using id 0x%x"
,
&
ca_msg
.
msg
[
12
],
msg_Dbg
(
obj
,
"found CAM %s using id 0x%x"
,
&
ca_msg
.
msg
[
12
],
(
ca_msg
.
msg
[
8
]
<<
8
)
|
ca_msg
.
msg
[
9
]
);
return
VLC_SUCCESS
;
}
else
{
msg_Err
(
obj
,
"CAM interface incompatible"
);
goto
error
;
}
return
p_cam
;
error:
free
(
p_cam
);
return
NULL
;
}
/*****************************************************************************
* en50221_Poll : Poll the CAM for TPDUs
*****************************************************************************/
int
en50221_Poll
(
cam_t
*
p_cam
)
void
en50221_Poll
(
cam_t
*
p_cam
)
{
switch
(
p_cam
->
i_ca_type
)
{
case
CA_CI_LINK
:
if
(
mdate
()
>
p_cam
->
i_next_event
)
break
;
case
CA_CI
:
return
;
default:
assert
(
0
);
}
for
(
unsigned
i_slot
=
0
;
i_slot
<
p_cam
->
i_nb_slots
;
i_slot
++
)
{
uint8_t
i_tag
;
...
...
@@ -2044,7 +2208,7 @@ int en50221_Poll( cam_t * p_cam )
}
}
return
VLC_SUCCESS
;
p_cam
->
i_next_event
=
mdate
()
+
p_cam
->
i_timeout
;
}
...
...
@@ -2120,7 +2284,7 @@ int en50221_SetCAPMT( cam_t * p_cam, dvbpsi_pmt_t *p_pmt )
/*****************************************************************************
* en50221_OpenMMI :
*****************************************************************************/
int
en50221_OpenMMI
(
cam_t
*
p_cam
,
unsigned
i_slot
)
static
int
en50221_OpenMMI
(
cam_t
*
p_cam
,
unsigned
i_slot
)
{
if
(
p_cam
->
i_ca_type
&
CA_CI_LINK
)
{
...
...
@@ -2160,7 +2324,7 @@ int en50221_OpenMMI( cam_t * p_cam, unsigned i_slot )
/*****************************************************************************
* en50221_CloseMMI :
*****************************************************************************/
int
en50221_CloseMMI
(
cam_t
*
p_cam
,
unsigned
i_slot
)
static
int
en50221_CloseMMI
(
cam_t
*
p_cam
,
unsigned
i_slot
)
{
if
(
p_cam
->
i_ca_type
&
CA_CI_LINK
)
{
...
...
@@ -2188,7 +2352,7 @@ int en50221_CloseMMI( cam_t * p_cam, unsigned i_slot )
/*****************************************************************************
* en50221_GetMMIObject :
*****************************************************************************/
en50221_mmi_object
_t
*
en50221_GetMMIObject
(
cam_t
*
p_cam
,
unsigned
i_slot
)
static
mmi
_t
*
en50221_GetMMIObject
(
cam_t
*
p_cam
,
unsigned
i_slot
)
{
if
(
p_cam
->
pb_slot_mmi_expected
[
i_slot
]
==
true
)
return
NULL
;
/* should not happen */
...
...
@@ -2202,7 +2366,7 @@ en50221_mmi_object_t *en50221_GetMMIObject( cam_t * p_cam, unsigned i_slot )
(
mmi_t
*
)
p_cam
->
p_sessions
[
i
-
1
].
p_sys
;
if
(
p_mmi
==
NULL
)
return
NULL
;
/* should not happen */
return
&
p_mmi
->
last_object
;
return
p_mmi
;
}
}
...
...
@@ -2213,8 +2377,8 @@ en50221_mmi_object_t *en50221_GetMMIObject( cam_t * p_cam, unsigned i_slot )
/*****************************************************************************
* en50221_SendMMIObject :
*****************************************************************************/
void
en50221_SendMMIObject
(
cam_t
*
p_cam
,
unsigned
i_slot
,
en50221_mmi_object
_t
*
p_object
)
static
void
en50221_SendMMIObject
(
cam_t
*
p_cam
,
unsigned
i_slot
,
mmi
_t
*
p_object
)
{
for
(
unsigned
i
=
1
;
i
<=
MAX_SESSIONS
;
i
++
)
{
...
...
@@ -2229,6 +2393,246 @@ void en50221_SendMMIObject( cam_t * p_cam, unsigned i_slot,
msg_Err
(
p_cam
->
obj
,
"SendMMIObject when no MMI session is opened !"
);
}
#ifdef ENABLE_HTTPD
char
*
en50221_Status
(
cam_t
*
p_cam
,
char
*
psz_request
)
{
if
(
psz_request
!=
NULL
&&
*
psz_request
)
{
/* Check if we have an undisplayed MMI message : in that case we ignore
* the user input to avoid confusing the CAM. */
for
(
unsigned
i_slot
=
0
;
i_slot
<
p_cam
->
i_nb_slots
;
i_slot
++
)
{
if
(
p_cam
->
pb_slot_mmi_undisplayed
[
i_slot
]
==
true
)
{
psz_request
=
NULL
;
msg_Dbg
(
p_cam
->
obj
,
"ignoring user request because of a new MMI object"
);
break
;
}
}
}
if
(
psz_request
!=
NULL
&&
*
psz_request
)
{
/* We have a mission to accomplish. */
mmi_t
mmi_object
;
char
psz_value
[
255
];
int
i_slot
;
bool
b_ok
=
false
;
if
(
HTTPExtractValue
(
psz_request
,
"slot"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
{
return
strdup
(
"invalid request parameter
\n
"
);
}
i_slot
=
atoi
(
psz_value
);
if
(
HTTPExtractValue
(
psz_request
,
"open"
,
psz_value
,
sizeof
(
psz_value
)
)
!=
NULL
)
{
en50221_OpenMMI
(
p_cam
,
i_slot
);
return
NULL
;
}
if
(
HTTPExtractValue
(
psz_request
,
"close"
,
psz_value
,
sizeof
(
psz_value
)
)
!=
NULL
)
{
en50221_CloseMMI
(
p_cam
,
i_slot
);
return
NULL
;
}
if
(
HTTPExtractValue
(
psz_request
,
"cancel"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
{
b_ok
=
true
;
}
if
(
HTTPExtractValue
(
psz_request
,
"type"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
{
return
strdup
(
"invalid request parameter
\n
"
);
}
if
(
!
strcmp
(
psz_value
,
"enq"
)
)
{
mmi_object
.
i_object_type
=
EN50221_MMI_ANSW
;
mmi_object
.
u
.
answ
.
b_ok
=
b_ok
;
if
(
b_ok
==
false
)
{
mmi_object
.
u
.
answ
.
psz_answ
=
strdup
(
""
);
}
else
{
if
(
HTTPExtractValue
(
psz_request
,
"answ"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
{
return
strdup
(
"invalid request parameter
\n
"
);
}
mmi_object
.
u
.
answ
.
psz_answ
=
strdup
(
psz_value
);
}
}
else
{
mmi_object
.
i_object_type
=
EN50221_MMI_MENU_ANSW
;
if
(
b_ok
==
false
)
{
mmi_object
.
u
.
menu_answ
.
i_choice
=
0
;
}
else
{
if
(
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
);
}
}
en50221_SendMMIObject
(
p_cam
,
i_slot
,
&
mmi_object
);
return
NULL
;
}
/* Check that we have all necessary MMI information. */
for
(
unsigned
i_slot
=
0
;
i_slot
<
p_cam
->
i_nb_slots
;
i_slot
++
)
{
if
(
p_cam
->
pb_slot_mmi_expected
[
i_slot
]
==
true
)
return
NULL
;
}
char
*
buf
=
xmalloc
(
10000
),
*
p
=
buf
;
ca_caps_t
caps
;
if
(
ioctl
(
p_cam
->
fd
,
CA_GET_CAP
,
&
caps
)
<
0
)
{
p
+=
sprintf
(
p
,
"ioctl CA_GET_CAP failed (%m)
\n
"
);
return
buf
;
}
/* 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
(
unsigned
i_slot
=
0
;
i_slot
<
p_cam
->
i_nb_slots
;
i_slot
++
)
{
ca_slot_info_t
sinfo
;
p_cam
->
pb_slot_mmi_undisplayed
[
i_slot
]
=
false
;
p
+=
sprintf
(
p
,
"<p>CA slot #%d: "
,
i_slot
);
sinfo
.
num
=
i_slot
;
if
(
ioctl
(
p_cam
->
fd
,
CA_GET_SLOT_INFO
,
&
sinfo
)
<
0
)
{
p
+=
sprintf
(
p
,
"ioctl CA_GET_SLOT_INFO failed (%m)<br>
\n
"
);
continue
;
}
#define CHECK_TYPE( x, s ) \
if ( sinfo.type & (CA_##x) ) \
p += sprintf( p, "%s", 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
)
{
mmi_t
*
p_object
=
en50221_GetMMIObject
(
p_cam
,
i_slot
);
p
+=
sprintf
(
p
,
"module present and ready<p>
\n
"
);
p
+=
sprintf
(
p
,
"<form action=index.html method=get>
\n
"
);
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
==
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
(
int
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
(
int
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
"
);
}
return
buf
;
}
#endif
/*****************************************************************************
* en50221_End :
*****************************************************************************/
...
...
@@ -2251,6 +2655,6 @@ void en50221_End( cam_t * p_cam )
}
}
/* Leave the CAM configured, so that it can be reused in another
* program. */
close
(
p_cam
->
fd
);
free
(
p_cam
);
}
modules/access/dvb/en50221.h
View file @
dacadc6e
...
...
@@ -25,117 +25,11 @@
typedef
struct
cam
cam_t
;
typedef
struct
en50221_session_t
{
unsigned
i_slot
;
int
i_resource_id
;
void
(
*
pf_handle
)(
cam_t
*
,
int
,
uint8_t
*
,
int
);
void
(
*
pf_close
)(
cam_t
*
,
int
);
void
(
*
pf_manage
)(
cam_t
*
,
int
);
void
*
p_sys
;
}
en50221_session_t
;
#define EN50221_MMI_NONE 0
#define EN50221_MMI_ENQ 1
#define EN50221_MMI_ANSW 2
#define EN50221_MMI_MENU 3
#define EN50221_MMI_MENU_ANSW 4
#define EN50221_MMI_LIST 5
typedef
struct
en50221_mmi_object_t
{
int
i_object_type
;
union
{
struct
{
bool
b_blind
;
char
*
psz_text
;
}
enq
;
struct
{
bool
b_ok
;
char
*
psz_answ
;
}
answ
;
struct
{
char
*
psz_title
,
*
psz_subtitle
,
*
psz_bottom
;
char
**
ppsz_choices
;
int
i_choices
;
}
menu
;
/* menu and list are the same */
struct
{
int
i_choice
;
}
menu_answ
;
}
u
;
}
en50221_mmi_object_t
;
static
inline
void
en50221_MMIFree
(
en50221_mmi_object_t
*
p_object
)
{
int
i
;
switch
(
p_object
->
i_object_type
)
{
case
EN50221_MMI_ENQ
:
FREENULL
(
p_object
->
u
.
enq
.
psz_text
);
break
;
case
EN50221_MMI_ANSW
:
if
(
p_object
->
u
.
answ
.
b_ok
)
{
FREENULL
(
p_object
->
u
.
answ
.
psz_answ
);
}
break
;
case
EN50221_MMI_MENU
:
case
EN50221_MMI_LIST
:
FREENULL
(
p_object
->
u
.
menu
.
psz_title
);
FREENULL
(
p_object
->
u
.
menu
.
psz_subtitle
);
FREENULL
(
p_object
->
u
.
menu
.
psz_bottom
);
for
(
i
=
0
;
i
<
p_object
->
u
.
menu
.
i_choices
;
i
++
)
{
free
(
p_object
->
u
.
menu
.
ppsz_choices
[
i
]
);
}
FREENULL
(
p_object
->
u
.
menu
.
ppsz_choices
);
break
;
default:
break
;
}
}
/* CA management */
#define MAX_CI_SLOTS 16
#define MAX_SESSIONS 32
#define MAX_PROGRAMS 24
struct
cam
{
vlc_object_t
*
obj
;
int
i_ca_type
;
int
fd
;
mtime_t
i_timeout
,
i_next_event
;
unsigned
i_nb_slots
;
bool
pb_active_slot
[
MAX_CI_SLOTS
];
bool
pb_tc_has_data
[
MAX_CI_SLOTS
];
bool
pb_slot_mmi_expected
[
MAX_CI_SLOTS
];
bool
pb_slot_mmi_undisplayed
[
MAX_CI_SLOTS
];
en50221_session_t
p_sessions
[
MAX_SESSIONS
];
dvbpsi_pmt_t
*
pp_selected_programs
[
MAX_PROGRAMS
];
int
i_selected_programs
;
};
int
en50221_Init
(
cam_t
*
);
int
en50221_Poll
(
cam_t
*
);
cam_t
*
en50221_Init
(
vlc_object_t
*
,
int
fd
);
void
en50221_Poll
(
cam_t
*
);
int
en50221_SetCAPMT
(
cam_t
*
,
dvbpsi_pmt_t
*
);
int
en50221_OpenMMI
(
cam_t
*
,
unsigned
i_slot
);
int
en50221_CloseMMI
(
cam_t
*
,
unsigned
i_slot
);
en50221_mmi_object_t
*
en50221_GetMMIObject
(
cam_t
*
,
unsigned
i_slot
);
void
en50221_SendMMIObject
(
cam_t
*
,
unsigned
i_slot
,
en50221_mmi_object_t
*
);
char
*
en50221_Status
(
cam_t
*
,
char
*
req
);
void
en50221_End
(
cam_t
*
);
#define STRINGIFY( z ) UGLY_KLUDGE( z )
#define UGLY_KLUDGE( z ) #z
modules/access/dvb/http.c
View file @
dacadc6e
...
...
@@ -242,7 +242,7 @@ static int HttpCallback( httpd_file_sys_t *p_args,
p_sys
->
i_httpd_timeout
=
mdate
()
+
INT64_C
(
3000000
);
/* 3 s */
p_sys
->
psz_request
=
psz_request
;
p_sys
->
b_request_frontend_info
=
true
;
if
(
p_sys
->
cam
.
fd
!=
-
1
)
if
(
p_sys
->
p_cam
!=
NULL
)
{
p_sys
->
b_request_mmi_info
=
true
;
}
...
...
modules/access/dvb/linux_dvb.c
View file @
dacadc6e
...
...
@@ -44,7 +44,6 @@
#include <linux/dvb/version.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/ca.h>
/* Include dvbpsi headers */
# include <dvbpsi/dvbpsi.h>
...
...
@@ -56,12 +55,9 @@
# include <dvbpsi/demux.h>
# include <dvbpsi/sdt.h>
#ifdef ENABLE_HTTPD
# include <vlc_httpd.h>
#endif
#include "dvb.h"
#include "scan.h"
#include "en50221.h"
#define DMX "/dev/dvb/adapter%d/demux%d"
#define FRONTEND "/dev/dvb/adapter%d/frontend%d"
...
...
@@ -1478,118 +1474,40 @@ void DVRClose( access_t * p_access )
*****************************************************************************/
int
CAMOpen
(
access_t
*
p_access
)
{
cam_t
*
p_cam
=
&
p_access
->
p_sys
->
cam
;
char
ca
[
128
];
int
i_adapter
,
i_device
;
ca_caps_t
caps
;
p_cam
->
obj
=
VLC_OBJECT
(
p_access
);
i_adapter
=
var_GetInteger
(
p_access
,
"dvb-adapter"
);
i_device
=
var_GetInteger
(
p_access
,
"dvb-device"
);
int
i_adapter
=
var_GetInteger
(
p_access
,
"dvb-adapter"
);
int
i_device
=
var_GetInteger
(
p_access
,
"dvb-device"
);
char
ca
[
128
];
if
(
snprintf
(
ca
,
sizeof
(
ca
),
CA
,
i_adapter
,
i_device
)
>=
(
int
)
sizeof
(
ca
)
)
{
msg_Err
(
p_access
,
"snprintf() truncated string for CA"
);
ca
[
sizeof
(
ca
)
-
1
]
=
'\0'
;
}
memset
(
&
caps
,
0
,
sizeof
(
ca_caps_t
));
msg_Dbg
(
p_access
,
"Opening device %s"
,
ca
);
p_cam
->
fd
=
vlc_open
(
ca
,
O_RDWR
|
O_NONBLOCK
);
if
(
p_cam
->
fd
==
-
1
)
int
fd
=
vlc_open
(
ca
,
O_RDWR
|
O_NONBLOCK
);
if
(
fd
==
-
1
)
{
msg_Warn
(
p_access
,
"CAMInit: opening CAM device failed (%m)"
);
return
VLC_EGENERIC
;
}
if
(
ioctl
(
p_cam
->
fd
,
CA_GET_CAP
,
&
caps
)
<
0
)
{
msg_Err
(
p_access
,
"CAMInit: ioctl() error getting CAM capabilities"
);
goto
error
;
}
/* Output CA capabilities */
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"
);
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
)
msg_Dbg
(
p_access
,
"CAMInit: CI physical layer level interface type (not supported) "
);
if
(
caps
.
slot_type
&
CA_DESCR
)
msg_Dbg
(
p_access
,
"CAMInit: built-in descrambler detected"
);
if
(
caps
.
slot_type
&
CA_SC
)
msg_Dbg
(
p_access
,
"CAMInit: simple smart card interface"
);
msg_Dbg
(
p_access
,
"CAMInit: %d available %s"
,
caps
.
descr_num
,
caps
.
descr_num
==
1
?
"descrambler (key)"
:
"descramblers (keys)"
);
if
(
caps
.
descr_type
&
CA_ECD
)
msg_Dbg
(
p_access
,
"CAMInit: ECD scrambling system supported"
);
if
(
caps
.
descr_type
&
CA_NDS
)
msg_Dbg
(
p_access
,
"CAMInit: NDS scrambling system supported"
);
if
(
caps
.
descr_type
&
CA_DSS
)
msg_Dbg
(
p_access
,
"CAMInit: DSS scrambling system supported"
);
if
(
caps
.
slot_num
==
0
)
{
msg_Err
(
p_access
,
"CAMInit: CAM module with no slots"
);
goto
error
;
}
if
(
caps
.
slot_type
&
CA_CI_LINK
)
{
p_cam
->
i_ca_type
=
CA_CI_LINK
;
}
else
if
(
caps
.
slot_type
&
CA_CI
)
{
p_cam
->
i_ca_type
=
CA_CI
;
}
else
if
(
!
(
p_access
->
p_sys
->
p_cam
=
en50221_Init
(
VLC_OBJECT
(
p_access
),
fd
))
)
{
p_cam
->
i_ca_type
=
-
1
;
msg_Err
(
p_access
,
"CAMInit: incompatible CAM interface"
);
goto
error
;
close
(
fd
);
return
VLC_EGENERIC
;
}
p_cam
->
i_nb_slots
=
caps
.
slot_num
;
memset
(
p_cam
->
pb_active_slot
,
0
,
sizeof
(
bool
)
*
MAX_CI_SLOTS
);
memset
(
p_cam
->
pb_slot_mmi_expected
,
0
,
sizeof
(
bool
)
*
MAX_CI_SLOTS
);
memset
(
p_cam
->
pb_slot_mmi_undisplayed
,
0
,
sizeof
(
bool
)
*
MAX_CI_SLOTS
);
return
en50221_Init
(
p_cam
);
error:
close
(
p_cam
->
fd
);
p_cam
->
fd
=
-
1
;
return
VLC_EGENERIC
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* CAMPoll :
*****************************************************************************/
int
CAMPoll
(
access_t
*
p_access
)
void
CAMPoll
(
access_t
*
p_access
)
{
cam_t
*
p_cam
=
&
p_access
->
p_sys
->
cam
;
if
(
p_cam
->
fd
==
-
1
)
return
VLC_EGENERIC
;
switch
(
p_cam
->
i_ca_type
)
{
case
CA_CI_LINK
:
if
(
mdate
()
>
p_cam
->
i_next_event
)
{
int
ret
=
en50221_Poll
(
p_cam
);
p_cam
->
i_next_event
=
mdate
()
+
p_cam
->
i_timeout
;
return
ret
;
}
case
CA_CI
:
return
VLC_SUCCESS
;
}
msg_Err
(
p_access
,
"CAMPoll: This should not happen"
);
return
VLC_EGENERIC
;;
cam_t
*
p_cam
=
p_access
->
p_sys
->
p_cam
;
if
(
p_cam
!=
NULL
)
en50221_Poll
(
p_cam
);
}
#ifdef ENABLE_HTTPD
...
...
@@ -1599,258 +1517,17 @@ int CAMPoll( access_t * p_access )
void
CAMStatus
(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
cam_t
*
p_cam
=
&
p_sys
->
cam
;
char
*
p
;
ca_caps_t
caps
;
int
i
;
cam_t
*
p_cam
=
p_sys
->
p_cam
;
if
(
p_sys
->
psz_request
!=
NULL
&&
*
p_sys
->
psz_request
)
p_sys
->
psz_mmi_info
=
en50221_Status
(
p_cam
,
p_sys
->
psz_request
);
p_sys
->
psz_request
=
NULL
;
if
(
p_sys
->
psz_mmi_info
!=
NULL
)
{
/* Check if we have an undisplayed MMI message : in that case we ignore
* the user input to avoid confusing the CAM. */
for
(
unsigned
i_slot
=
0
;
i_slot
<
p_cam
->
i_nb_slots
;
i_slot
++
)
{
if
(
p_cam
->
pb_slot_mmi_undisplayed
[
i_slot
]
==
true
)
{
p_sys
->
psz_request
=
NULL
;
msg_Dbg
(
p_access
,
"ignoring user request because of a new MMI object"
);
break
;
}
}
vlc_mutex_lock
(
&
p_sys
->
httpd_mutex
);
p_sys
->
b_request_mmi_info
=
false
;
vlc_cond_signal
(
&
p_sys
->
httpd_cond
);
vlc_mutex_unlock
(
&
p_sys
->
httpd_mutex
);
}
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
;
bool
b_ok
=
false
;
p_sys
->
psz_request
=
NULL
;
if
(
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
(
HTTPExtractValue
(
psz_request
,
"open"
,
psz_value
,
sizeof
(
psz_value
)
)
!=
NULL
)
{
en50221_OpenMMI
(
p_cam
,
i_slot
);
return
;
}
if
(
HTTPExtractValue
(
psz_request
,
"close"
,
psz_value
,
sizeof
(
psz_value
)
)
!=
NULL
)
{
en50221_CloseMMI
(
p_cam
,
i_slot
);
return
;
}
if
(
HTTPExtractValue
(
psz_request
,
"cancel"
,
psz_value
,
sizeof
(
psz_value
)
)
==
NULL
)
{
b_ok
=
true
;
}
if
(
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
==
false
)
{
mmi_object
.
u
.
answ
.
psz_answ
=
strdup
(
""
);
}
else
{
if
(
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
==
false
)
{
mmi_object
.
u
.
menu_answ
.
i_choice
=
0
;
}
else
{
if
(
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
);
}
}
en50221_SendMMIObject
(
p_cam
,
i_slot
,
&
mmi_object
);
return
;
}
/* Check that we have all necessary MMI information. */
for
(
unsigned
i_slot
=
0
;
i_slot
<
p_cam
->
i_nb_slots
;
i_slot
++
)
{
if
(
p_cam
->
pb_slot_mmi_expected
[
i_slot
]
==
true
)
return
;
}
p
=
p_sys
->
psz_mmi_info
=
malloc
(
10000
);
if
(
ioctl
(
p_cam
->
fd
,
CA_GET_CAP
,
&
caps
)
!=
0
)
{
char
buf
[
1000
];
strerror_r
(
errno
,
buf
,
sizeof
(
buf
)
);
p
+=
sprintf
(
p
,
"ioctl CA_GET_CAP failed (%s)
\n
"
,
buf
);
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
(
unsigned
i_slot
=
0
;
i_slot
<
p_cam
->
i_nb_slots
;
i_slot
++
)
{
ca_slot_info_t
sinfo
;
p_cam
->
pb_slot_mmi_undisplayed
[
i_slot
]
=
false
;
p
+=
sprintf
(
p
,
"<p>CA slot #%d: "
,
i_slot
);
sinfo
.
num
=
i_slot
;
if
(
ioctl
(
p_cam
->
fd
,
CA_GET_SLOT_INFO
,
&
sinfo
)
!=
0
)
{
char
buf
[
1000
];
strerror_r
(
errno
,
buf
,
sizeof
(
buf
)
);
p
+=
sprintf
(
p
,
"ioctl CA_GET_SLOT_INFO failed (%s)<br>
\n
"
,
buf
);
continue
;
}
#define CHECK_TYPE( x, s ) \
if ( sinfo.type & (CA_##x) ) \
p += sprintf( p, "%s", 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
=
en50221_GetMMIObject
(
p_cam
,
i_slot
);
p
+=
sprintf
(
p
,
"module present and ready<p>
\n
"
);
p
+=
sprintf
(
p
,
"<form action=index.html method=get>
\n
"
);
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
==
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
=
false
;
vlc_cond_signal
(
&
p_sys
->
httpd_cond
);
vlc_mutex_unlock
(
&
p_sys
->
httpd_mutex
);
}
#endif
...
...
@@ -1859,16 +1536,15 @@ out:
*****************************************************************************/
int
CAMSet
(
access_t
*
p_access
,
dvbpsi_pmt_t
*
p_pmt
)
{
cam_t
*
p_cam
=
&
p_access
->
p_sys
->
cam
;
cam_t
*
p_cam
=
p_access
->
p_sys
->
p_
cam
;
if
(
p_cam
->
fd
==
-
1
)
if
(
p_cam
==
NULL
)
{
dvbpsi_DeletePMT
(
p_pmt
);
return
VLC_EGENERIC
;
}
en50221_SetCAPMT
(
p_cam
,
p_pmt
);
return
VLC_SUCCESS
;
}
...
...
@@ -1877,11 +1553,8 @@ int CAMSet( access_t * p_access, dvbpsi_pmt_t *p_pmt )
*****************************************************************************/
void
CAMClose
(
access_t
*
p_access
)
{
cam_t
*
p_cam
=
&
p_access
->
p_sys
->
cam
;
if
(
p_cam
->
fd
==
-
1
)
return
;
cam_t
*
p_cam
=
p_access
->
p_sys
->
p_cam
;
en50221_End
(
p_cam
);
close
(
p_cam
->
fd
);
if
(
p_cam
!=
NULL
)
en50221_End
(
p_cam
);
}
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