📄 fe.c
字号:
} if (ioctl(adapter->fe.fd, IOCTL_SET_FE, &feparams) < 0) { logwrite(LOG_ERROR, "ioctl FE_SET_FRONTEND failed"); exit(-1); } return 0;}static int fe_tune_dvbc(struct adapter_s *adapter) { FE_PARAM feparams; memset(&feparams, 0, sizeof(FE_PARAM)); feparams.frequency = adapter->fe.dvbc.freq; DVB_SET_DELIVERY(&feparams, DVBFE_DELSYS_DVBC); DVBC_SET_SYMBOLRATE(&feparams, adapter->fe.dvbc.srate); feparams.inversion=INVERSION_AUTO; switch(adapter->fe.dvbc.modulation) { case -1: DVBC_SET_MODULATION(&feparams, DVBFE_MOD_QPSK); break; case 0: DVBC_SET_MODULATION(&feparams, DVBFE_MOD_QAMAUTO); break; case 16: DVBC_SET_MODULATION(&feparams, DVBFE_MOD_QAM16); break; case 32: DVBC_SET_MODULATION(&feparams, DVBFE_MOD_QAM32); break; case 64: DVBC_SET_MODULATION(&feparams, DVBFE_MOD_QAM64); break; case 128: DVBC_SET_MODULATION(&feparams, DVBFE_MOD_QAM128); break; case 256: DVBC_SET_MODULATION(&feparams, DVBFE_MOD_QAM256); break; default: logwrite(LOG_ERROR, "Unknown modulation %d", adapter->fe.dvbc.modulation); exit(-1); } switch(adapter->fe.dvbc.fec) { case 0: DVBC_SET_FEC(&feparams, DVBFE_FEC_NONE); break; case 1: DVBC_SET_FEC(&feparams, DVBFE_FEC_1_2); break; case 2: DVBC_SET_FEC(&feparams, DVBFE_FEC_2_3); break; case 3: DVBC_SET_FEC(&feparams, DVBFE_FEC_3_4); break; case 4: DVBC_SET_FEC(&feparams, DVBFE_FEC_4_5); break; case 5: DVBC_SET_FEC(&feparams, DVBFE_FEC_5_6); break; case 6: DVBC_SET_FEC(&feparams, DVBFE_FEC_6_7); break; case 7: DVBC_SET_FEC(&feparams, DVBFE_FEC_7_8); break; case 8: DVBC_SET_FEC(&feparams, DVBFE_FEC_8_9); break; case 9: DVBC_SET_FEC(&feparams, DVBFE_FEC_AUTO); break; default: logwrite(LOG_ERROR, "Unknown fec %d", adapter->fe.dvbc.fec); exit(-1); } if (ioctl(adapter->fe.fd, IOCTL_SET_FE, &feparams) < 0) { logwrite(LOG_ERROR, "ioctl FE_SET_FRONTEND failed"); exit(-1); } return 0;}static int fe_tune(struct adapter_s *adapter) { switch(adapter->type) { case(AT_DVBS2): case(AT_DVBS): fe_tune_dvbs(adapter); break; case(AT_DVBT): fe_tune_dvbt(adapter); break; case(AT_DVBC): fe_tune_dvbc(adapter); break; } adapter->fe.tunelast=time(NULL); return 0;}#define FE_TUNE_MINDELAY 5void fe_retune(struct adapter_s *adapter) { time_t now; now=time(NULL); /* Debounce the retuning */ if (adapter->fe.tunelast + FE_TUNE_MINDELAY > now) return; fe_tune(adapter);}static void fe_timer_init(struct adapter_s *adapter);static void fe_check_status(int fd, short event, void *arg) { struct adapter_s *adapter=arg; fe_status_t status; int res; res=ioctl(adapter->fe.fd, FE_READ_STATUS, &status); if (res == 0) { if (!(status & FE_HAS_LOCK)) { logwrite(LOG_INFO, "fe: Adapter %d Status: 0x%02x (%s)", adapter->no, status, fe_decode_status(status)); fe_retune(adapter); } } fe_timer_init(adapter);}#define FE_CHECKSTATUS_INTERVAL 5static void fe_timer_init(struct adapter_s *adapter) { struct timeval tv; tv.tv_sec=FE_CHECKSTATUS_INTERVAL; tv.tv_usec=0; evtimer_set(&adapter->fe.timer, fe_check_status, adapter); evtimer_add(&adapter->fe.timer, &tv);}/* * We had an event on the frontend filedescriptor - poll the event * and dump the status * */static void fe_event(int fd, short ev, void *arg) { struct adapter_s *adapter=arg; int res, status; FE_EVENT event; res=ioctl(adapter->fe.fd, IOCTL_GET_EVENT, &event); if (res < 0 && errno != EOVERFLOW) { logwrite(LOG_ERROR, "fe: Adapter %d Status event overflow %d", adapter->no, errno); return; } status=FE_GET_STATUS(event); if (res >= 0 && status) { if (!(status & FE_TIMEDOUT)) { logwrite(LOG_INFO, "fe: Adapter %d Status: 0x%02x (%s)", adapter->no, status, fe_decode_status(status)); if (!(status & FE_HAS_LOCK)) { fe_retune(adapter); } } }}#ifdef MULTIPROTOstatic void fe_checkcap(struct adapter_s *adapter) { /* With multiproto API changes from 2008-03-09 one has to set the * delsys before anything else */ if (ioctl(adapter->fe.fd, IOCTL_SET_DELSYS, &adapter->type)) { logwrite(LOG_ERROR, "fe: failed to set delivery system with IOCTL_SET_DELSYS with %s", strerror(errno)); exit(-1); } if (ioctl(adapter->fe.fd, IOCTL_GET_INFO, &adapter->fe.feinfo)) { logwrite(LOG_ERROR, "fe: ioctl(DVBFE_GET_INFO...) failed"); exit(-1); } logwrite(LOG_DEBUG, "fe: adapter %d delivery type %d name \"%s\"", adapter->no, adapter->type, adapter->fe.feinfo.name); logwrite(LOG_DEBUG, "fe: adapter %d frequency min %d max %d step %d tolerance %d", adapter->no, adapter->fe.feinfo.frequency_min, adapter->fe.feinfo.frequency_max, adapter->fe.feinfo.frequency_step, adapter->fe.feinfo.frequency_tolerance); logwrite(LOG_DEBUG, "fe: adapter %d symbol rate min %d max %d tolerance %d", adapter->no, adapter->fe.feinfo.symbol_rate_min, adapter->fe.feinfo.symbol_rate_max, adapter->fe.feinfo.symbol_rate_tolerance);}#elsestatic void fe_checkcap(struct adapter_s *adapter) { char *type="unknown"; if (ioctl(adapter->fe.fd, IOCTL_GET_INFO, &adapter->fe.feinfo)) { logwrite(LOG_ERROR, "fe: ioctl(FE_GET_INFO...) failed"); exit(-1); } switch(adapter->fe.feinfo.type) { case(FE_QPSK): type="QPSK"; if (adapter->type == AT_DVBS) break; logwrite(LOG_ERROR, "fe: Adapter %d is an DVB-S card - config is not for DVB-S", adapter->no); exit(-1); case(FE_OFDM): type="OFDM"; if (adapter->type == AT_DVBT) break; logwrite(LOG_ERROR, "fe: Adapter %d is an DVB-T card - config is not for DVB-T", adapter->no); exit(-1); case(FE_QAM): type="QAM"; if (adapter->type == AT_DVBC) break; logwrite(LOG_ERROR, "fe: Adapter %d is an DVB-C card - config is not for DVB-C", adapter->no); exit(-1); default: logwrite(LOG_ERROR, "fe: Adapter %d is an unknown card type %d", adapter->no, adapter->fe.feinfo.type); break; } if (adapter->fe.feinfo.type == FE_QPSK && !(adapter->fe.feinfo.caps & FE_CAN_FEC_AUTO)) { logwrite(LOG_ERROR, "fe: adapter %d is incapable of handling FEC_AUTO - please report to flo@rfc822.org", adapter->no); } logwrite(LOG_DEBUG, "fe: adapter %d type %s name \"%s\"", adapter->no, type, adapter->fe.feinfo.name); logwrite(LOG_DEBUG, "fe: adapter %d frequency min %d max %d step %d tolerance %d", adapter->no, adapter->fe.feinfo.frequency_min, adapter->fe.feinfo.frequency_max, adapter->fe.feinfo.frequency_stepsize, adapter->fe.feinfo.frequency_tolerance); logwrite(LOG_DEBUG, "fe: adapter %d symbol rate min %d max %d tolerance %d", adapter->no, adapter->fe.feinfo.symbol_rate_min, adapter->fe.feinfo.symbol_rate_max, adapter->fe.feinfo.symbol_rate_tolerance);}#endifint fe_tune_init(struct adapter_s *adapter) { char fename[128]; sprintf(fename, "/dev/dvb/adapter%d/frontend0", adapter->no); adapter->fe.fd=open(fename, O_RDWR|O_NONBLOCK); if (adapter->fe.fd < 0) { logwrite(LOG_ERROR, "Error opening dvb frontend %s", fename); exit(-1); } logwrite(LOG_INFO, "fe: Adapter %d Setting up frontend tuner", adapter->no); fe_checkcap(adapter); /* Single shot - try to tune */ fe_tune(adapter); /* Watch the filedescriptor for frontend events */ event_set(&adapter->fe.event, adapter->fe.fd, EV_READ|EV_PERSIST, fe_event, adapter); event_add(&adapter->fe.event, NULL); /* Create a timer to regular poll the status */ fe_timer_init(adapter); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -