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_AddPMT( uint8_t *p_pmt
);
73 void en50221_UpdatePMT( uint8_t *p_pmt
);
74 void en50221_DeletePMT( uint8_t *p_pmt
);
75 uint8_t en50221_StatusMMI( uint8_t *p_answer
, ssize_t
*pi_size
);
76 uint8_t en50221_StatusMMISlot( uint8_t *p_buffer
, ssize_t i_size
,
77 uint8_t *p_answer
, ssize_t
*pi_size
);
78 uint8_t en50221_OpenMMI( uint8_t *p_buffer
, ssize_t i_size
);
79 uint8_t en50221_CloseMMI( uint8_t *p_buffer
, ssize_t i_size
);
80 uint8_t en50221_GetMMIObject( uint8_t *p_buffer
, ssize_t i_size
,
81 uint8_t *p_answer
, ssize_t
*pi_size
);
82 uint8_t en50221_SendMMIObject( uint8_t *p_buffer
, ssize_t i_size
);
86 * This is where it gets scary: do not show to < 18 yrs old
89 /*****************************************************************************
90 * en50221_SerializeMMIObject :
91 *****************************************************************************/
92 static inline int en50221_SerializeMMIObject( uint8_t *p_answer
,
94 en50221_mmi_object_t
*p_object
)
96 ssize_t i_max_size
= *pi_size
;
97 en50221_mmi_object_t
*p_serialized
= (en50221_mmi_object_t
*)p_answer
;
101 #define STORE_MEMBER(pp_pointer, i_size) \
102 if ( i_size + *pi_size > i_max_size ) \
104 memcpy( p_answer, *pp_pointer, i_size ); \
105 *pp_pointer = (void *)*pi_size; \
106 *pi_size += i_size; \
109 if ( sizeof(en50221_mmi_object_t
) > i_max_size
)
111 memcpy( p_answer
, p_object
, sizeof(en50221_mmi_object_t
) );
112 *pi_size
= sizeof(en50221_mmi_object_t
);
113 p_answer
+= sizeof(en50221_mmi_object_t
);
115 switch ( p_object
->i_object_type
)
117 case EN50221_MMI_ENQ
:
118 STORE_MEMBER( &p_serialized
->u
.enq
.psz_text
,
119 strlen(p_object
->u
.enq
.psz_text
) + 1 );
122 case EN50221_MMI_ANSW
:
123 STORE_MEMBER( &p_serialized
->u
.answ
.psz_answ
,
124 strlen(p_object
->u
.answ
.psz_answ
) + 1 );
127 case EN50221_MMI_MENU
:
128 case EN50221_MMI_LIST
:
129 STORE_MEMBER( &p_serialized
->u
.menu
.psz_title
,
130 strlen(p_object
->u
.menu
.psz_title
) + 1 );
131 STORE_MEMBER( &p_serialized
->u
.menu
.psz_subtitle
,
132 strlen(p_object
->u
.menu
.psz_subtitle
) + 1 );
133 STORE_MEMBER( &p_serialized
->u
.menu
.psz_bottom
,
134 strlen(p_object
->u
.menu
.psz_bottom
) + 1 );
135 /* pointer alignment */
136 i
= ((*pi_size
+ 7) / 8) * 8 - *pi_size
;
139 pp_tmp
= (char **)p_answer
;
140 STORE_MEMBER( &p_serialized
->u
.menu
.ppsz_choices
,
141 p_object
->u
.menu
.i_choices
* sizeof(char *) );
143 for ( i
= 0; i
< p_object
->u
.menu
.i_choices
; i
++ )
145 STORE_MEMBER( &pp_tmp
[i
],
146 strlen(p_object
->u
.menu
.ppsz_choices
[i
]) + 1 );
157 /*****************************************************************************
158 * en50221_UnserializeMMIObject :
159 *****************************************************************************/
160 static inline int en50221_UnserializeMMIObject( en50221_mmi_object_t
*p_object
,
165 #define CHECK_MEMBER(pp_member) \
166 if ( (ptrdiff_t)*pp_member >= i_size ) \
168 for ( i = 0; ((char *)p_object + (ptrdiff_t)*pp_member)[i] != '\0'; \
170 if ( (ptrdiff_t)*pp_member + i >= i_size ) \
172 *pp_member += (ptrdiff_t)p_object;
174 switch ( p_object
->i_object_type
)
176 case EN50221_MMI_ENQ
:
177 CHECK_MEMBER(&p_object
->u
.enq
.psz_text
);
180 case EN50221_MMI_ANSW
:
181 CHECK_MEMBER(&p_object
->u
.answ
.psz_answ
);
184 case EN50221_MMI_MENU
:
185 case EN50221_MMI_LIST
:
186 CHECK_MEMBER(&p_object
->u
.menu
.psz_title
);
187 CHECK_MEMBER(&p_object
->u
.menu
.psz_subtitle
);
188 CHECK_MEMBER(&p_object
->u
.menu
.psz_bottom
);
189 if ( (ptrdiff_t)p_object
->u
.menu
.ppsz_choices
190 + p_object
->u
.menu
.i_choices
* sizeof(char *) >= i_size
)
192 p_object
->u
.menu
.ppsz_choices
= (char **)((char *)p_object
193 + (ptrdiff_t)p_object
->u
.menu
.ppsz_choices
);
195 for ( j
= 0; j
< p_object
->u
.menu
.i_choices
; j
++ )
197 CHECK_MEMBER(&p_object
->u
.menu
.ppsz_choices
[j
]);