📄 en50221.c
字号:
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; }}#if 0/* unused code for the moment - commented out to keep gcc happy *//***************************************************************************** * SessionCreate *****************************************************************************/static void SessionCreate( access_t * p_access, int i_slot, int i_resource_id ){ access_sys_t *p_sys = p_access->p_sys; uint8_t p_response[16]; uint8_t i_tag; int i_session_id; 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; p_sys->p_sessions[i_session_id - 1].p_sys = NULL; p_response[0] = ST_CREATE_SESSION; p_response[1] = 0x6; p_response[2] = i_resource_id >> 24; p_response[3] = (i_resource_id >> 16) & 0xff; p_response[4] = (i_resource_id >> 8) & 0xff; p_response[5] = i_resource_id & 0xff; p_response[6] = i_session_id >> 8; p_response[7] = i_session_id & 0xff; if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p_response, 4 ) != VLC_SUCCESS ) { msg_Err( p_access, "SessionCreate: 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, "SessionCreate: couldn't recv TPDU on slot %d", i_slot ); return; }}#endif/***************************************************************************** * SessionCreateResponse *****************************************************************************/static void SessionCreateResponse( 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_status = p_spdu[2]; int i_resource_id = ResourceIdToInt( &p_spdu[3] ); int i_session_id = ((int)p_spdu[7] << 8) | p_spdu[8]; if ( i_status != SS_OK ) { msg_Err( p_access, "SessionCreateResponse: failed to open session %d" " resource=0x%x status=0x%x", i_session_id, i_resource_id, i_status ); p_sys->p_sessions[i_session_id - 1].i_resource_id = 0; 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; }}/***************************************************************************** * SessionSendClose *****************************************************************************/static void SessionSendClose( 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; p_response[0] = ST_CLOSE_SESSION_REQUEST; p_response[1] = 0x2; p_response[2] = i_session_id >> 8; p_response[3] = i_session_id & 0xff; if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p_response, 4 ) != VLC_SUCCESS ) { msg_Err( p_access, "SessionSendClose: 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, "SessionSendClose: couldn't recv TPDU on slot %d", i_slot ); return; }}/***************************************************************************** * 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, "SessionClose: 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, "SessionClose: 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_CREATE_SESSION_RESPONSE: if ( i_size != 9 || p_spdu[1] != 0x7 ) return; SessionCreateResponse( p_access, i_slot, p_spdu, i_size ); break; case ST_CLOSE_SESSION_REQUEST: if ( i_size != 4 || p_spdu[1] != 0x2 ) return; i_session_id = ((int)p_spdu[2] << 8) | p_spdu[3]; SessionClose( p_access, i_session_id ); break; case ST_CLOSE_SESSION_RESPONSE: if ( i_size != 5 || p_spdu[1] != 0x3 ) return; i_session_id = ((int)p_spdu[3] << 8) | p_spdu[4]; if ( p_spdu[2] ) { msg_Err( p_access, "closing a session which is not allocated (%d)", i_session_id ); } else { 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; } break; default: msg_Err( p_access, "unexpected tag in SPDUHandle (%x)", p_spdu[0] ); 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 ){ access_sys_t *p_sys = p_access->p_sys; uint8_t *p_apdu = malloc( i_size + 12 ); uint8_t *p = p_apdu; ca_msg_t ca_msg; 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 ); if ( p_sys->i_ca_type == CA_CI_LINK ) { i_ret = SPDUSend( p_access, i_session_id, p_apdu, i_size + p - p_apdu ); } else { if ( i_size + p - p_apdu > 256 ) { msg_Err( p_access, "CAM: apdu overflow" ); i_ret = VLC_EGENERIC; } else { ca_msg.length = i_size + p - p_apdu; if ( i_size == 0 ) ca_msg.length=3; 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 ) { msg_Err( p_access, "Error sending to CAM: %m" ); i_ret = VLC_EGENERIC; } } } free( p_apdu ); return i_ret;}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -