]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
linuxdvb: ensure that the enabled flag is properly honoured
authorAdam Sutton <dev@adamsutton.me.uk>
Mon, 14 Apr 2014 20:29:56 +0000 (21:29 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Mon, 14 Apr 2014 20:29:56 +0000 (21:29 +0100)
src/input/mpegts.h
src/input/mpegts/linuxdvb/linuxdvb_adapter.c
src/input/mpegts/linuxdvb/linuxdvb_frontend.c
src/input/mpegts/linuxdvb/linuxdvb_private.h
src/input/mpegts/mpegts_input.c

index e0a56df8c8b6dfbf8c6898bfe73eb2de028c2814..a4c5d7554c553dd0b216818379459c32484bb186 100644 (file)
@@ -487,6 +487,7 @@ struct mpegts_input
    * Functions
    */
   int  (*mi_is_enabled)     (mpegts_input_t*);
+  void (*mi_enabled_updated)(mpegts_input_t*);
   void (*mi_display_name)   (mpegts_input_t*, char *buf, size_t len);
   int  (*mi_is_free)        (mpegts_input_t*);
   int  (*mi_get_weight)     (mpegts_input_t*);
index f48915b4d9de134ba9d11a0114496eef0fadb5ce..74ba3c2685adac9595a2128154ca0889dde67bff 100644 (file)
@@ -183,6 +183,7 @@ linux_dvb_get_type(int linux_type)
 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];
@@ -226,7 +227,7 @@ linuxdvb_adapter_add ( const char *path )
 
     /* 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);
       }
@@ -234,7 +235,7 @@ linuxdvb_adapter_add ( const char *path )
     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);
     }
@@ -310,6 +311,7 @@ linuxdvb_adapter_add ( const char *path )
         htsmsg_destroy(conf);
         return; // Note: save to return here as global_lock is held
       }
+      tvhinfo("linuxdvb", "adapter added %s", path);
     }
 
     /* Create frontend */
@@ -418,6 +420,7 @@ devdvb_create ( fsmonitor_t *fsm, const char *path )
 static void
 devdvb_delete ( fsmonitor_t *fsm, const char *path )
 {
+  tvhinfo("linuxdvb", "adapter removed %s", path);
   linuxdvb_adapter_del(path);
 }
 
index 66f417263f0df0b47f7fa3c440cebedcbcd8f926..d34a2d0c35b9344647384ca9bbe37db00348deee 100644 (file)
@@ -93,9 +93,9 @@ const idclass_t linuxdvb_frontend_class =
     },
     {
       .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),
     },
     {}
   }
@@ -192,6 +192,29 @@ const idclass_t linuxdvb_frontend_atsc_class =
  * 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 )
 {
@@ -416,9 +439,13 @@ linuxdvb_frontend_monitor ( void *aux )
 
   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;
@@ -433,9 +460,12 @@ linuxdvb_frontend_monitor ( void *aux )
     }
   }
 
-  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));
@@ -1173,11 +1203,12 @@ linuxdvb_frontend_create
   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;
@@ -1199,6 +1230,9 @@ linuxdvb_frontend_create
   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;
 }
 
index ea96b48b4eb04d1b0cbdd1751900916e211bd739..b5592d9d922458fb7f23ab65cd3d1be9aa0957c8 100644 (file)
@@ -108,7 +108,7 @@ struct linuxdvb_frontend
    * Configuration
    */
   int                       lfe_fullmux;
-  int                       lfe_noclosefe;
+  int                       lfe_powersave;
 
   /*
    * Satconf (DVB-S only)
index 39fedb4d6ef9835a9aedfe81177227caa4a7f83c..40d985530d6bbd38eb52d2df62b68e3160e64c26 100644 (file)
@@ -99,6 +99,21 @@ mpegts_input_class_network_rend ( void *obj )
   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",
@@ -110,6 +125,7 @@ const idclass_t mpegts_input_class =
       .id       = "enabled",
       .name     = "Enabled",
       .off      = offsetof(mpegts_input_t, mi_enabled),
+      .notify   = mpegts_input_enabled_notify,
       .def.i    = 1,
     },
     {