* demux.c: Rebuild the PAT when changing the output configuration (DVB->non-DVB)...
[dvblast.git] / en50221.h
blobea42792ef3b82d8fc18389db9e996a3cd81e4601
1 /*****************************************************************************
2 * en50221.h
3 *****************************************************************************
4 * Copyright (C) 2008 VideoLAN
5 * $Id$
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 *****************************************************************************/
24 #include <malloc.h>
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
40 int i_object_type;
42 union
44 struct
46 int b_blind;
47 char *psz_text;
48 } enq;
50 struct
52 int b_ok;
53 char *psz_answ;
54 } answ;
56 struct
58 char *psz_title, *psz_subtitle, *psz_bottom;
59 char **ppsz_choices;
60 int i_choices;
61 } menu; /* menu and list are the same */
63 struct
65 int i_choice;
66 } menu_answ;
67 } u;
68 } en50221_mmi_object_t;
70 #define MAX_CI_SLOTS 16
71 #define MAX_SESSIONS 32
73 extern int i_ca_handle;
74 extern int i_ca_type;
76 /*****************************************************************************
77 * Prototypes
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,
104 ssize_t *pi_size,
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;
109 char **pp_tmp;
110 int i;
112 #define STORE_MEMBER(pp_pointer, i_size) \
113 if ( i_size + *pi_size > i_max_size ) \
114 return -1; \
115 memcpy( p_answer, *pp_pointer, i_size ); \
116 *pp_pointer = (void *)*pi_size; \
117 *pi_size += i_size; \
118 p_answer += i_size;
120 if ( sizeof(en50221_mmi_object_t) > i_max_size )
121 return -1;
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 );
131 break;
133 case EN50221_MMI_ANSW:
134 STORE_MEMBER( &p_serialized->u.answ.psz_answ,
135 strlen(p_object->u.answ.psz_answ) + 1 );
136 break;
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;
148 *pi_size += i;
149 p_answer += i;
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 );
159 break;
161 default:
162 break;
165 return 0;
168 /*****************************************************************************
169 * en50221_UnserializeMMIObject :
170 *****************************************************************************/
171 static inline int en50221_UnserializeMMIObject( en50221_mmi_object_t *p_object,
172 ssize_t i_size )
174 int i, j;
176 #define CHECK_MEMBER(pp_member) \
177 if ( (ptrdiff_t)*pp_member >= i_size ) \
178 return -1; \
179 for ( i = 0; ((char *)p_object + (ptrdiff_t)*pp_member)[i] != '\0'; \
180 i++ ) \
181 if ( (ptrdiff_t)*pp_member + i >= i_size ) \
182 return -1; \
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);
189 break;
191 case EN50221_MMI_ANSW:
192 CHECK_MEMBER(&p_object->u.answ.psz_answ);
193 break;
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 )
202 return -1;
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]);
210 break;
212 default:
213 break;
216 return 0;