Factor out common code
[dvblast.git] / en50221.h
blobdcfadb15d127aca988755f3601c0b87387e6c1db
1 /*****************************************************************************
2 * en50221.h
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 *****************************************************************************/
15 #include <malloc.h>
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
31 int i_object_type;
33 union
35 struct
37 int b_blind;
38 char *psz_text;
39 } enq;
41 struct
43 int b_ok;
44 char *psz_answ;
45 } answ;
47 struct
49 char *psz_title, *psz_subtitle, *psz_bottom;
50 char **ppsz_choices;
51 int i_choices;
52 } menu; /* menu and list are the same */
54 struct
56 int i_choice;
57 } menu_answ;
58 } u;
59 } en50221_mmi_object_t;
61 #define MAX_CI_SLOTS 16
62 #define MAX_SESSIONS 32
64 extern int i_ca_handle;
65 extern int i_ca_type;
67 /*****************************************************************************
68 * Prototypes
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,
95 ssize_t *pi_size,
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;
100 char **pp_tmp;
101 int i;
103 #define STORE_MEMBER(pp_pointer, i_size) \
104 if ( i_size + *pi_size > i_max_size ) \
105 return -1; \
106 memcpy( p_answer, *pp_pointer, i_size ); \
107 *pp_pointer = (void *)*pi_size; \
108 *pi_size += i_size; \
109 p_answer += i_size;
111 if ( sizeof(en50221_mmi_object_t) > i_max_size )
112 return -1;
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 );
122 break;
124 case EN50221_MMI_ANSW:
125 STORE_MEMBER( &p_serialized->u.answ.psz_answ,
126 strlen(p_object->u.answ.psz_answ) + 1 );
127 break;
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;
139 *pi_size += i;
140 p_answer += i;
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 );
150 break;
152 default:
153 break;
156 return 0;
159 /*****************************************************************************
160 * en50221_UnserializeMMIObject :
161 *****************************************************************************/
162 static inline int en50221_UnserializeMMIObject( en50221_mmi_object_t *p_object,
163 ssize_t i_size )
165 int i, j;
167 #define CHECK_MEMBER(pp_member) \
168 if ( (ptrdiff_t)*pp_member >= i_size ) \
169 return -1; \
170 for ( i = 0; ((char *)p_object + (ptrdiff_t)*pp_member)[i] != '\0'; \
171 i++ ) \
172 if ( (ptrdiff_t)*pp_member + i >= i_size ) \
173 return -1; \
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);
180 break;
182 case EN50221_MMI_ANSW:
183 CHECK_MEMBER(&p_object->u.answ.psz_answ);
184 break;
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 )
193 return -1;
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]);
201 break;
203 default:
204 break;
207 return 0;