📄 en50221.c
字号:
/***************************************************************************** * CAPMTNeedsDescrambling *****************************************************************************/static vlc_bool_t CAPMTNeedsDescrambling( dvbpsi_pmt_t *p_pmt ){ dvbpsi_descriptor_t *p_dr; dvbpsi_pmt_es_t *p_es; for( p_dr = p_pmt->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next ) { if( p_dr->i_tag == 0x9 ) { return VLC_TRUE; } } for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next ) { for( p_dr = p_es->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next ) { if( p_dr->i_tag == 0x9 ) { return VLC_TRUE; } } } return VLC_FALSE;}/***************************************************************************** * CAPMTBuild *****************************************************************************/static int GetCADSize( system_ids_t *p_ids, dvbpsi_descriptor_t *p_dr ){ int i_cad_size = 0; while ( p_dr != NULL ) { if( p_dr->i_tag == 0x9 ) { uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8) | p_dr->p_data[1]; if ( CheckSystemID( p_ids, i_sysid ) ) i_cad_size += p_dr->i_length + 2; } p_dr = p_dr->p_next; } return i_cad_size;}static uint8_t *CAPMTHeader( system_ids_t *p_ids, uint8_t i_list_mgt, uint16_t i_program_number, uint8_t i_version, int i_size, dvbpsi_descriptor_t *p_dr, uint8_t i_cmd ){ uint8_t *p_data; if ( i_size ) p_data = malloc( 7 + i_size ); else p_data = malloc( 6 ); p_data[0] = i_list_mgt; p_data[1] = i_program_number >> 8; p_data[2] = i_program_number & 0xff; p_data[3] = ((i_version & 0x1f) << 1) | 0x1; if ( i_size ) { int i; p_data[4] = (i_size + 1) >> 8; p_data[5] = (i_size + 1) & 0xff; p_data[6] = i_cmd; i = 7; while ( p_dr != NULL ) { if( p_dr->i_tag == 0x9 ) { uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8) | p_dr->p_data[1]; if ( CheckSystemID( p_ids, i_sysid ) ) { p_data[i] = 0x9; p_data[i + 1] = p_dr->i_length; memcpy( &p_data[i + 2], p_dr->p_data, p_dr->i_length ); i += p_dr->i_length + 2; } } p_dr = p_dr->p_next; } } else { p_data[4] = 0; p_data[5] = 0; } return p_data;}static uint8_t *CAPMTES( system_ids_t *p_ids, uint8_t *p_capmt, int i_capmt_size, uint8_t i_type, uint16_t i_pid, int i_size, dvbpsi_descriptor_t *p_dr, uint8_t i_cmd ){ uint8_t *p_data; int i; if ( i_size ) p_data = realloc( p_capmt, i_capmt_size + 6 + i_size ); else p_data = realloc( p_capmt, i_capmt_size + 5 ); i = i_capmt_size; p_data[i] = i_type; p_data[i + 1] = i_pid >> 8; p_data[i + 2] = i_pid & 0xff; if ( i_size ) { p_data[i + 3] = (i_size + 1) >> 8; p_data[i + 4] = (i_size + 1) & 0xff; p_data[i + 5] = i_cmd; i += 6; while ( p_dr != NULL ) { if( p_dr->i_tag == 0x9 ) { uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8) | p_dr->p_data[1]; if ( CheckSystemID( p_ids, i_sysid ) ) { p_data[i] = 0x9; p_data[i + 1] = p_dr->i_length; memcpy( &p_data[i + 2], p_dr->p_data, p_dr->i_length ); i += p_dr->i_length + 2; } } p_dr = p_dr->p_next; } } else { p_data[i + 3] = 0; p_data[i + 4] = 0; } return p_data;}static uint8_t *CAPMTBuild( access_t * p_access, int i_session_id, dvbpsi_pmt_t *p_pmt, uint8_t i_list_mgt, uint8_t i_cmd, int *pi_capmt_size ){ access_sys_t *p_sys = p_access->p_sys; system_ids_t *p_ids = (system_ids_t *)p_sys->p_sessions[i_session_id - 1].p_sys; dvbpsi_pmt_es_t *p_es; int i_cad_size, i_cad_program_size; uint8_t *p_capmt; i_cad_size = i_cad_program_size = GetCADSize( p_ids, p_pmt->p_first_descriptor ); for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next ) { i_cad_size += GetCADSize( p_ids, p_es->p_first_descriptor ); } if ( !i_cad_size ) { msg_Warn( p_access, "no compatible scrambling system for SID %d on session %d", p_pmt->i_program_number, i_session_id ); *pi_capmt_size = 0; return NULL; } p_capmt = CAPMTHeader( p_ids, i_list_mgt, p_pmt->i_program_number, p_pmt->i_version, i_cad_program_size, p_pmt->p_first_descriptor, i_cmd ); if ( i_cad_program_size ) *pi_capmt_size = 7 + i_cad_program_size; else *pi_capmt_size = 6; for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next ) { i_cad_size = GetCADSize( p_ids, p_es->p_first_descriptor ); if ( i_cad_size || i_cad_program_size ) { p_capmt = CAPMTES( p_ids, p_capmt, *pi_capmt_size, p_es->i_type, p_es->i_pid, i_cad_size, p_es->p_first_descriptor, i_cmd ); if ( i_cad_size ) *pi_capmt_size += 6 + i_cad_size; else *pi_capmt_size += 5; } } return p_capmt;}/***************************************************************************** * CAPMTFirst *****************************************************************************/static void CAPMTFirst( access_t * p_access, int i_session_id, dvbpsi_pmt_t *p_pmt ){ uint8_t *p_capmt; int i_capmt_size; msg_Dbg( p_access, "adding first CAPMT for SID %d on session %d", p_pmt->i_program_number, i_session_id ); p_capmt = CAPMTBuild( p_access, i_session_id, p_pmt, 0x3 /* only */, 0x1 /* ok_descrambling */, &i_capmt_size ); if ( i_capmt_size ) APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );}/***************************************************************************** * CAPMTAdd *****************************************************************************/static void CAPMTAdd( access_t * p_access, int i_session_id, dvbpsi_pmt_t *p_pmt ){ uint8_t *p_capmt; int i_capmt_size; msg_Dbg( p_access, "adding CAPMT for SID %d on session %d", p_pmt->i_program_number, i_session_id ); p_capmt = CAPMTBuild( p_access, i_session_id, p_pmt, 0x4 /* add */, 0x1 /* ok_descrambling */, &i_capmt_size ); if ( i_capmt_size ) APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );}/***************************************************************************** * CAPMTUpdate *****************************************************************************/static void CAPMTUpdate( access_t * p_access, int i_session_id, dvbpsi_pmt_t *p_pmt ){ uint8_t *p_capmt; int i_capmt_size; msg_Dbg( p_access, "updating CAPMT for SID %d on session %d", p_pmt->i_program_number, i_session_id ); p_capmt = CAPMTBuild( p_access, i_session_id, p_pmt, 0x5 /* update */, 0x1 /* ok_descrambling */, &i_capmt_size ); if ( i_capmt_size ) APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );}/***************************************************************************** * CAPMTDelete *****************************************************************************/static void CAPMTDelete( access_t * p_access, int i_session_id, dvbpsi_pmt_t *p_pmt ){ uint8_t *p_capmt; int i_capmt_size; msg_Dbg( p_access, "deleting CAPMT for SID %d on session %d", p_pmt->i_program_number, i_session_id ); p_capmt = CAPMTBuild( p_access, i_session_id, p_pmt, 0x5 /* update */, 0x4 /* not selected */, &i_capmt_size ); if ( i_capmt_size ) APDUSend( p_access, i_session_id, AOT_CA_PMT, p_capmt, i_capmt_size );}/***************************************************************************** * ConditionalAccessHandle *****************************************************************************/static void ConditionalAccessHandle( access_t * p_access, int i_session_id, uint8_t *p_apdu, int i_size ){ access_sys_t *p_sys = p_access->p_sys; system_ids_t *p_ids = (system_ids_t *)p_sys->p_sessions[i_session_id - 1].p_sys; int i_tag = APDUGetTag( p_apdu, i_size ); switch ( i_tag ) { case AOT_CA_INFO: { vlc_bool_t b_inited = VLC_FALSE; int i; int l = 0; uint8_t *d = APDUGetLength( p_apdu, &l ); msg_Dbg( p_access, "CA system IDs supported by the application :" ); for ( i = 0; i < l / 2; i++ ) { p_ids->pi_system_ids[i] = ((uint16_t)d[0] << 8) | d[1]; d += 2; msg_Dbg( p_access, "- 0x%x", p_ids->pi_system_ids[i] ); } p_ids->pi_system_ids[i] = 0; for ( i = 0; i < MAX_PROGRAMS; i++ ) { if ( p_sys->pp_selected_programs[i] != NULL ) { if ( b_inited ) CAPMTAdd( p_access, i_session_id, p_sys->pp_selected_programs[i] ); else CAPMTFirst( p_access, i_session_id, p_sys->pp_selected_programs[i] ); b_inited = VLC_TRUE; } } break; } default: msg_Err( p_access, "unexpected tag in ConditionalAccessHandle (0x%x)", i_tag ); }}/***************************************************************************** * ConditionalAccessOpen *****************************************************************************/static void ConditionalAccessOpen( access_t * p_access, int i_session_id ){ access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_access, "opening ConditionalAccess session (%d)", i_session_id ); p_sys->p_sessions[i_session_id - 1].pf_handle = ConditionalAccessHandle; 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) ); APDUSend( p_access, i_session_id, AOT_CA_INFO_ENQ, NULL, 0 );}/* * Date Time */typedef struct{ int i_interval; mtime_t i_last;} date_time_t;/***************************************************************************** * DateTimeSend *****************************************************************************/static void DateTimeSend( access_t * p_access, int i_session_id ){ access_sys_t *p_sys = p_access->p_sys; date_time_t *p_date = (date_time_t *)p_sys->p_sessions[i_session_id - 1].p_sys; time_t t = time(NULL); struct tm tm_gmt; struct tm tm_loc; if ( gmtime_r(&t, &tm_gmt) && localtime_r(&t, &tm_loc) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -