1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2008 VideoLAN
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
8 * This program is free software. It comes without any warranty, to
9 * the extent permitted by applicable law. You can redistribute it
10 * and/or modify it under the terms of the Do What The Fuck You Want
11 * To Public License, Version 2, as published by Sam Hocevar. See
12 * http://sam.zoy.org/wtfpl/COPYING for more details.
13 *****************************************************************************/
17 typedef void * access_t
;
19 #define STRINGIFY( z ) UGLY_KLUDGE( z )
20 #define UGLY_KLUDGE( z ) #z
22 #define EN50221_MMI_NONE 0
23 #define EN50221_MMI_ENQ 1
24 #define EN50221_MMI_ANSW 2
25 #define EN50221_MMI_MENU 3
26 #define EN50221_MMI_MENU_ANSW 4
27 #define EN50221_MMI_LIST 5
29 typedef struct en50221_mmi_object_t
49 char *psz_title
, *psz_subtitle
, *psz_bottom
;
52 } menu
; /* menu and list are the same */
59 } en50221_mmi_object_t
;
61 #define MAX_CI_SLOTS 16
62 #define MAX_SESSIONS 32
64 extern int i_ca_handle
;
67 /*****************************************************************************
69 *****************************************************************************/
70 void en50221_Init( void );
71 void en50221_Reset( void );
72 void en50221_Read( void );
73 void en50221_Poll( void );
74 void en50221_AddPMT( uint8_t *p_pmt
);
75 void en50221_UpdatePMT( uint8_t *p_pmt
);
76 void en50221_DeletePMT( uint8_t *p_pmt
);
77 uint8_t en50221_StatusMMI( uint8_t *p_answer
, ssize_t
*pi_size
);
78 uint8_t en50221_StatusMMISlot( uint8_t *p_buffer
, ssize_t i_size
,
79 uint8_t *p_answer
, ssize_t
*pi_size
);
80 uint8_t en50221_OpenMMI( uint8_t *p_buffer
, ssize_t i_size
);
81 uint8_t en50221_CloseMMI( uint8_t *p_buffer
, ssize_t i_size
);
82 uint8_t en50221_GetMMIObject( uint8_t *p_buffer
, ssize_t i_size
,
83 uint8_t *p_answer
, ssize_t
*pi_size
);
84 uint8_t en50221_SendMMIObject( uint8_t *p_buffer
, ssize_t i_size
);
88 * This is where it gets scary: do not show to < 18 yrs old
91 /*****************************************************************************
92 * en50221_SerializeMMIObject :
93 *****************************************************************************/
94 static inline int en50221_SerializeMMIObject( uint8_t *p_answer
,
96 en50221_mmi_object_t
*p_object
)
98 ssize_t i_max_size
= *pi_size
;
99 en50221_mmi_object_t
*p_serialized
= (en50221_mmi_object_t
*)p_answer
;
103 #define STORE_MEMBER(pp_pointer, i_size) \
104 if ( i_size + *pi_size > i_max_size ) \
106 memcpy( p_answer, *pp_pointer, i_size ); \
107 *pp_pointer = (void *)*pi_size; \
108 *pi_size += i_size; \
111 if ( sizeof(en50221_mmi_object_t
) > i_max_size
)
113 memcpy( p_answer
, p_object
, sizeof(en50221_mmi_object_t
) );
114 *pi_size
= sizeof(en50221_mmi_object_t
);
115 p_answer
+= sizeof(en50221_mmi_object_t
);
117 switch ( p_object
->i_object_type
)
119 case EN50221_MMI_ENQ
:
120 STORE_MEMBER( &p_serialized
->u
.enq
.psz_text
,
121 strlen(p_object
->u
.enq
.psz_text
) + 1 );
124 case EN50221_MMI_ANSW
:
125 STORE_MEMBER( &p_serialized
->u
.answ
.psz_answ
,
126 strlen(p_object
->u
.answ
.psz_answ
) + 1 );
129 case EN50221_MMI_MENU
:
130 case EN50221_MMI_LIST
:
131 STORE_MEMBER( &p_serialized
->u
.menu
.psz_title
,
132 strlen(p_object
->u
.menu
.psz_title
) + 1 );
133 STORE_MEMBER( &p_serialized
->u
.menu
.psz_subtitle
,
134 strlen(p_object
->u
.menu
.psz_subtitle
) + 1 );
135 STORE_MEMBER( &p_serialized
->u
.menu
.psz_bottom
,
136 strlen(p_object
->u
.menu
.psz_bottom
) + 1 );
137 /* pointer alignment */
138 i
= ((*pi_size
+ 7) / 8) * 8 - *pi_size
;
141 pp_tmp
= (char **)p_answer
;
142 STORE_MEMBER( &p_serialized
->u
.menu
.ppsz_choices
,
143 p_object
->u
.menu
.i_choices
* sizeof(char *) );
145 for ( i
= 0; i
< p_object
->u
.menu
.i_choices
; i
++ )
147 STORE_MEMBER( &pp_tmp
[i
],
148 strlen(p_object
->u
.menu
.ppsz_choices
[i
]) + 1 );
159 /*****************************************************************************
160 * en50221_UnserializeMMIObject :
161 *****************************************************************************/
162 static inline int en50221_UnserializeMMIObject( en50221_mmi_object_t
*p_object
,
167 #define CHECK_MEMBER(pp_member) \
168 if ( (ptrdiff_t)*pp_member >= i_size ) \
170 for ( i = 0; ((char *)p_object + (ptrdiff_t)*pp_member)[i] != '\0'; \
172 if ( (ptrdiff_t)*pp_member + i >= i_size ) \
174 *pp_member += (ptrdiff_t)p_object;
176 switch ( p_object
->i_object_type
)
178 case EN50221_MMI_ENQ
:
179 CHECK_MEMBER(&p_object
->u
.enq
.psz_text
);
182 case EN50221_MMI_ANSW
:
183 CHECK_MEMBER(&p_object
->u
.answ
.psz_answ
);
186 case EN50221_MMI_MENU
:
187 case EN50221_MMI_LIST
:
188 CHECK_MEMBER(&p_object
->u
.menu
.psz_title
);
189 CHECK_MEMBER(&p_object
->u
.menu
.psz_subtitle
);
190 CHECK_MEMBER(&p_object
->u
.menu
.psz_bottom
);
191 if ( (ptrdiff_t)p_object
->u
.menu
.ppsz_choices
192 + p_object
->u
.menu
.i_choices
* sizeof(char *) >= i_size
)
194 p_object
->u
.menu
.ppsz_choices
= (char **)((char *)p_object
195 + (ptrdiff_t)p_object
->u
.menu
.ppsz_choices
);
197 for ( j
= 0; j
< p_object
->u
.menu
.i_choices
; j
++ )
199 CHECK_MEMBER(&p_object
->u
.menu
.ppsz_choices
[j
]);