⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 en50221.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * MMIHandleMenu *****************************************************************************/static void MMIHandleMenu( access_t *p_access, int i_session_id, int i_tag,                           uint8_t *p_apdu, int i_size ){    access_sys_t *p_sys = p_access->p_sys;    mmi_t *p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys;    int i_slot = p_sys->p_sessions[i_session_id - 1].i_slot;    int l;    uint8_t *d = APDUGetLength( p_apdu, &l );    en50221_MMIFree( &p_mmi->last_object );    p_mmi->last_object.i_object_type = (i_tag == AOT_MENU_LAST) ?                                       EN50221_MMI_MENU : EN50221_MMI_LIST;    p_mmi->last_object.u.menu.i_choices = 0;    p_mmi->last_object.u.menu.ppsz_choices = NULL;    if ( l > 0 )    {        l--; d++; /* choice_nb */#define GET_FIELD( x )                                                      \        if ( l > 0 )                                                        \        {                                                                   \            p_mmi->last_object.u.menu.psz_##x                               \                            = MMIGetText( p_access, &d, &l );               \            msg_Dbg( p_access, "MMI " STRINGIFY( x ) ": %s",                \                     p_mmi->last_object.u.menu.psz_##x );                   \        }        GET_FIELD( title );        GET_FIELD( subtitle );        GET_FIELD( bottom );#undef GET_FIELD        while ( l > 0 )        {            char *psz_text = MMIGetText( p_access, &d, &l );            TAB_APPEND( p_mmi->last_object.u.menu.i_choices,                        p_mmi->last_object.u.menu.ppsz_choices,                        psz_text );            msg_Dbg( p_access, "MMI choice: %s", psz_text );        }    }    p_sys->pb_slot_mmi_expected[i_slot] = false;    p_sys->pb_slot_mmi_undisplayed[i_slot] = true;}/***************************************************************************** * 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 )    {    case AOT_DISPLAY_CONTROL:    {        int l;        uint8_t *d = APDUGetLength( p_apdu, &l );        if ( l > 0 )        {            switch ( *d )            {            case DCC_SET_MMI_MODE:                if ( l == 2 && d[1] == MM_HIGH_LEVEL )                    MMIDisplayReply( p_access, i_session_id );                else                    msg_Err( p_access, "unsupported MMI mode %02x", d[1] );                break;            default:                msg_Err( p_access, "unsupported display control command %02x",                         *d );                break;            }        }        break;    }    case AOT_ENQ:        MMIHandleEnq( p_access, i_session_id, p_apdu, i_size );        break;    case AOT_LIST_LAST:    case AOT_MENU_LAST:        MMIHandleMenu( p_access, i_session_id, i_tag, p_apdu, i_size );        break;    case AOT_CLOSE_MMI:        SessionSendClose( p_access, i_session_id );        break;    default:        msg_Err( p_access, "unexpected tag in MMIHandle (0x%x)", i_tag );    }}/***************************************************************************** * MMIClose *****************************************************************************/static void MMIClose( 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;    mmi_t *p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys;    en50221_MMIFree( &p_mmi->last_object );    free( p_sys->p_sessions[i_session_id - 1].p_sys );    msg_Dbg( p_access, "closing MMI session (%d)", i_session_id );    p_sys->pb_slot_mmi_expected[i_slot] = false;    p_sys->pb_slot_mmi_undisplayed[i_slot] = true;}/***************************************************************************** * MMIOpen *****************************************************************************/static void MMIOpen( access_t *p_access, int i_session_id ){    access_sys_t *p_sys = p_access->p_sys;    mmi_t *p_mmi;    msg_Dbg( p_access, "opening MMI session (%d)", i_session_id );    p_sys->p_sessions[i_session_id - 1].pf_handle = MMIHandle;    p_sys->p_sessions[i_session_id - 1].pf_close = MMIClose;    p_sys->p_sessions[i_session_id - 1].p_sys = malloc(sizeof(mmi_t));    p_mmi = (mmi_t *)p_sys->p_sessions[i_session_id - 1].p_sys;    p_mmi->last_object.i_object_type = EN50221_MMI_NONE;}/* * 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] = true;            break;        }        if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, NULL )                != 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_Init : Initialize the CAM for en50221 *****************************************************************************/int en50221_Init( access_t * p_access ){    access_sys_t *p_sys = p_access->p_sys;    if( p_sys->i_ca_type & CA_CI_LINK )    {        int i_slot;        for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ )        {            if ( ioctl( p_sys->i_ca_handle, CA_RESET, 1 << i_slot) != 0 )            {                msg_Err( p_access, "en50221_Init: couldn't reset slot %d",                         i_slot );            }        }        p_sys->i_ca_timeout = 100000;        /* Wait a bit otherwise it doesn't initialize properly... */        msleep( 1000000 );        return VLC_SUCCESS;    }    else    {        struct ca_slot_info info;        info.num = 0;        /* We don't reset the CAM in that case because it's done by the         * ASIC. */        if ( ioctl( p_sys->i_ca_handle, CA_GET_SLOT_INFO, &info ) < 0 )        {            msg_Err( p_access, "en50221_Init: couldn't get slot info" );            close( p_sys->i_ca_handle );            p_sys->i_ca_handle = 0;            return VLC_EGENERIC;        }        if( info.flags == 0 )        {            msg_Err( p_access, "en50221_Init: no CAM inserted" );            close( p_sys->i_ca_handle );            p_sys->i_ca_handle = 0;            return VLC_EGENERIC;        }        /* Allocate a dummy sessions */        p_sys->p_sessions[ 0 ].i_resource_id = RI_CONDITIONAL_ACCESS_SUPPORT;        /* Get application info to find out which cam we are using and make           sure everything is ready to play */        ca_msg_t ca_msg;        ca_msg.length=3;        ca_msg.msg[0] = ( AOT_APPLICATION_INFO & 0xFF0000 ) >> 16;        ca_msg.msg[1] = ( AOT_APPLICATION_INFO & 0x00FF00 ) >> 8;        ca_msg.msg[2] = ( AOT_APPLICATION_INFO & 0x0000FF ) >> 0;        memset( &ca_msg.msg[3], 0, 253 );        APDUSend( p_access, 1, AOT_APPLICATION_INFO_ENQ, NULL, 0 );        if ( ioctl( p_sys->i_ca_handle, CA_GET_MSG, &ca_msg ) < 0 )        {            msg_Err( p_access, "en50221_Init: failed getting message" );            return VLC_EGENERIC;        }#if HLCI_WAIT_CAM_READY        while( ca_msg.msg[8] == 0xff && ca_msg.msg[9] == 0xff )        {            if( !vlc_object_alive (p_access) ) return VLC_EGENERIC;            msleep(1);            msg_Dbg( p_access, "CAM: please wait" );            APDUSend( p_access, 1, AOT_APPLICATION_INFO_ENQ, NULL, 0 );            ca_msg.length=3;            ca_msg.msg[0] = ( AOT_APPLICATION_INFO & 0xFF0000 ) >> 16;            ca_msg.msg[1] = ( AOT_APPLICATION_INFO & 0x00FF00 ) >> 8;            ca_msg.msg[2] = ( AOT_APPLICATION_INFO & 0x0000FF ) >> 0;            memset( &ca_msg.msg[3], 0, 253 );            if ( ioctl( p_sys->i_ca_handle, CA_GET_MSG, &ca_msg ) < 0 )            {                msg_Err( p_access, "en50221_Init: failed getting message" );                return VLC_EGENERIC;            }            msg_Dbg( p_access, "en50221_Init: Got length: %d, tag: 0x%x", ca_msg.length, APDUGetTag( ca_msg.msg, ca_msg.length ) );        }#else        if( ca_msg.msg[8] == 0xff && ca_msg.msg[9] == 0xff )        {            msg_Err( p_access, "CAM returns garbage as application info!" );            return VLC_EGENERIC;        }#endif        msg_Dbg( p_access, "found CAM %s using id 0x%x", &ca_msg.msg[12],                 (ca_msg.msg[8]<<8)|ca_msg.msg[9] );        return VLC_SUCCESS;    }}/***************************************************************************** * en50221_Poll : Poll the CAM for TPDUs *****************************************************************************/int 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;        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) )        {            if ( p_sys->pb_active_slot[i_slot] )            {                msg_Dbg( p_access, "en50221_Poll: slot %d has been removed",                         i_slot );                p_sys->pb_active_slot[i_slot] = false;                p_sys->pb_slot_mmi_expected[i_slot] = false;                p_sys->pb_slot_mmi_undisplayed[i_slot] = false;                /* Close all sessions for this slot. */                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].i_slot                               == 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;                    }                }            }            continue;        }        else if ( !p_sys->pb_active_slot[i_slot] )        {            InitSlot( p_access, i_slot );            if ( !p_sys->pb_active_slot[i_slot] )            {                msg_Dbg( p_access, "en50221_Poll: resetting slot %d", i_slot );                if ( ioctl( p_sys->i_ca_handle, CA_RESET, 1 << i_slot) != 0 )                {                    msg_Err( p_access, "en50221_Poll: couldn't reset slot %d",                             i_slot );                }                continue;            }            msg_Dbg( p_access, "en50221_Poll: slot %d is active",                     i_slot );        }        if ( !p_sys->pb_tc_has_data[i_slot] )        {            if ( TPDUSend( p_access, i_slot, T_DATA_LAST, NULL, NULL ) !=                    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_ac

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -