Add new option --udp-lock-timeout.
[dvblast.git] / en50221.h
blobeb120329d99ccf7ef2d354541cc1f3da5bd97319
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 <stddef.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_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,
93 ssize_t *pi_size,
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;
98 char **pp_tmp;
99 int i;
101 #define STORE_MEMBER(pp_pointer, i_size) \
102 if ( i_size + *pi_size > i_max_size ) \
103 return -1; \
104 memcpy( p_answer, *pp_pointer, i_size ); \
105 *pp_pointer = (void *)*pi_size; \
106 *pi_size += i_size; \
107 p_answer += i_size;
109 if ( sizeof(en50221_mmi_object_t) > i_max_size )
110 return -1;
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 );
120 break;
122 case EN50221_MMI_ANSW:
123 STORE_MEMBER( &p_serialized->u.answ.psz_answ,
124 strlen(p_object->u.answ.psz_answ) + 1 );
125 break;
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;
137 *pi_size += i;
138 p_answer += i;
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 );
148 break;
150 default:
151 break;
154 return 0;
157 /*****************************************************************************
158 * en50221_UnserializeMMIObject :
159 *****************************************************************************/
160 static inline int en50221_UnserializeMMIObject( en50221_mmi_object_t *p_object,
161 ssize_t i_size )
163 int i, j;
165 #define CHECK_MEMBER(pp_member) \
166 if ( (ptrdiff_t)*pp_member >= i_size ) \
167 return -1; \
168 for ( i = 0; ((char *)p_object + (ptrdiff_t)*pp_member)[i] != '\0'; \
169 i++ ) \
170 if ( (ptrdiff_t)*pp_member + i >= i_size ) \
171 return -1; \
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);
178 break;
180 case EN50221_MMI_ANSW:
181 CHECK_MEMBER(&p_object->u.answ.psz_answ);
182 break;
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 )
191 return -1;
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]);
199 break;
201 default:
202 break;
205 return 0;