📄 en50221.c
字号:
{ int Y = tm_gmt.tm_year; int M = tm_gmt.tm_mon + 1; int D = tm_gmt.tm_mday; int L = (M == 1 || M == 2) ? 1 : 0; int MJD = 14956 + D + (int)((Y - L) * 365.25) + (int)((M + 1 + L * 12) * 30.6001); uint8_t p_response[7];#define DEC2BCD(d) (((d / 10) << 4) + (d % 10)) p_response[0] = htons(MJD) >> 8; p_response[1] = htons(MJD) & 0xff; p_response[2] = DEC2BCD(tm_gmt.tm_hour); p_response[3] = DEC2BCD(tm_gmt.tm_min); p_response[4] = DEC2BCD(tm_gmt.tm_sec); p_response[5] = htons(tm_loc.tm_gmtoff / 60) >> 8; p_response[6] = htons(tm_loc.tm_gmtoff / 60) & 0xff; APDUSend( p_access, i_session_id, AOT_DATE_TIME, p_response, 7 ); p_date->i_last = mdate(); }}/***************************************************************************** * DateTimeHandle *****************************************************************************/static void DateTimeHandle( access_t * p_access, int i_session_id, uint8_t *p_apdu, int i_size ){ 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; int i_tag = APDUGetTag( p_apdu, i_size ); switch ( i_tag ) { case AOT_DATE_TIME_ENQ: { int l; const uint8_t *d = APDUGetLength( p_apdu, &l ); if ( l > 0 ) { p_date->i_interval = *d; msg_Dbg( p_access, "DateTimeHandle : interval set to %d", p_date->i_interval ); } else p_date->i_interval = 0; DateTimeSend( p_access, i_session_id ); break; } default: msg_Err( p_access, "unexpected tag in DateTimeHandle (0x%x)", i_tag ); }}/***************************************************************************** * DateTimeManage *****************************************************************************/static void DateTimeManage( 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; if ( p_date->i_interval && mdate() > p_date->i_last + (mtime_t)p_date->i_interval * 1000000 ) { DateTimeSend( p_access, i_session_id ); }}/***************************************************************************** * DateTimeOpen *****************************************************************************/static void DateTimeOpen( access_t * p_access, int i_session_id ){ access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_access, "opening DateTime session (%d)", i_session_id ); 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].p_sys = malloc(sizeof(date_time_t)); memset( p_sys->p_sessions[i_session_id - 1].p_sys, 0, sizeof(date_time_t) ); DateTimeSend( p_access, i_session_id );}/* * MMI *//***************************************************************************** * MMIHandle *****************************************************************************/static void MMIHandle( 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 ) { default: msg_Err( p_access, "unexpected tag in MMIHandle (0x%x)", i_tag ); }}/***************************************************************************** * MMIOpen *****************************************************************************/static void MMIOpen( access_t * p_access, int i_session_id ){ access_sys_t *p_sys = p_access->p_sys; msg_Dbg( p_access, "opening MMI session (%d)", i_session_id ); p_sys->p_sessions[i_session_id - 1].pf_handle = MMIHandle;}/* * Hardware handling *//***************************************************************************** * InitSlot: Open the transport layer *****************************************************************************/#define MAX_TC_RETRIES 20static int InitSlot( access_t * p_access, int i_slot ){ access_sys_t *p_sys = p_access->p_sys; int i; if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 ) != VLC_SUCCESS ) { msg_Err( p_access, "en50221_Init: couldn't send TPDU on slot %d", i_slot ); return VLC_EGENERIC; } /* This is out of the spec */ for ( i = 0; i < MAX_TC_RETRIES; i++ ) { uint8_t i_tag; if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) == VLC_SUCCESS && i_tag == T_CTC_REPLY ) { p_sys->pb_active_slot[i_slot] = VLC_TRUE; break; } if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 ) != VLC_SUCCESS ) { msg_Err( p_access, "en50221_Init: couldn't send TPDU on slot %d", i_slot ); continue; } } if ( p_sys->pb_active_slot[i_slot] ) { p_sys->i_ca_timeout = 100000; return VLC_SUCCESS; } return VLC_EGENERIC;}/* * External entry points *//***************************************************************************** * en50221_Poll : Poll the CAM for TPDUs *****************************************************************************/int E_(en50221_Poll)( access_t * p_access ){ access_sys_t *p_sys = p_access->p_sys; int i_slot; int i_session_id; for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ ) { uint8_t i_tag; if ( !p_sys->pb_active_slot[i_slot] ) { ca_slot_info_t sinfo; sinfo.num = i_slot; if ( ioctl( p_sys->i_ca_handle, CA_GET_SLOT_INFO, &sinfo ) != 0 ) { msg_Err( p_access, "en50221_Poll: couldn't get info on slot %d", i_slot ); continue; } if ( sinfo.flags & CA_CI_MODULE_READY ) { msg_Dbg( p_access, "en50221_Poll: slot %d is active", i_slot ); p_sys->pb_active_slot[i_slot] = VLC_TRUE; } else continue; InitSlot( p_access, i_slot ); } if ( !p_sys->pb_tc_has_data[i_slot] ) { if ( TPDUSend( p_access, i_slot, T_DATA_LAST, NULL, 0 ) != VLC_SUCCESS ) { msg_Err( p_access, "en50221_Poll: couldn't send TPDU on slot %d", i_slot ); continue; } if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS ) { msg_Err( p_access, "en50221_Poll: couldn't recv TPDU on slot %d", i_slot ); continue; } } while ( p_sys->pb_tc_has_data[i_slot] ) { uint8_t p_tpdu[MAX_TPDU_SIZE]; int i_size, i_session_size; uint8_t *p_session; if ( TPDUSend( p_access, i_slot, T_RCV, NULL, 0 ) != VLC_SUCCESS ) { msg_Err( p_access, "en50221_Poll: couldn't send TPDU on slot %d", i_slot ); continue; } if ( TPDURecv( p_access, i_slot, &i_tag, p_tpdu, &i_size ) != VLC_SUCCESS ) { msg_Err( p_access, "en50221_Poll: couldn't recv TPDU on slot %d", i_slot ); continue; } p_session = GetLength( &p_tpdu[3], &i_session_size ); if ( i_session_size <= 1 ) continue; p_session++; i_session_size--; if ( i_tag != T_DATA_LAST ) { msg_Err( p_access, "en50221_Poll: fragmented TPDU not supported" ); break; } SPDUHandle( p_access, i_slot, p_session, i_session_size ); } } 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 && p_sys->p_sessions[i_session_id - 1].pf_manage ) { p_sys->p_sessions[i_session_id - 1].pf_manage( p_access, i_session_id ); } } return VLC_SUCCESS;}/***************************************************************************** * en50221_SetCAPMT : *****************************************************************************/int E_(en50221_SetCAPMT)( access_t * p_access, dvbpsi_pmt_t *p_pmt ){ access_sys_t *p_sys = p_access->p_sys; int i, i_session_id; vlc_bool_t b_update = VLC_FALSE; vlc_bool_t b_needs_descrambling = CAPMTNeedsDescrambling( p_pmt ); for ( i = 0; i < MAX_PROGRAMS; i++ ) { if ( p_sys->pp_selected_programs[i] != NULL && p_sys->pp_selected_programs[i]->i_program_number == p_pmt->i_program_number ) { b_update = VLC_TRUE; if ( !b_needs_descrambling ) { dvbpsi_DeletePMT( p_pmt ); p_pmt = p_sys->pp_selected_programs[i]; p_sys->pp_selected_programs[i] = NULL; } else { dvbpsi_DeletePMT( p_sys->pp_selected_programs[i] ); p_sys->pp_selected_programs[i] = p_pmt; } break; } } if ( !b_update && b_needs_descrambling ) { for ( i = 0; i < MAX_PROGRAMS; i++ ) { if ( p_sys->pp_selected_programs[i] == NULL ) { p_sys->pp_selected_programs[i] = p_pmt; break; } } } if ( b_update || b_needs_descrambling ) { 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 == RI_CONDITIONAL_ACCESS_SUPPORT ) { if ( b_update && b_needs_descrambling ) CAPMTUpdate( p_access, i_session_id, p_pmt ); else if ( b_update ) CAPMTDelete( p_access, i_session_id, p_pmt ); else CAPMTAdd( p_access, i_session_id, p_pmt ); } } } if ( !b_needs_descrambling ) { dvbpsi_DeletePMT( p_pmt ); } return VLC_SUCCESS;}/***************************************************************************** * en50221_End : *****************************************************************************/void E_(en50221_End)( access_t * p_access ){ access_sys_t *p_sys = p_access->p_sys; int i; for ( i = 0; i < MAX_PROGRAMS; i++ ) { if ( p_sys->pp_selected_programs[i] != NULL ) { dvbpsi_DeletePMT( p_sys->pp_selected_programs[i] ); } } /* TODO */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -