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

📄 en50221.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * en50221.c : implementation of the transport, session and applications * layers of EN 50 221 ***************************************************************************** * Copyright (C) 2004 VideoLAN * * Authors: Christophe Massiot <massiot@via.ecp.fr> * Based on code from libdvbci Copyright (C) 2000 Klaus Schmidinger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA    02111, USA. *****************************************************************************/#include <vlc/vlc.h>#include <vlc/input.h>#include <sys/ioctl.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <time.h>#include <unistd.h>#include <sys/stat.h>#include <sys/poll.h>/* DVB Card Drivers */#include <linux/dvb/version.h>#include <linux/dvb/dmx.h>#include <linux/dvb/frontend.h>#include <linux/dvb/ca.h>/* Include dvbpsi headers */#ifdef HAVE_DVBPSI_DR_H#   include <dvbpsi/dvbpsi.h>#   include <dvbpsi/descriptor.h>#   include <dvbpsi/pat.h>#   include <dvbpsi/pmt.h>#   include <dvbpsi/dr.h>#   include <dvbpsi/psi.h>#else#   include "dvbpsi.h"#   include "descriptor.h"#   include "tables/pat.h"#   include "tables/pmt.h"#   include "descriptors/dr.h"#   include "psi.h"#endif#include "dvb.h"#undef DEBUG_TPDUstatic void ResourceManagerOpen( access_t * p_access, int i_session_id );static void ApplicationInformationOpen( access_t * p_access, int i_session_id );static void ConditionalAccessOpen( access_t * p_access, int i_session_id );static void DateTimeOpen( access_t * p_access, int i_session_id );static void MMIOpen( access_t * p_access, int i_session_id );/***************************************************************************** * Utility functions *****************************************************************************/#define SIZE_INDICATOR 0x80static uint8_t *GetLength( uint8_t *p_data, int *pi_length ){    *pi_length = *p_data++;    if ( (*pi_length & SIZE_INDICATOR) != 0 )    {        int l = *pi_length & ~SIZE_INDICATOR;        int i;        *pi_length = 0;        for ( i = 0; i < l; i++ )            *pi_length = (*pi_length << 8) | *p_data++;    }    return p_data;}static uint8_t *SetLength( uint8_t *p_data, int i_length ){    uint8_t *p = p_data;    if ( i_length < 128 )    {        *p++ = i_length;    }    else if ( i_length < 256 )    {        *p++ = SIZE_INDICATOR | 0x1;        *p++ = i_length;    }    else if ( i_length < 65536 )    {        *p++ = SIZE_INDICATOR | 0x2;        *p++ = i_length >> 8;        *p++ = i_length & 0xff;    }    else if ( i_length < 16777216 )    {        *p++ = SIZE_INDICATOR | 0x3;        *p++ = i_length >> 16;        *p++ = (i_length >> 8) & 0xff;        *p++ = i_length & 0xff;    }    else    {        *p++ = SIZE_INDICATOR | 0x4;        *p++ = i_length >> 24;        *p++ = (i_length >> 16) & 0xff;        *p++ = (i_length >> 8) & 0xff;        *p++ = i_length & 0xff;    }    return p;}/* * Transport layer */#define MAX_TPDU_SIZE  2048#define MAX_TPDU_DATA  (MAX_TPDU_SIZE - 4)#define DATA_INDICATOR 0x80#define T_SB           0x80#define T_RCV          0x81#define T_CREATE_TC    0x82#define T_CTC_REPLY    0x83#define T_DELETE_TC    0x84#define T_DTC_REPLY    0x85#define T_REQUEST_TC   0x86#define T_NEW_TC       0x87#define T_TC_ERROR     0x88#define T_DATA_LAST    0xA0#define T_DATA_MORE    0xA1static void Dump( vlc_bool_t b_outgoing, uint8_t *p_data, int i_size ){#ifdef DEBUG_TPDU    int i;#define MAX_DUMP 256    fprintf(stderr, "%s ", b_outgoing ? "-->" : "<--");    for ( i = 0; i < i_size && i < MAX_DUMP; i++)        fprintf(stderr, "%02X ", p_data[i]);    fprintf(stderr, "%s\n", i_size >= MAX_DUMP ? "..." : "");#endif}/***************************************************************************** * TPDUSend *****************************************************************************/static int TPDUSend( access_t * p_access, uint8_t i_slot, uint8_t i_tag,                     const uint8_t *p_content, int i_length ){    access_sys_t *p_sys = p_access->p_sys;    uint8_t i_tcid = i_slot + 1;    uint8_t p_data[MAX_TPDU_SIZE];    int i_size;    i_size = 0;    p_data[0] = i_slot;    p_data[1] = i_tcid;    p_data[2] = i_tag;    switch ( i_tag )    {    case T_RCV:    case T_CREATE_TC:    case T_CTC_REPLY:    case T_DELETE_TC:    case T_DTC_REPLY:    case T_REQUEST_TC:        p_data[3] = 1; /* length */        p_data[4] = i_tcid;        i_size = 5;        break;    case T_NEW_TC:    case T_TC_ERROR:        p_data[3] = 2; /* length */        p_data[4] = i_tcid;        p_data[5] = p_content[0];        i_size = 6;        break;    case T_DATA_LAST:    case T_DATA_MORE:    {        /* i_length <= MAX_TPDU_DATA */        uint8_t *p = p_data + 3;        p = SetLength( p, i_length + 1 );        *p++ = i_tcid;        if ( i_length )            memcpy( p, p_content, i_length );            i_size = i_length + (p - p_data);        }        break;    default:        break;    }    Dump( VLC_TRUE, p_data, i_size );    if ( write( p_sys->i_ca_handle, p_data, i_size ) != i_size )    {        msg_Err( p_access, "cannot write to CAM device (%s)",                 strerror(errno) );        return VLC_EGENERIC;    }    return VLC_SUCCESS;}/***************************************************************************** * TPDURecv *****************************************************************************/#define CAM_READ_TIMEOUT  3500 // msstatic int TPDURecv( access_t * p_access, uint8_t i_slot, uint8_t *pi_tag,                     uint8_t *p_data, int *pi_size ){    access_sys_t *p_sys = p_access->p_sys;    uint8_t i_tcid = i_slot + 1;    int i_size;    struct pollfd pfd[1];    pfd[0].fd = p_sys->i_ca_handle;    pfd[0].events = POLLIN;    if ( !(poll(pfd, 1, CAM_READ_TIMEOUT) > 0 && (pfd[0].revents & POLLIN)) )    {        msg_Err( p_access, "cannot poll from CAM device" );        return VLC_EGENERIC;    }    if ( pi_size == NULL )    {        p_data = malloc( MAX_TPDU_SIZE );    }    for ( ; ; )    {        i_size = read( p_sys->i_ca_handle, p_data, MAX_TPDU_SIZE );        if ( i_size >= 0 || errno != EINTR )            break;    }    if ( i_size < 5 )    {        msg_Err( p_access, "cannot read from CAM device (%d:%s)", i_size,                 strerror(errno) );        return VLC_EGENERIC;    }    if ( p_data[1] != i_tcid )    {        msg_Err( p_access, "invalid read from CAM device (%d instead of %d)",                 p_data[1], i_tcid );        return VLC_EGENERIC;    }    *pi_tag = p_data[2];    p_sys->pb_tc_has_data[i_slot] = (i_size >= 4                                      && p_data[i_size - 4] == T_SB                                      && p_data[i_size - 3] == 2                                      && (p_data[i_size - 1] & DATA_INDICATOR))                                        ?  VLC_TRUE : VLC_FALSE;    Dump( VLC_FALSE, p_data, i_size );    if ( pi_size == NULL )        free( p_data );    else        *pi_size = i_size;    return VLC_SUCCESS;}/* * Session layer */#define ST_SESSION_NUMBER           0x90#define ST_OPEN_SESSION_REQUEST     0x91#define ST_OPEN_SESSION_RESPONSE    0x92#define ST_CREATE_SESSION           0x93#define ST_CREATE_SESSION_RESPONSE  0x94#define ST_CLOSE_SESSION_REQUEST    0x95#define ST_CLOSE_SESSION_RESPONSE   0x96#define SS_OK             0x00#define SS_NOT_ALLOCATED  0xF0#define RI_RESOURCE_MANAGER            0x00010041#define RI_APPLICATION_INFORMATION     0x00020041#define RI_CONDITIONAL_ACCESS_SUPPORT  0x00030041#define RI_HOST_CONTROL                0x00200041#define RI_DATE_TIME                   0x00240041#define RI_MMI                         0x00400041static int ResourceIdToInt( uint8_t *p_data ){    return ((int)p_data[0] << 24) | ((int)p_data[1] << 16)            | ((int)p_data[2] << 8) | p_data[3];}/***************************************************************************** * SPDUSend *****************************************************************************/static int SPDUSend( access_t * p_access, int i_session_id,                     uint8_t *p_data, int i_size ){    access_sys_t *p_sys = p_access->p_sys;    uint8_t *p_spdu = malloc( i_size + 4 );    uint8_t *p = p_spdu;    uint8_t i_tag;    uint8_t i_slot = p_sys->p_sessions[i_session_id - 1].i_slot;    *p++ = ST_SESSION_NUMBER;    *p++ = 0x02;    *p++ = (i_session_id >> 8);    *p++ = i_session_id & 0xff;    memcpy( p, p_data, i_size );    i_size += 4;    p = p_spdu;    while ( i_size > 0 )    {        if ( i_size > MAX_TPDU_DATA )        {            if ( TPDUSend( p_access, i_slot, T_DATA_MORE, p,                           MAX_TPDU_DATA ) != VLC_SUCCESS )            {                msg_Err( p_access, "couldn't send TPDU on session %d",                         i_session_id );                free( p_spdu );                return VLC_EGENERIC;            }            p += MAX_TPDU_DATA;            i_size -= MAX_TPDU_DATA;        }        else        {            if ( TPDUSend( p_access, i_slot, T_DATA_LAST, p, i_size )                    != VLC_SUCCESS )            {                msg_Err( p_access, "couldn't send TPDU on session %d",                         i_session_id );                free( p_spdu );                return VLC_EGENERIC;            }            i_size = 0;        }        if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) != VLC_SUCCESS               || i_tag != T_SB )        {            msg_Err( p_access, "couldn't recv TPDU on session %d",                     i_session_id );            free( p_spdu );            return VLC_EGENERIC;        }    }

⌨️ 快捷键说明

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