#include <errno.h>
#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <time.h>
#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/poll.h>
+#include <poll.h>
#include <netinet/in.h>
/* DVB Card Drivers */
# include "descriptors/dr.h"
# include "psi.h"
# include "demux.h"
-# include "sdt.h"
+# include "tables/sdt.h"
#endif
#ifdef ENABLE_HTTPD
-# include "vlc_httpd.h"
+# include <vlc_httpd.h>
#endif
#include "dvb.h"
#undef DEBUG_TPDU
#define HLCI_WAIT_CAM_READY 0
#define CAM_PROG_MAX MAX_PROGRAMS
+//#define CAPMT_WAIT 100 /* uncomment this for slow CAMs */
static void ResourceManagerOpen( access_t * p_access, int i_session_id );
static void ApplicationInformationOpen( access_t * p_access, int i_session_id );
* Transport layer
*/
-#define MAX_TPDU_SIZE 2048
+#define MAX_TPDU_SIZE 4096
#define MAX_TPDU_DATA (MAX_TPDU_SIZE - 4)
#define DATA_INDICATOR 0x80
if ( pi_size == NULL )
{
- p_data = malloc( MAX_TPDU_SIZE );
+ p_data = xmalloc( MAX_TPDU_SIZE );
}
for ( ; ; )
if ( i_size < 5 )
{
msg_Err( p_access, "cannot read from CAM device (%d:%m)", i_size );
+ if( pi_size == NULL )
+ free( p_data );
return VLC_EGENERIC;
}
{
msg_Err( p_access, "invalid read from CAM device (%d instead of %d)",
p_data[1], i_tcid );
+ if( pi_size == NULL )
+ free( p_data );
return VLC_EGENERIC;
}
uint8_t *p_data, int i_size )
{
access_sys_t *p_sys = p_access->p_sys;
- uint8_t *p_spdu = malloc( i_size + 4 );
+ uint8_t *p_spdu = xmalloc( i_size + 4 );
uint8_t *p = p_spdu;
uint8_t i_tag;
uint8_t i_slot = p_sys->p_sessions[i_session_id - 1].i_slot;
static void SessionOpen( access_t * p_access, uint8_t i_slot,
uint8_t *p_spdu, int i_size )
{
+ VLC_UNUSED( i_size );
+
access_sys_t *p_sys = p_access->p_sys;
int i_session_id;
int i_resource_id = ResourceIdToInt( &p_spdu[2] );
if ( !p_sys->p_sessions[i_session_id - 1].i_resource_id )
break;
}
- if ( i_session_id == MAX_SESSIONS )
+ if ( i_session_id > MAX_SESSIONS )
{
msg_Err( p_access, "too many sessions !" );
return;
static void SessionCreateResponse( access_t * p_access, uint8_t i_slot,
uint8_t *p_spdu, int i_size )
{
+ VLC_UNUSED( i_size );
+ VLC_UNUSED( i_slot );
+
access_sys_t *p_sys = p_access->p_sys;
int i_status = p_spdu[2];
int i_resource_id = ResourceIdToInt( &p_spdu[3] );
uint8_t *p_data, int i_size )
{
access_sys_t *p_sys = p_access->p_sys;
- uint8_t *p_apdu = malloc( i_size + 12 );
+ uint8_t *p_apdu = xmalloc( i_size + 12 );
uint8_t *p = p_apdu;
ca_msg_t ca_msg;
int i_ret;
}
else
{
- char *psz_hex;
ca_msg.length = i_size + p - p_apdu;
if ( i_size == 0 ) ca_msg.length=3;
- psz_hex = (char*)malloc( ca_msg.length*3 + 1);
memcpy( ca_msg.msg, p_apdu, i_size + p - p_apdu );
i_ret = ioctl(p_sys->i_ca_handle, CA_SEND_MSG, &ca_msg );
if ( i_ret < 0 )
static void ApplicationInformationHandle( access_t * p_access, int i_session_id,
uint8_t *p_apdu, int i_size )
{
+ VLC_UNUSED(i_session_id);
int i_tag = APDUGetTag( p_apdu, i_size );
switch ( i_tag )
* Conditional Access
*/
-#define MAX_CASYSTEM_IDS 16
+#define MAX_CASYSTEM_IDS 64
typedef struct
{
static bool CheckSystemID( system_ids_t *p_ids, uint16_t i_id )
{
int i = 0;
- if( !p_ids ) return true;
+ if( !p_ids ) return true; /* dummy session for high-level CI intf */
while ( p_ids->pi_system_ids[i] )
{
uint8_t *p_data;
if ( i_size )
- p_data = malloc( 7 + i_size );
+ p_data = xmalloc( 7 + i_size );
else
- p_data = malloc( 6 );
+ p_data = xmalloc( 6 );
p_data[0] = i_list_mgt;
p_data[1] = i_program_number >> 8;
int i;
if ( i_size )
- p_data = realloc( p_capmt, i_capmt_size + 6 + i_size );
+ p_data = xrealloc( p_capmt, i_capmt_size + 6 + i_size );
else
- p_data = realloc( p_capmt, i_capmt_size + 5 );
+ p_data = xrealloc( p_capmt, i_capmt_size + 5 );
i = i_capmt_size;
0x3 /* only */, 0x1 /* ok_descrambling */,
&i_capmt_size );
- if ( i_capmt_size )
+ if( i_capmt_size )
+ {
APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );
+ free( p_capmt );
+ }
}
/*****************************************************************************
return;
}
+#ifdef CAPMT_WAIT
+ msleep( CAPMT_WAIT * 1000 );
+#endif
msg_Dbg( p_access, "adding CAPMT for SID %d on session %d",
p_pmt->i_program_number, i_session_id );
0x4 /* add */, 0x1 /* ok_descrambling */,
&i_capmt_size );
- if ( i_capmt_size )
+ if( i_capmt_size )
+ {
APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );
+ free( p_capmt );
+ }
}
/*****************************************************************************
0x5 /* update */, 0x1 /* ok_descrambling */,
&i_capmt_size );
- if ( i_capmt_size )
+ if( i_capmt_size )
+ {
APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );
+ free( p_capmt );
+ }
}
/*****************************************************************************
0x5 /* update */, 0x4 /* not selected */,
&i_capmt_size );
- if ( i_capmt_size )
+ if( i_capmt_size )
+ {
APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );
+ free( p_capmt );
+ }
}
/*****************************************************************************
p_sys->p_sessions[i_session_id - 1].pf_handle = ConditionalAccessHandle;
p_sys->p_sessions[i_session_id - 1].pf_close = ConditionalAccessClose;
- p_sys->p_sessions[i_session_id - 1].p_sys = malloc(sizeof(system_ids_t));
- memset( p_sys->p_sessions[i_session_id - 1].p_sys, 0,
- sizeof(system_ids_t) );
+ p_sys->p_sessions[i_session_id - 1].p_sys = calloc( 1, sizeof(system_ids_t) );
APDUSend( p_access, i_session_id, AOT_CA_INFO_ENQ, NULL, 0 );
}
p_sys->p_sessions[i_session_id - 1].pf_handle = DateTimeHandle;
p_sys->p_sessions[i_session_id - 1].pf_manage = DateTimeManage;
p_sys->p_sessions[i_session_id - 1].pf_close = DateTimeClose;
- p_sys->p_sessions[i_session_id - 1].p_sys = malloc(sizeof(date_time_t));
- memset( p_sys->p_sessions[i_session_id - 1].p_sys, 0, sizeof(date_time_t) );
+ p_sys->p_sessions[i_session_id - 1].p_sys = calloc( 1, sizeof(date_time_t) );
DateTimeSend( p_access, i_session_id );
}
case EN50221_MMI_ANSW:
i_tag = AOT_ANSW;
i_size = 1 + strlen( p_object->u.answ.psz_answ );
- p_data = malloc( i_size );
+ p_data = xmalloc( i_size );
p_data[0] = (p_object->u.answ.b_ok == true) ? 0x1 : 0x0;
strncpy( (char *)&p_data[1], p_object->u.answ.psz_answ, i_size - 1 );
break;
case EN50221_MMI_MENU_ANSW:
i_tag = AOT_MENU_ANSW;
i_size = 1;
- p_data = malloc( i_size );
+ p_data = xmalloc( i_size );
p_data[0] = p_object->u.menu_answ.i_choice;
break;
static void MMIHandleEnq( access_t *p_access, int i_session_id,
uint8_t *p_apdu, int i_size )
{
+ VLC_UNUSED( i_size );
+
access_sys_t *p_sys = p_access->p_sys;
mmi_t *p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys;
int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot;
p_mmi->last_object.u.enq.b_blind = (*d & 0x1) ? true : false;
d += 2; /* skip answer_text_length because it is not mandatory */
l -= 2;
- p_mmi->last_object.u.enq.psz_text = malloc( l + 1 );
+ p_mmi->last_object.u.enq.psz_text = xmalloc( l + 1 );
strncpy( p_mmi->last_object.u.enq.psz_text, (char *)d, l );
p_mmi->last_object.u.enq.psz_text[l] = '\0';
static void MMIHandleMenu( access_t *p_access, int i_session_id, int i_tag,
uint8_t *p_apdu, int i_size )
{
+ VLC_UNUSED(i_size);
access_sys_t *p_sys = p_access->p_sys;
mmi_t *p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys;
int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot;
p_sys->p_sessions[i_session_id - 1].pf_handle = MMIHandle;
p_sys->p_sessions[i_session_id - 1].pf_close = MMIClose;
- p_sys->p_sessions[i_session_id - 1].p_sys = malloc(sizeof(mmi_t));
+ p_sys->p_sessions[i_session_id - 1].p_sys = xmalloc(sizeof(mmi_t));
p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys;
p_mmi->last_object.i_object_type = EN50221_MMI_NONE;
}
return p;
}
-char *dvbsi_to_utf8( char *psz_instring, size_t i_length )
+char *dvbsi_to_utf8( const char *psz_instring, size_t i_length )
{
const char *psz_encoding, *psz_stringstart;
char *psz_outstring, *psz_tmp;
iconv_handle = vlc_iconv_open( "UTF-8", psz_encoding );
i_in = i_length - (psz_stringstart - psz_instring );
i_out = i_in * 6;
- psz_outstring = psz_tmp = (char*)malloc( i_out * sizeof(char) + 1 );
+ psz_outstring = psz_tmp = (char*)xmalloc( i_out + 1 );
vlc_iconv( iconv_handle, &psz_stringstart, &i_in, &psz_tmp, &i_out );
vlc_iconv_close( iconv_handle );
*psz_tmp = '\0';