📄 en50221.c
字号:
* Resource Manager *//***************************************************************************** * ResourceManagerHandle *****************************************************************************/static void ResourceManagerHandle( access_t * p_access, int i_session_id, uint8_t *p_apdu, int i_size ){ int i_tag = APDUGetTag( p_apdu, i_size ); switch ( i_tag ) { case AOT_PROFILE_ENQ: { int resources[] = { htonl(RI_RESOURCE_MANAGER), htonl(RI_APPLICATION_INFORMATION), htonl(RI_CONDITIONAL_ACCESS_SUPPORT), htonl(RI_DATE_TIME), htonl(RI_MMI) }; APDUSend( p_access, i_session_id, AOT_PROFILE, (uint8_t*)resources, sizeof(resources) ); break; } case AOT_PROFILE: APDUSend( p_access, i_session_id, AOT_PROFILE_CHANGE, NULL, 0 ); break; default: msg_Err( p_access, "unexpected tag in ResourceManagerHandle (0x%x)", i_tag ); }}/***************************************************************************** * ResourceManagerOpen *****************************************************************************/static void ResourceManagerOpen( access_t * p_access, int i_session_id ){ access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_access, "opening ResourceManager session (%d)", i_session_id ); p_sys->p_sessions[i_session_id - 1].pf_handle = ResourceManagerHandle; APDUSend( p_access, i_session_id, AOT_PROFILE_ENQ, NULL, 0 );}/* * Application Information *//***************************************************************************** * ApplicationInformationEnterMenu *****************************************************************************/static void ApplicationInformationEnterMenu( access_t * p_access, int i_session_id ){ access_sys_t *p_sys = p_access->p_sys; int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot; msg_Dbg( p_access, "entering MMI menus on session %d", i_session_id ); APDUSend( p_access, i_session_id, AOT_ENTER_MENU, NULL, 0 ); p_sys->pb_slot_mmi_expected[i_slot] = true;}/***************************************************************************** * ApplicationInformationHandle *****************************************************************************/static void ApplicationInformationHandle( access_t * p_access, int i_session_id, uint8_t *p_apdu, int i_size ){ int i_tag = APDUGetTag( p_apdu, i_size ); switch ( i_tag ) { case AOT_APPLICATION_INFO: { int i_type, i_manufacturer, i_code; int l = 0; uint8_t *d = APDUGetLength( p_apdu, &l ); if ( l < 4 ) break; p_apdu[l + 4] = '\0'; i_type = *d++; i_manufacturer = ((int)d[0] << 8) | d[1]; d += 2; i_code = ((int)d[0] << 8) | d[1]; d += 2; d = GetLength( d, &l ); d[l] = '\0'; msg_Info( p_access, "CAM: %s, %02X, %04X, %04X", d, i_type, i_manufacturer, i_code ); break; } default: msg_Err( p_access, "unexpected tag in ApplicationInformationHandle (0x%x)", i_tag ); }}/***************************************************************************** * ApplicationInformationOpen *****************************************************************************/static void ApplicationInformationOpen( access_t * p_access, int i_session_id ){ access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_access, "opening ApplicationInformation session (%d)", i_session_id ); p_sys->p_sessions[i_session_id - 1].pf_handle = ApplicationInformationHandle; APDUSend( p_access, i_session_id, AOT_APPLICATION_INFO_ENQ, NULL, 0 );}/* * Conditional Access */#define MAX_CASYSTEM_IDS 16typedef struct{ uint16_t pi_system_ids[MAX_CASYSTEM_IDS + 1];} system_ids_t;static bool CheckSystemID( system_ids_t *p_ids, uint16_t i_id ){ int i = 0; if( !p_ids ) return true; while ( p_ids->pi_system_ids[i] ) { if ( p_ids->pi_system_ids[i] == i_id ) return true; i++; } return false;}/***************************************************************************** * CAPMTNeedsDescrambling *****************************************************************************/static bool 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 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 true; } } } return 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 );// p_data[i+4] &= 0x1f; 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 ); free( p_capmt ); }}/***************************************************************************** * 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; if( p_access->p_sys->i_selected_programs >= CAM_PROG_MAX ) { msg_Warn( p_access, "Not adding CAPMT for SID %d, too many programs", p_pmt->i_program_number ); return; } p_access->p_sys->i_selected_programs++; if( p_access->p_sys->i_selected_programs == 1 ) { CAPMTFirst( p_access, i_session_id, p_pmt ); return; } 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 ); free( p_capmt ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -