static void
linuxdvb_adapter_add ( const char *path )
{
+#define MAX_DEV_OPEN_ATTEMPTS 20
extern int linuxdvb_adapter_mask;
int a, i, j, r, fd;
char fe_path[512], dmx_path[512], dvr_path[512];
/* Wait for access (first FE can take a fe ms to be setup) */
if (!i) {
- for (j = 0; j < 10; j++) {
+ for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) {
if (!access(fe_path, R_OK | W_OK)) break;
usleep(100000);
}
if (access(fe_path, R_OK | W_OK)) continue;
/* Get frontend info */
- for (j = 0; j < 10; j++) {
+ for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) {
if ((fd = tvh_open(fe_path, O_RDWR, 0)) > 0) break;
usleep(100000);
}
htsmsg_destroy(conf);
return; // Note: save to return here as global_lock is held
}
+ tvhinfo("linuxdvb", "adapter added %s", path);
}
/* Create frontend */
static void
devdvb_delete ( fsmonitor_t *fsm, const char *path )
{
+ tvhinfo("linuxdvb", "adapter removed %s", path);
linuxdvb_adapter_del(path);
}
},
{
.type = PT_BOOL,
- .id = "noclosefe",
- .name = "Keep FE open",
- .off = offsetof(linuxdvb_frontend_t, lfe_noclosefe),
+ .id = "powersave",
+ .name = "Power Save",
+ .off = offsetof(linuxdvb_frontend_t, lfe_powersave),
},
{}
}
* Class methods
* *************************************************************************/
+static void
+linuxdvb_frontend_enabled_updated ( mpegts_input_t *mi )
+{
+ char buf[512];
+ linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
+
+ mi->mi_display_name(mi, buf, sizeof(buf));
+
+ /* Ensure disabled */
+ if (!mi->mi_enabled) {
+ tvhtrace("linuxdvb", "%s - disabling tuner", buf);
+ if (lfe->lfe_fe_fd > 0)
+ close(lfe->lfe_fe_fd);
+ gtimer_disarm(&lfe->lfe_monitor_timer);
+
+ /* Ensure FE opened (if not powersave) */
+ } else if (!lfe->lfe_powersave && lfe->lfe_fe_fd <= 0 && lfe->lfe_fe_path) {
+ lfe->lfe_fe_fd = tvh_open(lfe->lfe_fe_path, O_RDWR | O_NONBLOCK, 0);
+ tvhtrace("linuxdvb", "%s - opening FE %s (%d)",
+ buf, lfe->lfe_fe_path, lfe->lfe_fe_fd);
+ }
+}
+
static int
linuxdvb_frontend_is_free ( mpegts_input_t *mi )
{
lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf));
tvhtrace("linuxdvb", "%s - checking FE status", buf);
+
+ /* Disabled */
+ if (!lfe->mi_enabled && mmi)
+ mmi->mmi_mux->mm_stop(mmi->mmi_mux, 1);
/* Close FE */
- if (lfe->lfe_fe_fd > 0 && !mmi && !lfe->lfe_noclosefe) {
+ if (lfe->lfe_fe_fd > 0 && !mmi && lfe->lfe_powersave) {
tvhtrace("linuxdvb", "%s - closing frontend", buf);
close(lfe->lfe_fe_fd);
lfe->lfe_fe_fd = -1;
}
}
- gtimer_arm(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 1);
+ /* Stop timer */
if (!mmi) return;
+ /* re-arm */
+ gtimer_arm(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 1);
+
/* Get current status */
if (ioctl(lfe->lfe_fe_fd, FE_READ_STATUS, &fe_status) == -1) {
tvhwarn("linuxdvb", "%s - FE_READ_STATUS error %s", buf, strerror(errno));
lfe->lfe_dvr_path = strdup(dvr_path);
/* Input callbacks */
- lfe->mi_is_enabled = linuxdvb_frontend_is_enabled;
- lfe->mi_start_mux = linuxdvb_frontend_start_mux;
- lfe->mi_stop_mux = linuxdvb_frontend_stop_mux;
- lfe->mi_network_list = linuxdvb_frontend_network_list;
- lfe->mi_open_pid = linuxdvb_frontend_open_pid;
+ lfe->mi_is_enabled = linuxdvb_frontend_is_enabled;
+ lfe->mi_start_mux = linuxdvb_frontend_start_mux;
+ lfe->mi_stop_mux = linuxdvb_frontend_stop_mux;
+ lfe->mi_network_list = linuxdvb_frontend_network_list;
+ lfe->mi_open_pid = linuxdvb_frontend_open_pid;
+ lfe->mi_enabled_updated = linuxdvb_frontend_enabled_updated;
/* Adapter link */
lfe->lfe_adapter = la;
if (lfe->lfe_type == DVB_TYPE_S && !lfe->lfe_satconf)
lfe->lfe_satconf = linuxdvb_satconf_create(lfe, sctype, scuuid, scconf);
+ /* Double check enabled */
+ linuxdvb_frontend_enabled_updated((mpegts_input_t*)lfe);
+
return lfe;
}
return str;
}
+static void
+mpegts_input_enabled_notify ( void *p )
+{
+ mpegts_input_t *mi = p;
+ mpegts_mux_instance_t *mmi;
+
+ /* Stop */
+ LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link)
+ mmi->mmi_mux->mm_stop(mmi->mmi_mux, 1);
+
+ /* Alert */
+ if (mi->mi_enabled_updated)
+ mi->mi_enabled_updated(mi);
+}
+
const idclass_t mpegts_input_class =
{
.ic_class = "mpegts_input",
.id = "enabled",
.name = "Enabled",
.off = offsetof(mpegts_input_t, mi_enabled),
+ .notify = mpegts_input_enabled_notify,
.def.i = 1,
},
{