📄 dvb.c
字号:
/***************************************************************************** * dvb.c : functions to control a DVB card under Linux with v4l2 ***************************************************************************** * Copyright (C) 1998-2003 VideoLAN * * Authors: Damien Lucas <nitrox@via.ecp.fr> * Johan Bilien <jobi@via.ecp.fr> * Jean-Paul Saman <jpsaman@wxs.nl> * Christopher Ross <chris@tebibyte.org> * * 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 <stdio.h>#ifdef HAVE_ERRNO_H# include <string.h># include <errno.h>#endif#ifdef HAVE_INTTYPES_H# include <inttypes.h> /* int16_t .. */#endif#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <time.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/poll.h>/* DVB Card Drivers */#include <linux/dvb/dmx.h>#include <linux/dvb/frontend.h>#include <linux/errno.h>#include "dvb.h"struct diseqc_cmd_t{ struct dvb_diseqc_master_cmd cmd; uint32_t wait;};struct diseqc_cmd_t switch_cmds[] ={ { { { 0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xf2, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xf1, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xf3, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xf4, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xf6, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xf5, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xf7, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xf8, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xfa, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xf9, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xfb, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xfc, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xfe, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xfd, 0x00, 0x00 }, 4 }, 0 }, { { { 0xe0, 0x10, 0x38, 0xff, 0x00, 0x00 }, 4 }, 0 }};static int ioctl_CheckFrontend(input_thread_t * p_input, int front);/***************************************************************************** * ioctl_InfoFrontend : return information about given frontend *****************************************************************************/int ioctl_InfoFrontend(input_thread_t * p_input, struct dvb_frontend_info *info, unsigned int u_adapter, unsigned int u_device){ int front; int ret; char frontend[] = FRONTEND; int i_len; i_len = sizeof(FRONTEND); if (snprintf(frontend, sizeof(FRONTEND), FRONTEND, u_adapter, u_device) >= i_len) { msg_Err(p_input, "snprintf() truncated string for FRONTEND" ); frontend[sizeof(FRONTEND)] = '\0'; } msg_Dbg(p_input, "Opening device %s", frontend); if((front = open(frontend,O_RDWR)) < 0) {# ifdef HAVE_ERRNO_H msg_Err(p_input, "ioctl_InfoFrontEnd: opening device failed (%s)", strerror(errno));# else msg_Err(p_input, "ioctl_InfoFrontEnd: opening device failed");# endif return -1; } /* Determine type of frontend */ if ((ret=ioctl(front, FE_GET_INFO, info)) < 0) { close(front);# ifdef HAVE_ERRNO_H msg_Err(p_input, "ioctl FE_GET_INFO failed (%d) %s", ret, strerror(errno));# else msg_Err(p_input, "ioctl FE_GET_INFO failed (%d)", ret);# endif return -1; } /* Print out frontend capabilities. */ msg_Dbg(p_input, "Frontend Info:\tname = %s\n\t\tfrequency_min = %d\n\t\tfrequency_max = %d\n\t\tfrequency_stepsize = %d\n\t\tfrequency_tolerance = %d\n\t\tsymbol_rate_min = %d\n\t\tsymbol_rate_max = %d\n\t\tsymbol_rate_tolerance (ppm) = %d\n\t\tnotifier_delay (ms)= %d\n", info->name, info->frequency_min, info->frequency_max, info->frequency_stepsize, info->frequency_tolerance, info->symbol_rate_min, info->symbol_rate_max, info->symbol_rate_tolerance, info->notifier_delay ); msg_Dbg(p_input, "Frontend Info capability list:"); if (info->caps&FE_IS_STUPID) msg_Dbg(p_input, "no capabilities - frontend is stupid!"); if (info->caps&FE_CAN_INVERSION_AUTO) msg_Dbg(p_input, "inversion auto"); if (info->caps&FE_CAN_FEC_1_2) msg_Dbg(p_input, "forward error correction 1/2"); if (info->caps&FE_CAN_FEC_2_3) msg_Dbg(p_input, "forward error correction 2/3"); if (info->caps&FE_CAN_FEC_3_4) msg_Dbg(p_input, "forward error correction 3/4"); if (info->caps&FE_CAN_FEC_4_5) msg_Dbg(p_input, "forward error correction 4/5"); if (info->caps&FE_CAN_FEC_5_6) msg_Dbg(p_input, "forward error correction 5/6"); if (info->caps&FE_CAN_FEC_6_7) msg_Dbg(p_input, "forward error correction 6/7"); if (info->caps&FE_CAN_FEC_7_8) msg_Dbg(p_input, "forward error correction 7/8"); if (info->caps&FE_CAN_FEC_8_9) msg_Dbg(p_input, "forward error correction 8/9"); if (info->caps&FE_CAN_FEC_AUTO) msg_Dbg(p_input, "forward error correction auto"); if (info->caps&FE_CAN_QPSK) msg_Dbg(p_input, "card can do QPSK"); if (info->caps&FE_CAN_QAM_16) msg_Dbg(p_input, "card can do QAM 16"); if (info->caps&FE_CAN_QAM_32) msg_Dbg(p_input, "card can do QAM 32"); if (info->caps&FE_CAN_QAM_64) msg_Dbg(p_input, "card can do QAM 64"); if (info->caps&FE_CAN_QAM_128) msg_Dbg(p_input, "card can do QAM 128"); if (info->caps&FE_CAN_QAM_256) msg_Dbg(p_input, "card can do QAM 256"); if (info->caps&FE_CAN_QAM_AUTO) msg_Dbg(p_input, "card can do QAM auto"); if (info->caps&FE_CAN_TRANSMISSION_MODE_AUTO) msg_Dbg(p_input, "transmission mode auto"); if (info->caps&FE_CAN_BANDWIDTH_AUTO) msg_Dbg(p_input, "bandwidth mode auto"); if (info->caps&FE_CAN_GUARD_INTERVAL_AUTO) msg_Dbg(p_input, "guard interval mode auto"); if (info->caps&FE_CAN_HIERARCHY_AUTO) msg_Dbg(p_input, "hierarchy mode auto"); if (info->caps&FE_CAN_MUTE_TS) msg_Dbg(p_input, "card can mute TS"); if (info->caps&FE_CAN_CLEAN_SETUP) msg_Dbg(p_input, "clean setup"); msg_Dbg(p_input,"End of capability list"); close(front); return 0;}/* QPSK only */int ioctl_DiseqcSendMsg (input_thread_t *p_input, int fd, fe_sec_voltage_t v, struct diseqc_cmd_t **cmd, fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b){ int err; if ((err = ioctl(fd, FE_SET_TONE, SEC_TONE_OFF))<0) {# ifdef HAVE_ERRNO_H msg_Err(p_input, "ioclt FE_SET_TONE failed, tone=%s (%d) %s", SEC_TONE_ON ? "on" : "off", err, strerror(errno));# else msg_Err(p_input, "ioclt FE_SET_TONE failed, tone=%s (%d)", SEC_TONE_ON ? "on" : "off", err);# endif return err; } if ((err = ioctl(fd, FE_SET_VOLTAGE, v))<0) {# ifdef HAVE_ERRNO_H msg_Err(p_input, "ioclt FE_SET_VOLTAGE failed, voltage=%d (%d) %s", v, err, strerror(errno));# else msg_Err(p_input, "ioclt FE_SET_VOLTAGE failed, voltage=%d (%d)", v, err);# endif return err; } msleep(15); while (*cmd) { msg_Dbg(p_input, "DiseqcSendMsg(): %02x %02x %02x %02x %02x %02x", (*cmd)->cmd.msg[0], (*cmd)->cmd.msg[1], (*cmd)->cmd.msg[2], (*cmd)->cmd.msg[3], (*cmd)->cmd.msg[4], (*cmd)->cmd.msg[5]); if ((err = ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &(*cmd)->cmd))<0) {# ifdef HAVE_ERRNO_H msg_Err(p_input, "ioclt FE_DISEQC_SEND_MASTER_CMD failed (%d) %s", err, strerror(errno));# else msg_Err(p_input, "ioclt FE_DISEQC_SEND_MASTER_CMD failed (%d)", err);# endif return err; } msleep((*cmd)->wait); cmd++; } msleep(15); if ((err = ioctl(fd, FE_DISEQC_SEND_BURST, b))<0) {# ifdef HAVE_ERRNO_H msg_Err(p_input, "ioctl FE_DISEQC_SEND_BURST failed, burst=%d (%d) %s",b, err, strerror(errno));# else msg_Err(p_input, "ioctl FE_DISEQC_SEND_BURST failed, burst=%d (%d)",b, err);# endif return err; } msleep(15); if ((err = ioctl(fd, FE_SET_TONE, t))<0) {# ifdef HAVE_ERRNO_H msg_Err(p_input, "ioctl FE_SET_TONE failed, tone=%d (%d) %s", t, err, strerror(errno));# else msg_Err(p_input, "ioctl FE_SET_TONE failed, tone=%d (%d)", t, err);# endif return err; } return err; }/* QPSK only */int ioctl_SetupSwitch (input_thread_t *p_input, int frontend_fd, int switch_pos, int voltage_18, int hiband){ int ret; struct diseqc_cmd_t *cmd[2] = { NULL, NULL }; int i = 4 * switch_pos + 2 * hiband + (voltage_18 ? 1 : 0); msg_Dbg(p_input, "ioctl_SetupSwitch: switch pos %i, %sV, %sband", switch_pos, voltage_18 ? "18" : "13", hiband ? "hi" : "lo"); msg_Dbg(p_input, "ioctl_SetupSwitch: index %i", i); if ((i < 0) || (i >= (int)(sizeof(switch_cmds)/sizeof(struct diseqc_cmd_t)))) return -EINVAL; cmd[0] = &switch_cmds[i]; if ((ret = ioctl_DiseqcSendMsg (p_input, frontend_fd, (i % 2) ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13, cmd, (i/2) % 2 ? SEC_TONE_ON : SEC_TONE_OFF, (i/4) % 2 ? SEC_MINI_B : SEC_MINI_A))<0) { msg_Err(p_input, "ioctl_DiseqcSendMsg() failed (%d)", ret); return ret; } return ret;}/***************************************************************************** * ioctl_SetQPSKFrontend : controls the FE device *****************************************************************************/int ioctl_SetQPSKFrontend (input_thread_t * p_input, struct dvb_frontend_parameters fep, int b_polarisation, unsigned int u_lnb_lof1, unsigned int u_lnb_lof2, unsigned int u_lnb_slof, unsigned int u_adapter, unsigned int u_device ){ int ret; int front; int hiband; char frontend[] = FRONTEND; int i_len; i_len = sizeof(FRONTEND); if (snprintf(frontend, sizeof(FRONTEND), FRONTEND, u_adapter, u_device) >= i_len) { msg_Err(p_input, "DVB-S: FrontEnd snprintf() truncated string for FRONTEND" ); frontend[sizeof(FRONTEND)] = '\0'; } /* Open the frontend device */ msg_Dbg(p_input, "DVB-S: Opening frontend %s", frontend); if(( front = open(frontend,O_RDWR)) < 0) {# ifdef HAVE_ERRNO_H msg_Err(p_input, "DVB-S: failed to open frontend (%s)", strerror(errno));# else msg_Err(p_input, "DVB-S: failed to open frontend");# endif return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -