extensions to tune dvb-s2 via s2api
This commit is contained in:
parent
66d7585d89
commit
3ddef93591
5 changed files with 226 additions and 27 deletions
|
@ -64,7 +64,9 @@ typedef struct dvb_mux_conf {
|
|||
struct dvb_frontend_parameters dmc_fe_params;
|
||||
int dmc_polarisation;
|
||||
dvb_satconf_t *dmc_satconf;
|
||||
|
||||
fe_modulation_t dmc_fe_modulation;
|
||||
fe_delivery_system_t dmc_fe_delsys;
|
||||
fe_rolloff_t dmc_fe_rolloff;
|
||||
} dvb_mux_conf_t;
|
||||
|
||||
|
||||
|
|
|
@ -601,10 +601,12 @@ dvb_fe_opts(th_dvb_adapter_t *tda, const char *which)
|
|||
fe_opts_add(a, "2/3", FEC_2_3);
|
||||
fe_opts_add(a, "3/4", FEC_3_4);
|
||||
fe_opts_add(a, "4/5", FEC_4_5);
|
||||
fe_opts_add(a, "3/5", FEC_3_5);
|
||||
fe_opts_add(a, "5/6", FEC_5_6);
|
||||
fe_opts_add(a, "6/7", FEC_6_7);
|
||||
fe_opts_add(a, "7/8", FEC_7_8);
|
||||
fe_opts_add(a, "8/9", FEC_8_9);
|
||||
fe_opts_add(a, "9/10", FEC_9_10);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
|
100
src/dvb/dvb_fe.c
100
src/dvb/dvb_fe.c
|
@ -174,6 +174,48 @@ dvb_fe_stop(th_dvb_mux_instance_t *tdmi)
|
|||
}
|
||||
|
||||
|
||||
static int check_frontend (int fe_fd, int dvr, int human_readable) {
|
||||
(void)dvr;
|
||||
fe_status_t status;
|
||||
uint16_t snr, signal;
|
||||
uint32_t ber, uncorrected_blocks;
|
||||
int timeout = 0;
|
||||
|
||||
do {
|
||||
if (ioctl(fe_fd, FE_READ_STATUS, &status) == -1)
|
||||
perror("FE_READ_STATUS failed");
|
||||
/* some frontends might not support all these ioctls, thus we
|
||||
* avoid printing errors
|
||||
*/
|
||||
if (ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal) == -1)
|
||||
signal = -2;
|
||||
if (ioctl(fe_fd, FE_READ_SNR, &snr) == -1)
|
||||
snr = -2;
|
||||
if (ioctl(fe_fd, FE_READ_BER, &ber) == -1)
|
||||
ber = -2;
|
||||
if (ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks) == -1)
|
||||
uncorrected_blocks = -2;
|
||||
|
||||
if (human_readable) {
|
||||
printf ("status %02x | signal %3u%% | snr %3u%% | ber %d | unc %d | ",
|
||||
status, (signal * 100) / 0xffff, (snr * 100) / 0xffff, ber, uncorrected_blocks);
|
||||
} else {
|
||||
printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
|
||||
status, signal, snr, ber, uncorrected_blocks);
|
||||
}
|
||||
if (status & FE_HAS_LOCK)
|
||||
printf("FE_HAS_LOCK");
|
||||
printf("\n");
|
||||
|
||||
if ((status & FE_HAS_LOCK) || (++timeout >= 10))
|
||||
break;
|
||||
|
||||
usleep(1000000);
|
||||
} while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -245,12 +287,62 @@ dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason)
|
|||
"dvb", "\"%s\" tuning to \"%s\" (%s)", tda->tda_rootpath, buf,
|
||||
reason);
|
||||
|
||||
r = ioctl(tda->tda_fe_fd, FE_SET_FRONTEND, &p);
|
||||
if (tda->tda_type == FE_QPSK) {
|
||||
struct dtv_property clear_p[] = {
|
||||
{ .cmd = DTV_CLEAR },
|
||||
};
|
||||
|
||||
struct dtv_properties clear_cmdseq = {
|
||||
.num = 1,
|
||||
.props = clear_p
|
||||
};
|
||||
|
||||
if ((ioctl(tda->tda_fe_fd, FE_SET_PROPERTY, &clear_cmdseq)) != 0) {
|
||||
perror("FE_SET_PROPERTY DTV_CLEAR failed");
|
||||
return;
|
||||
}
|
||||
struct dvb_frontend_event ev;
|
||||
|
||||
/* Support for legacy satellite tune, with the new API. */
|
||||
struct dtv_property _dvbs_cmdargs[] = {
|
||||
{ .cmd = DTV_DELIVERY_SYSTEM, .u.data = tdmi->tdmi_conf.dmc_fe_delsys },
|
||||
{ .cmd = DTV_FREQUENCY, .u.data = p.frequency },
|
||||
{ .cmd = DTV_MODULATION, .u.data = tdmi->tdmi_conf.dmc_fe_modulation },
|
||||
{ .cmd = DTV_SYMBOL_RATE, .u.data = p.u.qpsk.symbol_rate },
|
||||
{ .cmd = DTV_INNER_FEC, .u.data = p.u.qpsk.fec_inner },
|
||||
{ .cmd = DTV_INVERSION, .u.data = INVERSION_AUTO },
|
||||
{ .cmd = DTV_ROLLOFF, .u.data = tdmi->tdmi_conf.dmc_fe_rolloff },
|
||||
{ .cmd = DTV_PILOT, .u.data = PILOT_AUTO },
|
||||
{ .cmd = DTV_TUNE },
|
||||
};
|
||||
|
||||
struct dtv_properties _dvbs_cmdseq = {
|
||||
.num = 9,
|
||||
.props = _dvbs_cmdargs
|
||||
};
|
||||
|
||||
/* discard stale QPSK events */
|
||||
while (1) {
|
||||
if (ioctl(tda->tda_fe_fd, FE_GET_EVENT, &ev) == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
tvhlog(LOG_INFO,
|
||||
"dvb", "tuning via s2api to %s, freq %d, symbolrate %d, fec %d, sys %d, mod %d",
|
||||
buf, p.frequency, p.u.qpsk.symbol_rate, p.u.qpsk.fec_inner, tdmi->tdmi_conf.dmc_fe_delsys,
|
||||
tdmi->tdmi_conf.dmc_fe_modulation);
|
||||
r = ioctl(tda->tda_fe_fd, FE_SET_PROPERTY, &_dvbs_cmdseq);
|
||||
|
||||
if(0)
|
||||
check_frontend (tda->tda_fe_fd, 0, 1);
|
||||
} else
|
||||
r = ioctl(tda->tda_fe_fd, FE_SET_FRONTEND, &p);
|
||||
|
||||
if(r != 0) {
|
||||
tvhlog(LOG_ERR, "dvb", "\"%s\" tuning to \"%s\""
|
||||
" -- Front configuration failed -- %s",
|
||||
tda->tda_rootpath, buf, strerror(errno));
|
||||
}
|
||||
" -- Front configuration failed -- %s",
|
||||
tda->tda_rootpath, buf, strerror(errno));
|
||||
}
|
||||
|
||||
tda->tda_mux_current = tdmi;
|
||||
|
||||
|
|
|
@ -133,7 +133,10 @@ tdmi_compare_conf(int adapter_type,
|
|||
case FE_QPSK:
|
||||
return memcmp(&a->dmc_fe_params.u.qpsk,
|
||||
&b->dmc_fe_params.u.qpsk,
|
||||
sizeof(a->dmc_fe_params.u.qpsk));
|
||||
sizeof(a->dmc_fe_params.u.qpsk)) ||
|
||||
a->dmc_fe_modulation != b->dmc_fe_modulation ||
|
||||
a->dmc_fe_delsys != b->dmc_fe_delsys ||
|
||||
a->dmc_fe_rolloff != b->dmc_fe_rolloff;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -166,6 +169,8 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
|
|||
if(!tdmi_compare_conf(tda->tda_type, &tdmi->tdmi_conf, dmc))
|
||||
return NULL; // Nothings changed
|
||||
|
||||
memcpy(&tdmi->tdmi_conf, dmc, sizeof(struct dvb_mux_conf));
|
||||
|
||||
dvb_mux_save(tdmi);
|
||||
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
|
@ -315,9 +320,12 @@ dvb_mux_find_by_identifier(const char *identifier)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static struct strtab rollofftab[] = {
|
||||
{ "ROLLOFF_35", ROLLOFF_35 },
|
||||
{ "ROLLOFF_20", ROLLOFF_20 },
|
||||
{ "ROLLOFF_25", ROLLOFF_25 },
|
||||
{ "ROLLOFF_AUTO", ROLLOFF_AUTO }
|
||||
};
|
||||
|
||||
static struct strtab fectab[] = {
|
||||
{ "NONE", FEC_NONE },
|
||||
|
@ -329,19 +337,44 @@ static struct strtab fectab[] = {
|
|||
{ "6/7", FEC_6_7 },
|
||||
{ "7/8", FEC_7_8 },
|
||||
{ "8/9", FEC_8_9 },
|
||||
{ "AUTO", FEC_AUTO }
|
||||
{ "AUTO", FEC_AUTO },
|
||||
{ "3/5", FEC_3_4 },
|
||||
{ "9/10", FEC_9_10 }
|
||||
};
|
||||
|
||||
static struct strtab qamtab[] = {
|
||||
{ "QPSK", QPSK },
|
||||
{ "QAM16", QAM_16 },
|
||||
{ "QAM32", QAM_32 },
|
||||
{ "QAM64", QAM_64 },
|
||||
{ "QAM128", QAM_128 },
|
||||
{ "QAM256", QAM_256 },
|
||||
{ "AUTO", QAM_AUTO },
|
||||
{ "8VSB", VSB_8 },
|
||||
{ "16VSB", VSB_16 }
|
||||
{ "QPSK", QPSK },
|
||||
{ "QAM16", QAM_16 },
|
||||
{ "QAM32", QAM_32 },
|
||||
{ "QAM64", QAM_64 },
|
||||
{ "QAM128", QAM_128 },
|
||||
{ "QAM256", QAM_256 },
|
||||
{ "AUTO", QAM_AUTO },
|
||||
{ "8VSB", VSB_8 },
|
||||
{ "16VSB", VSB_16 },
|
||||
{ "PSK_8", PSK_8 },
|
||||
{ "APSK_16", APSK_16 },
|
||||
{ "APSK_32", APSK_32 },
|
||||
{ "DQPSK", DQPSK }
|
||||
};
|
||||
|
||||
static struct strtab delsystab[] = {
|
||||
{ "SYS_UNDEFINED", SYS_UNDEFINED },
|
||||
{ "SYS_DVBC_ANNEX_AC", SYS_DVBC_ANNEX_AC },
|
||||
{ "SYS_DVBC_ANNEX_B", SYS_DVBC_ANNEX_B },
|
||||
{ "SYS_DVBT", SYS_DVBT },
|
||||
{ "SYS_DSS", SYS_DSS },
|
||||
{ "SYS_DVBS", SYS_DVBS },
|
||||
{ "SYS_DVBS2", SYS_DVBS2 },
|
||||
{ "SYS_DVBH", SYS_DVBH },
|
||||
{ "SYS_ISDBT", SYS_ISDBT },
|
||||
{ "SYS_ISDBS", SYS_ISDBS },
|
||||
{ "SYS_ISDBC", SYS_ISDBC },
|
||||
{ "SYS_ATSC", SYS_ATSC },
|
||||
{ "SYS_ATSCMH", SYS_ATSCMH },
|
||||
{ "SYS_DMBTH", SYS_DMBTH },
|
||||
{ "SYS_CMMB", SYS_CMMB },
|
||||
{ "SYS_DAB", SYS_DAB }
|
||||
};
|
||||
|
||||
static struct strtab bwtab[] = {
|
||||
|
@ -429,10 +462,19 @@ dvb_mux_save(th_dvb_mux_instance_t *tdmi)
|
|||
htsmsg_add_u32(m, "symbol_rate", f->u.qpsk.symbol_rate);
|
||||
|
||||
htsmsg_add_str(m, "fec",
|
||||
val2str(f->u.qpsk.fec_inner, fectab));
|
||||
val2str(f->u.qpsk.fec_inner, fectab));
|
||||
|
||||
htsmsg_add_str(m, "polarisation",
|
||||
val2str(tdmi->tdmi_conf.dmc_polarisation, poltab));
|
||||
val2str(tdmi->tdmi_conf.dmc_polarisation, poltab));
|
||||
|
||||
htsmsg_add_str(m, "modulation",
|
||||
val2str(tdmi->tdmi_conf.dmc_fe_modulation, qamtab));
|
||||
|
||||
htsmsg_add_str(m, "delivery_system",
|
||||
val2str(tdmi->tdmi_conf.dmc_fe_delsys, delsystab));
|
||||
|
||||
htsmsg_add_str(m, "rolloff",
|
||||
val2str(tdmi->tdmi_conf.dmc_fe_rolloff, rollofftab));
|
||||
break;
|
||||
|
||||
case FE_QAM:
|
||||
|
@ -470,7 +512,6 @@ tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m, const char *identifier)
|
|||
struct dvb_mux_conf dmc;
|
||||
const char *s;
|
||||
int r;
|
||||
int polarisation = 0;
|
||||
unsigned int tsid, u32, enabled;
|
||||
dvb_satconf_t *sc;
|
||||
|
||||
|
@ -531,7 +572,31 @@ tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m, const char *identifier)
|
|||
s = htsmsg_get_str(m, "polarisation");
|
||||
if(s == NULL || (r = str2val(s, poltab)) < 0)
|
||||
return "Invalid polarisation";
|
||||
polarisation = r;
|
||||
dmc.dmc_polarisation = r;
|
||||
|
||||
s = htsmsg_get_str(m, "modulation");
|
||||
if(s == NULL || (r = str2val(s, qamtab)) < 0) {
|
||||
r = str2val("QPSK", qamtab);
|
||||
tvhlog(LOG_INFO,
|
||||
"dvb", "no modulation for mux found, defaulting to QPSK");
|
||||
}
|
||||
dmc.dmc_fe_modulation = r;
|
||||
|
||||
s = htsmsg_get_str(m, "delivery_system");
|
||||
if(s == NULL || (r = str2val(s, delsystab)) < 0) {
|
||||
r = str2val("SYS_DVBS", delsystab);
|
||||
tvhlog(LOG_INFO,
|
||||
"dvb", "no delivery system for mux found, defaulting to SYS_DVBS");
|
||||
}
|
||||
dmc.dmc_fe_delsys = r;
|
||||
|
||||
s = htsmsg_get_str(m, "rolloff");
|
||||
if(s == NULL || (r = str2val(s, rollofftab)) < 0) {
|
||||
r = str2val("ROLLOFF_35", rollofftab);
|
||||
tvhlog(LOG_INFO,
|
||||
"dvb", "no rolloff for mux found, defaulting to ROLLOFF_35");
|
||||
}
|
||||
dmc.dmc_fe_rolloff = r;
|
||||
break;
|
||||
|
||||
case FE_QAM:
|
||||
|
|
|
@ -800,9 +800,11 @@ dvb_cat_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
/**
|
||||
* Tables for delivery descriptor parsing
|
||||
*/
|
||||
static const fe_code_rate_t fec_tab [8] = {
|
||||
static const fe_code_rate_t fec_tab [16] = {
|
||||
FEC_AUTO, FEC_1_2, FEC_2_3, FEC_3_4,
|
||||
FEC_5_6, FEC_7_8, FEC_NONE, FEC_NONE
|
||||
FEC_5_6, FEC_7_8, FEC_8_9, FEC_3_5,
|
||||
FEC_4_5, FEC_9_10, FEC_NONE, FEC_NONE,
|
||||
FEC_NONE, FEC_NONE, FEC_NONE, FEC_NONE
|
||||
};
|
||||
|
||||
|
||||
|
@ -862,7 +864,7 @@ static int
|
|||
dvb_table_sat_delivery(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||
uint16_t tsid)
|
||||
{
|
||||
int freq, symrate;
|
||||
int freq, symrate, modulation;
|
||||
struct dvb_mux_conf dmc;
|
||||
|
||||
if(!tdmi->tdmi_adapter->tda_autodiscovery)
|
||||
|
@ -884,14 +886,50 @@ dvb_table_sat_delivery(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
bcdtoint(ptr[9]) * 10 + (ptr[10] >> 4);
|
||||
dmc.dmc_fe_params.u.qam.symbol_rate = symrate * 100;
|
||||
|
||||
dmc.dmc_fe_params.u.qam.fec_inner = fec_tab[ptr[10] & 0x07];
|
||||
dmc.dmc_fe_params.u.qam.fec_inner = fec_tab[ptr[10] & 0x0f];
|
||||
|
||||
dmc.dmc_polarisation = (ptr[6] >> 5) & 0x03;
|
||||
// Same satconf (lnb, switch, etc)
|
||||
dmc.dmc_satconf = tdmi->tdmi_conf.dmc_satconf;
|
||||
|
||||
modulation = (ptr[6] & 0x03);
|
||||
|
||||
if (modulation == 0x01)
|
||||
dmc.dmc_fe_modulation = QPSK;
|
||||
else if (modulation == 0x02)
|
||||
dmc.dmc_fe_modulation = PSK_8;
|
||||
else if (modulation == 0x03)
|
||||
dmc.dmc_fe_modulation = QAM_16;
|
||||
else
|
||||
dmc.dmc_fe_modulation = 0;
|
||||
|
||||
if (ptr[6] & 0x04) {
|
||||
dmc.dmc_fe_delsys = SYS_DVBS2;
|
||||
|
||||
switch ((ptr[6] >> 3) & 0x03) {
|
||||
case 0x00:
|
||||
dmc.dmc_fe_rolloff = ROLLOFF_35;
|
||||
break;
|
||||
case 0x01:
|
||||
dmc.dmc_fe_rolloff = ROLLOFF_25;
|
||||
break;
|
||||
case 0x02:
|
||||
dmc.dmc_fe_rolloff = ROLLOFF_20;
|
||||
break;
|
||||
default:
|
||||
case 0x03:
|
||||
dmc.dmc_fe_rolloff = ROLLOFF_AUTO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dmc.dmc_fe_delsys = SYS_DVBS;
|
||||
dmc.dmc_fe_rolloff = ROLLOFF_35;
|
||||
}
|
||||
|
||||
dvb_mux_create(tdmi->tdmi_adapter, &dmc, tsid, NULL,
|
||||
"automatic mux discovery", 1, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue