📄 en50221.c
字号:
free( p_spdu ); return VLC_SUCCESS;}/***************************************************************************** * SessionOpen *****************************************************************************/static void SessionOpen( access_t * p_access, uint8_t i_slot, uint8_t *p_spdu, int i_size ){ access_sys_t *p_sys = p_access->p_sys; int i_session_id; int i_resource_id = ResourceIdToInt( &p_spdu[2] ); uint8_t p_response[16]; int i_status = SS_NOT_ALLOCATED; uint8_t i_tag; for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ ) { if ( !p_sys->p_sessions[i_session_id - 1].i_resource_id ) break; } if ( i_session_id == MAX_SESSIONS ) { msg_Err( p_access, "too many sessions !" ); return; } p_sys->p_sessions[i_session_id - 1].i_slot = i_slot; p_sys->p_sessions[i_session_id - 1].i_resource_id = i_resource_id; p_sys->p_sessions[i_session_id - 1].pf_close = NULL; p_sys->p_sessions[i_session_id - 1].pf_manage = NULL; if ( i_resource_id == RI_RESOURCE_MANAGER || i_resource_id == RI_APPLICATION_INFORMATION || i_resource_id == RI_CONDITIONAL_ACCESS_SUPPORT || i_resource_id == RI_DATE_TIME || i_resource_id == RI_MMI ) { i_status = SS_OK; } p_response[0] = ST_OPEN_SESSION_RESPONSE; p_response[1] = 0x7; p_response[2] = i_status; p_response[3] = p_spdu[2]; p_response[4] = p_spdu[3]; p_response[5] = p_spdu[4]; p_response[6] = p_spdu[5]; p_response[7] = i_session_id >> 8; p_response[8] = i_session_id & 0xff; if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p_response, 9 ) != VLC_SUCCESS ) { msg_Err( p_access, "SessionOpen: couldn't send TPDU on slot %d", i_slot ); return; } if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS ) { msg_Err( p_access, "SessionOpen: couldn't recv TPDU on slot %d", i_slot ); return; } switch ( i_resource_id ) { case RI_RESOURCE_MANAGER: ResourceManagerOpen( p_access, i_session_id ); break; case RI_APPLICATION_INFORMATION: ApplicationInformationOpen( p_access, i_session_id ); break; case RI_CONDITIONAL_ACCESS_SUPPORT: ConditionalAccessOpen( p_access, i_session_id ); break; case RI_DATE_TIME: DateTimeOpen( p_access, i_session_id ); break; case RI_MMI: MMIOpen( p_access, i_session_id ); break; case RI_HOST_CONTROL: default: msg_Err( p_access, "unknown resource id (0x%x)", i_resource_id ); p_sys->p_sessions[i_session_id - 1].i_resource_id = 0; }}/***************************************************************************** * SessionClose *****************************************************************************/static void SessionClose( access_t * p_access, int i_session_id ){ access_sys_t *p_sys = p_access->p_sys; uint8_t p_response[16]; uint8_t i_tag; uint8_t i_slot = p_sys->p_sessions[i_session_id - 1].i_slot; if ( p_sys->p_sessions[i_session_id - 1].pf_close != NULL ) p_sys->p_sessions[i_session_id - 1].pf_close( p_access, i_session_id ); p_sys->p_sessions[i_session_id - 1].i_resource_id = 0; p_response[0] = ST_CLOSE_SESSION_RESPONSE; p_response[1] = 0x3; p_response[2] = SS_OK; p_response[3] = i_session_id >> 8; p_response[4] = i_session_id & 0xff; if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p_response, 5 ) != VLC_SUCCESS ) { msg_Err( p_access, "SessionOpen: couldn't send TPDU on slot %d", i_slot ); return; } if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS ) { msg_Err( p_access, "SessionOpen: couldn't recv TPDU on slot %d", i_slot ); return; }}/***************************************************************************** * SPDUHandle *****************************************************************************/static void SPDUHandle( access_t * p_access, uint8_t i_slot, uint8_t *p_spdu, int i_size ){ access_sys_t *p_sys = p_access->p_sys; int i_session_id; switch ( p_spdu[0] ) { case ST_SESSION_NUMBER: if ( i_size <= 4 ) return; i_session_id = ((int)p_spdu[2] << 8) | p_spdu[3]; p_sys->p_sessions[i_session_id - 1].pf_handle( p_access, i_session_id, p_spdu + 4, i_size - 4 ); break; case ST_OPEN_SESSION_REQUEST: if ( i_size != 6 || p_spdu[1] != 0x4 ) return; SessionOpen( p_access, i_slot, p_spdu, i_size ); break; case ST_CLOSE_SESSION_REQUEST: i_session_id = ((int)p_spdu[2] << 8) | p_spdu[3]; SessionClose( p_access, i_session_id ); break; default: break; }}/* * Application layer */#define AOT_NONE 0x000000#define AOT_PROFILE_ENQ 0x9F8010#define AOT_PROFILE 0x9F8011#define AOT_PROFILE_CHANGE 0x9F8012#define AOT_APPLICATION_INFO_ENQ 0x9F8020#define AOT_APPLICATION_INFO 0x9F8021#define AOT_ENTER_MENU 0x9F8022#define AOT_CA_INFO_ENQ 0x9F8030#define AOT_CA_INFO 0x9F8031#define AOT_CA_PMT 0x9F8032#define AOT_CA_PMT_REPLY 0x9F8033#define AOT_TUNE 0x9F8400#define AOT_REPLACE 0x9F8401#define AOT_CLEAR_REPLACE 0x9F8402#define AOT_ASK_RELEASE 0x9F8403#define AOT_DATE_TIME_ENQ 0x9F8440#define AOT_DATE_TIME 0x9F8441#define AOT_CLOSE_MMI 0x9F8800#define AOT_DISPLAY_CONTROL 0x9F8801#define AOT_DISPLAY_REPLY 0x9F8802#define AOT_TEXT_LAST 0x9F8803#define AOT_TEXT_MORE 0x9F8804#define AOT_KEYPAD_CONTROL 0x9F8805#define AOT_KEYPRESS 0x9F8806#define AOT_ENQ 0x9F8807#define AOT_ANSW 0x9F8808#define AOT_MENU_LAST 0x9F8809#define AOT_MENU_MORE 0x9F880A#define AOT_MENU_ANSW 0x9F880B#define AOT_LIST_LAST 0x9F880C#define AOT_LIST_MORE 0x9F880D#define AOT_SUBTITLE_SEGMENT_LAST 0x9F880E#define AOT_SUBTITLE_SEGMENT_MORE 0x9F880F#define AOT_DISPLAY_MESSAGE 0x9F8810#define AOT_SCENE_END_MARK 0x9F8811#define AOT_SCENE_DONE 0x9F8812#define AOT_SCENE_CONTROL 0x9F8813#define AOT_SUBTITLE_DOWNLOAD_LAST 0x9F8814#define AOT_SUBTITLE_DOWNLOAD_MORE 0x9F8815#define AOT_FLUSH_DOWNLOAD 0x9F8816#define AOT_DOWNLOAD_REPLY 0x9F8817#define AOT_COMMS_CMD 0x9F8C00#define AOT_CONNECTION_DESCRIPTOR 0x9F8C01#define AOT_COMMS_REPLY 0x9F8C02#define AOT_COMMS_SEND_LAST 0x9F8C03#define AOT_COMMS_SEND_MORE 0x9F8C04#define AOT_COMMS_RCV_LAST 0x9F8C05#define AOT_COMMS_RCV_MORE 0x9F8C06/***************************************************************************** * APDUGetTag *****************************************************************************/static int APDUGetTag( const uint8_t *p_apdu, int i_size ){ if ( i_size >= 3 ) { int i, t = 0; for ( i = 0; i < 3; i++ ) t = (t << 8) | *p_apdu++; return t; } return AOT_NONE;}/***************************************************************************** * APDUGetLength *****************************************************************************/static uint8_t *APDUGetLength( uint8_t *p_apdu, int *pi_size ){ return GetLength( &p_apdu[3], pi_size );}/***************************************************************************** * APDUSend *****************************************************************************/static int APDUSend( access_t * p_access, int i_session_id, int i_tag, uint8_t *p_data, int i_size ){ uint8_t *p_apdu = malloc( i_size + 12 ); uint8_t *p = p_apdu; int i_ret; *p++ = (i_tag >> 16); *p++ = (i_tag >> 8) & 0xff; *p++ = i_tag & 0xff; p = SetLength( p, i_size ); if ( i_size ) memcpy( p, p_data, i_size ); i_ret = SPDUSend( p_access, i_session_id, p_apdu, i_size + p - p_apdu ); free( p_apdu ); return i_ret;}/* * 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 *//***************************************************************************** * 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 vlc_bool_t CheckSystemID( system_ids_t *p_ids, uint16_t i_id ){ int i = 0; while ( p_ids->pi_system_ids[i] ) { if ( p_ids->pi_system_ids[i] == i_id ) return VLC_TRUE; i++; } return VLC_FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -