1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2008 VideoLAN
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
26 typedef void * access_t
;
28 #define STRINGIFY( z ) UGLY_KLUDGE( z )
29 #define UGLY_KLUDGE( z ) #z
31 #define EN50221_MMI_NONE 0
32 #define EN50221_MMI_ENQ 1
33 #define EN50221_MMI_ANSW 2
34 #define EN50221_MMI_MENU 3
35 #define EN50221_MMI_MENU_ANSW 4
36 #define EN50221_MMI_LIST 5
38 typedef struct en50221_mmi_object_t
58 char *psz_title
, *psz_subtitle
, *psz_bottom
;
61 } menu
; /* menu and list are the same */
68 } en50221_mmi_object_t
;
70 #define MAX_CI_SLOTS 16
71 #define MAX_SESSIONS 32
73 extern int i_ca_handle
;
76 /*****************************************************************************
78 *****************************************************************************/
79 void en50221_Init( void );
80 void en50221_Reset( void );
81 void en50221_Read( void );
82 void en50221_Poll( void );
83 void en50221_AddPMT( uint8_t *p_pmt
);
84 void en50221_UpdatePMT( uint8_t *p_pmt
);
85 void en50221_DeletePMT( uint8_t *p_pmt
);
86 uint8_t en50221_StatusMMI( uint8_t *p_answer
, ssize_t
*pi_size
);
87 uint8_t en50221_StatusMMISlot( uint8_t *p_buffer
, ssize_t i_size
,
88 uint8_t *p_answer
, ssize_t
*pi_size
);
89 uint8_t en50221_OpenMMI( uint8_t *p_buffer
, ssize_t i_size
);
90 uint8_t en50221_CloseMMI( uint8_t *p_buffer
, ssize_t i_size
);
91 uint8_t en50221_GetMMIObject( uint8_t *p_buffer
, ssize_t i_size
,
92 uint8_t *p_answer
, ssize_t
*pi_size
);
93 uint8_t en50221_SendMMIObject( uint8_t *p_buffer
, ssize_t i_size
);
97 * This is where it gets scary: do not show to < 18 yrs old
100 /*****************************************************************************
101 * en50221_SerializeMMIObject :
102 *****************************************************************************/
103 static inline int en50221_SerializeMMIObject( uint8_t *p_answer
,
105 en50221_mmi_object_t
*p_object
)
107 ssize_t i_max_size
= *pi_size
;
108 en50221_mmi_object_t
*p_serialized
= (en50221_mmi_object_t
*)p_answer
;
112 #define STORE_MEMBER(pp_pointer, i_size) \
113 if ( i_size + *pi_size > i_max_size ) \
115 memcpy( p_answer, *pp_pointer, i_size ); \
116 *pp_pointer = (void *)*pi_size; \
117 *pi_size += i_size; \
120 if ( sizeof(en50221_mmi_object_t
) > i_max_size
)
122 memcpy( p_answer
, p_object
, sizeof(en50221_mmi_object_t
) );
123 *pi_size
= sizeof(en50221_mmi_object_t
);
124 p_answer
+= sizeof(en50221_mmi_object_t
);
126 switch ( p_object
->i_object_type
)
128 case EN50221_MMI_ENQ
:
129 STORE_MEMBER( &p_serialized
->u
.enq
.psz_text
,
130 strlen(p_object
->u
.enq
.psz_text
) + 1 );
133 case EN50221_MMI_ANSW
:
134 STORE_MEMBER( &p_serialized
->u
.answ
.psz_answ
,
135 strlen(p_object
->u
.answ
.psz_answ
) + 1 );
138 case EN50221_MMI_MENU
:
139 case EN50221_MMI_LIST
:
140 STORE_MEMBER( &p_serialized
->u
.menu
.psz_title
,
141 strlen(p_object
->u
.menu
.psz_title
) + 1 );
142 STORE_MEMBER( &p_serialized
->u
.menu
.psz_subtitle
,
143 strlen(p_object
->u
.menu
.psz_subtitle
) + 1 );
144 STORE_MEMBER( &p_serialized
->u
.menu
.psz_bottom
,
145 strlen(p_object
->u
.menu
.psz_bottom
) + 1 );
146 /* pointer alignment */
147 i
= ((*pi_size
+ 7) / 8) * 8 - *pi_size
;
150 pp_tmp
= (char **)p_answer
;
151 STORE_MEMBER( &p_serialized
->u
.menu
.ppsz_choices
,
152 p_object
->u
.menu
.i_choices
* sizeof(char *) );
154 for ( i
= 0; i
< p_object
->u
.menu
.i_choices
; i
++ )
156 STORE_MEMBER( &pp_tmp
[i
],
157 strlen(p_object
->u
.menu
.ppsz_choices
[i
]) + 1 );
168 /*****************************************************************************
169 * en50221_UnserializeMMIObject :
170 *****************************************************************************/
171 static inline int en50221_UnserializeMMIObject( en50221_mmi_object_t
*p_object
,
176 #define CHECK_MEMBER(pp_member) \
177 if ( (ptrdiff_t)*pp_member >= i_size ) \
179 for ( i = 0; ((char *)p_object + (ptrdiff_t)*pp_member)[i] != '\0'; \
181 if ( (ptrdiff_t)*pp_member + i >= i_size ) \
183 *pp_member += (ptrdiff_t)p_object;
185 switch ( p_object
->i_object_type
)
187 case EN50221_MMI_ENQ
:
188 CHECK_MEMBER(&p_object
->u
.enq
.psz_text
);
191 case EN50221_MMI_ANSW
:
192 CHECK_MEMBER(&p_object
->u
.answ
.psz_answ
);
195 case EN50221_MMI_MENU
:
196 case EN50221_MMI_LIST
:
197 CHECK_MEMBER(&p_object
->u
.menu
.psz_title
);
198 CHECK_MEMBER(&p_object
->u
.menu
.psz_subtitle
);
199 CHECK_MEMBER(&p_object
->u
.menu
.psz_bottom
);
200 if ( (ptrdiff_t)p_object
->u
.menu
.ppsz_choices
201 + p_object
->u
.menu
.i_choices
* sizeof(char *) >= i_size
)
203 p_object
->u
.menu
.ppsz_choices
= (char **)((char *)p_object
204 + (ptrdiff_t)p_object
->u
.menu
.ppsz_choices
);
206 for ( j
= 0; j
< p_object
->u
.menu
.i_choices
; j
++ )
208 CHECK_MEMBER(&p_object
->u
.menu
.ppsz_choices
[j
]);