diff --git a/src/dvb/diseqc.c b/src/dvb/diseqc.c index c3344d0e..404c423c 100644 --- a/src/dvb/diseqc.c +++ b/src/dvb/diseqc.c @@ -112,3 +112,13 @@ diseqc_setup(int frontend_fd, int switch_pos, int voltage_18, int hiband, } +int diseqc_voltage_off(int frontend_fd) +{ + fe_sec_voltage_t v = SEC_VOLTAGE_OFF; + int err; + + if ((err = ioctl(frontend_fd, FE_SET_VOLTAGE, v))) + return err; + + return 0; +} diff --git a/src/dvb/diseqc.h b/src/dvb/diseqc.h index a1ad4509..5daeb88d 100644 --- a/src/dvb/diseqc.h +++ b/src/dvb/diseqc.h @@ -21,5 +21,6 @@ extern int diseqc_send_msg(int fd, fe_sec_voltage_t v, struct diseqc_cmd **cmd, int diseqc_setup(int frontend_fd, int switch_pos, int voltage_18, int hiband, int diseqc_ver); -#endif +int diseqc_voltage_off(int frontend_fd); +#endif diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 997bf4f3..d7d30d93 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -175,6 +175,7 @@ typedef struct th_dvb_adapter { uint32_t tda_autodiscovery; uint32_t tda_idlescan; uint32_t tda_qmon; + uint32_t tda_off; uint32_t tda_nitoid; uint32_t tda_diseqc_version; char *tda_displayname; @@ -288,6 +289,8 @@ void dvb_adapter_set_qmon(th_dvb_adapter_t *tda, int on); void dvb_adapter_set_dump_muxes(th_dvb_adapter_t *tda, int on); +void dvb_adapter_set_off(th_dvb_adapter_t *tda, int on); + void dvb_adapter_set_nitoid(th_dvb_adapter_t *tda, int nitoid); void dvb_adapter_set_diseqc_version(th_dvb_adapter_t *tda, unsigned int v); @@ -389,6 +392,8 @@ int dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason); void dvb_fe_stop(th_dvb_mux_instance_t *tdmi); +void dvb_fe_turn_off(th_dvb_adapter_t *tda); + /** * DVB Tables diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index 5f0bfe86..5cffdbdb 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -86,6 +86,7 @@ tda_save(th_dvb_adapter_t *tda) htsmsg_add_u32(m, "idlescan", tda->tda_idlescan); htsmsg_add_u32(m, "qmon", tda->tda_qmon); htsmsg_add_u32(m, "dump_muxes", tda->tda_dump_muxes); + htsmsg_add_u32(m, "off", tda->tda_off); htsmsg_add_u32(m, "nitoid", tda->tda_nitoid); htsmsg_add_u32(m, "diseqc_version", tda->tda_diseqc_version); htsmsg_add_u32(m, "extrapriority", tda->tda_extrapriority); @@ -194,6 +195,25 @@ dvb_adapter_set_qmon(th_dvb_adapter_t *tda, int on) } +/** + * + */ +void +dvb_adapter_set_off(th_dvb_adapter_t *tda, int on) +{ + if(tda->tda_off == on) + return; + + lock_assert(&global_lock); + + tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" idle off set to: %s", + tda->tda_displayname, on ? "On" : "Off"); + + tda->tda_off = on; + tda_save(tda); +} + + /** * */ @@ -421,6 +441,7 @@ dvb_adapter_init(uint32_t adapter_mask) htsmsg_get_u32(c, "idlescan", &tda->tda_idlescan); htsmsg_get_u32(c, "qmon", &tda->tda_qmon); htsmsg_get_u32(c, "dump_muxes", &tda->tda_dump_muxes); + htsmsg_get_u32(c, "off", &tda->tda_off); htsmsg_get_u32(c, "nitoid", &tda->tda_nitoid); htsmsg_get_u32(c, "diseqc_version", &tda->tda_diseqc_version); htsmsg_get_u32(c, "extrapriority", &tda->tda_extrapriority); @@ -453,7 +474,7 @@ dvb_adapter_mux_scanner(void *aux) gtimer_arm(&tda->tda_mux_scanner_timer, dvb_adapter_mux_scanner, tda, 20); if(LIST_FIRST(&tda->tda_muxes) == NULL) - return; // No muxes configured + goto off; // No muxes configured if(service_compute_weight(&tda->tda_transports) > 0) return; /* someone is here */ @@ -479,13 +500,13 @@ dvb_adapter_mux_scanner(void *aux) if(!idle_epg && TAILQ_FIRST(&tda->tda_scan_queues[TDA_SCANQ_BAD]) == NULL) { if(!tda->tda_qmon) - return; // Quality monitoring is disabled + goto off; // Quality monitoring is disabled /* If the currently tuned mux is ok, we can stick to it */ tdmi = tda->tda_mux_current; if(tdmi != NULL && tdmi->tdmi_quality > 90) - return; + goto off; } /* EPG */ @@ -511,6 +532,10 @@ dvb_adapter_mux_scanner(void *aux) } } } + +off: + /* turn off the LNB voltage */ + dvb_fe_turn_off(tda); } /** diff --git a/src/dvb/dvb_fe.c b/src/dvb/dvb_fe.c index 173f9700..efff87cc 100644 --- a/src/dvb/dvb_fe.c +++ b/src/dvb/dvb_fe.c @@ -526,3 +526,18 @@ dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason) dvb_adapter_notify(tda); return 0; } + +/** + * + */ +void dvb_fe_turn_off(th_dvb_adapter_t *tda) +{ + lock_assert(&global_lock); + if (!tda->tda_off) + return; + if (tda->tda_mux_current) + dvb_fe_stop(tda->tda_mux_current); + if (tda->tda_type == FE_QPSK) + diseqc_voltage_off(tda->tda_fe_fd); + tvhlog(LOG_DEBUG, "dvb", "\"%s\" is off", tda->tda_rootpath); +} diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index 1eb4e490..ea6b3303 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -152,6 +152,7 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) htsmsg_add_u32(r, "idlescan", tda->tda_idlescan); htsmsg_add_u32(r, "qmon", tda->tda_qmon); htsmsg_add_u32(r, "dumpmux", tda->tda_dump_muxes); + htsmsg_add_u32(r, "off", tda->tda_off); htsmsg_add_u32(r, "nitoid", tda->tda_nitoid); htsmsg_add_str(r, "diseqcversion", ((const char *[]){"DiSEqC 1.0 / 2.0", @@ -177,6 +178,9 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) s = http_arg_get(&hc->hc_req_args, "qmon"); dvb_adapter_set_qmon(tda, !!s); + s = http_arg_get(&hc->hc_req_args, "off"); + dvb_adapter_set_off(tda, !!s); + s = http_arg_get(&hc->hc_req_args, "dumpmux"); dvb_adapter_set_dump_muxes(tda, !!s); diff --git a/src/webui/static/app/dvb.js b/src/webui/static/app/dvb.js index 13f3976e..ceb614eb 100644 --- a/src/webui/static/app/dvb.js +++ b/src/webui/static/app/dvb.js @@ -1106,7 +1106,7 @@ tvheadend.dvb_adapter_general = function(adapterData, satConfStore) { var confreader = new Ext.data.JsonReader({ root: 'dvbadapters' }, ['name', 'automux', 'skip_initialscan', 'idlescan', 'diseqcversion', 'qmon', - 'dumpmux', 'nitoid','extrapriority']); + 'dumpmux', 'off', 'nitoid','extrapriority']); function saveConfForm () { @@ -1150,6 +1150,10 @@ tvheadend.dvb_adapter_general = function(adapterData, satConfStore) { 'of diskspace. You have been warned'); } }), + new Ext.form.Checkbox({ + fieldLabel: 'Turn off adapter when idle', + name: 'off' + }), { fieldLabel: 'NIT-o Network ID', name: 'nitoid',