]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
mpegts linuxdvb: starting to get more complete config load/save
authorAdam Sutton <dev@adamsutton.me.uk>
Thu, 30 May 2013 19:55:11 +0000 (20:55 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Thu, 30 May 2013 19:55:11 +0000 (20:55 +0100)
12 files changed:
src/idnode.c
src/idnode.h
src/input/mpegts.h
src/input/mpegts/dvb.h
src/input/mpegts/dvb_psi.c
src/input/mpegts/dvb_support.c
src/input/mpegts/linuxdvb/linuxdvb_frontend.c
src/input/mpegts/linuxdvb/linuxdvb_mux.c
src/input/mpegts/linuxdvb/linuxdvb_network.c
src/input/mpegts/mpegts_mux.c
src/input/mpegts/mpegts_network.c
src/prop.c

index 49475f14c3f1c4d16bffb43ef909800405f6f29c..cfcc035266e0ce1bb6bb17fc5689e627e591b0e0 100644 (file)
@@ -342,9 +342,27 @@ idnode_notify_title_changed(void *obj)
   notify_by_msg("idnodeNameChanged", m);
 }
 
-int
-idnode_load_one
-  ( idnode_t *self, htsmsg_t *m )
+/*
+ * Save
+ */
+void
+idnode_save ( idnode_t *self, htsmsg_t *c )
 {
-  return 0;
+  const idclass_t *idc = self->in_class;
+  while (idc) {
+    prop_read_values(self, idc->ic_properties, c);
+    idc = idc->ic_super;
+  }
+}
+
+/*
+ * Load
+ */
+void idnode_load ( idnode_t *self, htsmsg_t *c )
+{
+  const idclass_t *idc = self->in_class;
+  while (idc) {
+    prop_write_values(self, idc->ic_properties, c);
+    idc = idc->ic_super;
+  }
 }
index 9edba2db3d79b3a9a1790c44365c993939d05b5c..da079ac0c4bbaeceba111038fbb22944a5bdbf2d 100644 (file)
@@ -50,16 +50,5 @@ void idnode_update_all_props(idnode_t *in,
 
 void idnode_notify_title_changed(void *obj);
 
-void idnode_save ( idnode_t *self, const char *path );
-
-idnode_t *idnode_load ( htsmsg_field_t *cfg, void*(*create)(const char*) );
-
-void idnode_load_all ( const char *path, void *(*create)(const char*) );
-
-idnode_t *idnode_create0
-  ( size_t alloc, const idclass_t *class, const char *uuid );
-
-#define idnode_create(c, uuid)\
-  (struct c*)idnode_create0(sizeof(struct c), &c##_class, uuid)
-
-int idnode_load_one(idnode_t *self, htsmsg_t *cfg);
+void idnode_save ( idnode_t *self, htsmsg_t *m );
+void idnode_load ( idnode_t *self, htsmsg_t *m );
index bb2e1a4767a8edf9e0670b72714aad3899f1341c..48a5e10d14559299baf25974f291ade124d513b5 100644 (file)
@@ -146,7 +146,6 @@ struct mpegts_network
   /*
    * Identification
    */
-
   char                    *mn_network_name;
 
   /*
@@ -170,30 +169,18 @@ struct mpegts_network
   /*
    * Functions
    */
+  void              (*mn_display_name) (mpegts_network_t*, char *buf, size_t len);
+  void              (*mn_config_save)  (mpegts_network_t*);
   mpegts_mux_t*     (*mn_create_mux)
     (mpegts_mux_t*, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *conf);
   mpegts_service_t* (*mn_create_service)
     (mpegts_mux_t*, uint16_t sid, uint16_t pmt_pid);
-  void              (*mn_display_name) (mpegts_network_t*, char *buf, size_t len);
-  void              (*mn_config_save)  (mpegts_network_t*);
-
-  // Note: the above are slightly odd in that they take mux instead of
-  //       network as initial param. This is intentional as we need to
-  //       know the mux and can easily get to network from there
-
-#if 0 // TODO: FIXME
-  int dn_fe_type;  // Frontend types for this network (FE_QPSK, etc)
-#endif
-
-  uint32_t mn_nid; // limit scope of scanning
-
-#if 0 // TODO: FIXME CONFIG
-  uint32_t dn_disable_pmt_monitor;
-  uint32_t dn_autodiscovery;
-  uint32_t dn_nitoid;
-  uint32_t dn_skip_checksubscr;
-#endif
 
+  /*
+   * Configuration
+   */
+  uint32_t mn_nid;
+  uint32_t mn_autodiscovery;
 };
 
 /* Multiplex */
@@ -249,17 +236,18 @@ struct mpegts_mux
    */
 
   void (*mm_config_save)      (mpegts_mux_t *mm);
+  void (*mm_display_name)     (mpegts_mux_t*, char *buf, size_t len);
+  int  (*mm_is_enabled)       (mpegts_mux_t *mm);
   int  (*mm_start)            (mpegts_mux_t *mm, const char *r, int w);
   void (*mm_stop)             (mpegts_mux_t *mm);
   void (*mm_open_table)       (mpegts_mux_t*,mpegts_table_t*);
   void (*mm_close_table)      (mpegts_mux_t*,mpegts_table_t*);
   void (*mm_create_instances) (mpegts_mux_t*);
-  void (*mm_display_name)     (mpegts_mux_t*, char *buf, size_t len);
 
   /*
-   * Fields
+   * Configuration
    */
-  char *mm_dvb_default_authority;
+  char *mm_crid_authority;
   int   mm_enabled;
 };
  
@@ -473,9 +461,9 @@ mpegts_mux_instance_t *mpegts_mux_instance_create0
                                             &type##_class, uuid,\
                                             mi, mm);
 
-int mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force );
-int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid, int force );
-int mpegts_mux_set_default_authority ( mpegts_mux_t *mm, const char *defauth );
+int mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid );
+int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid );
+int mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth );
 
 size_t mpegts_input_recv_packets
   (mpegts_input_t *mi, mpegts_mux_instance_t *mmi, uint8_t *tsb, size_t len,
index 64e7f10c9c81672ad5bb7794f7529070f8739fd9..c72acf39de3c3b74e567df6787b17466d5c0091b 100644 (file)
@@ -200,8 +200,8 @@ typedef struct dvb_mux_conf
 
 const char *dvb_mux_conf_load
   ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m );
-int dvb_mux_conf_save
-  ( dvb_mux_conf_t *dmc, htsmsg_t *m );
+void dvb_mux_conf_save
+  ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m );
 
 /* conversion routines */
 const char *dvb_rolloff2str ( int rolloff );
index b7469082dfeae14902b4a29f5311f85204dedbec..3ed5fa374e6e4521fe5311eff43cc442d0351be5 100644 (file)
@@ -438,7 +438,7 @@ dvb_pat_callback
 {
   int sect, last, ver;
   uint16_t sid, pid, tsid;
-  uint16_t nit_pid = DVB_NIT_PID;
+  uint16_t nit_pid = 0;
   mpegts_mux_t          *mm  = mt->mt_mux;
 
   /* Begin */
@@ -449,9 +449,7 @@ dvb_pat_callback
   /* Multiplex */
   tsid = (ptr[0] << 8) | ptr[1];
   tvhtrace("pat", "tsid %04X (%d)", tsid, tsid);
-  mpegts_mux_set_tsid(mm, tsid, 0);
-  if (mm->mm_tsid != tsid)
-    return -1;
+  mpegts_mux_set_tsid(mm, tsid);
   
   /* Process each programme */
   ptr += 5;
@@ -463,8 +461,8 @@ dvb_pat_callback
     /* NIT PID */
     if (sid == 0) {
       if (pid) {
-        tvhtrace("pat", "  nit on pid %04X (%d)", pid, pid);
         nit_pid = pid;
+        tvhtrace("pat", "  nit on pid %04X (%d)", pid, pid);
       }
 
     /* Service */
@@ -481,11 +479,13 @@ dvb_pat_callback
     ptr += 4;
     len -= 4;
   }
+  
+  /* Install NIT handler */
+  if (nit_pid)
+    mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback,
+                     NULL, "nit", MT_QUICKREQ | MT_CRC, nit_pid);
 
-  /* Install NIT monitor */
-  mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback,
-                   NULL, "nit", MT_CRC | MT_QUICKREQ, nit_pid);
-
+  /* End */
   dvb_table_end(mt, tableid, sect, last, ver);
   return mt->mt_state[0].complete ? 0 : -1;
 }
@@ -631,7 +631,7 @@ dvb_nit_callback
             return -1;
           tvhtrace(mt->mt_name, "    default auth [%s]", dauth);
           if (mux && *dauth)
-            mpegts_mux_set_default_authority(mux, dauth);
+            mpegts_mux_set_crid_authority(mux, dauth);
           break;
         case DVB_DESC_LOCAL_CHAN:
           if (dvb_desc_local_channel(mt->mt_name, dptr, dlen, mux))
@@ -675,10 +675,8 @@ dvb_sdt_callback
 
   /* Find Transport Stream */
   if (tableid == 0x42) {
-    mpegts_mux_set_onid(mm, onid, 0);
-    mpegts_mux_set_tsid(mm, tsid, 0);
-    if (mm->mm_onid != onid || mm->mm_tsid != tsid)
-      return -1;
+    mpegts_mux_set_onid(mm, onid);
+    mpegts_mux_set_tsid(mm, tsid);
   } else {
     mpegts_network_t *mn = mm->mm_network;
     LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link)
index 45a009cf9e0b4ef4d87a4224a03080b672a678e7..e319b0ad5ee0de25c9df21e3b75dc7732975c8ff 100644 (file)
@@ -676,4 +676,66 @@ dvb_mux_conf_load ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m )
     return "Invalid FE type";
 }
 
+static void
+dvb_mux_conf_save_dvbt ( dvb_mux_conf_t *dmc, htsmsg_t *m )
+{
+  struct dvb_ofdm_parameters *ofdm = &dmc->dmc_fe_params.u.ofdm;
+  htsmsg_add_str(m, "bandwidth",
+                 dvb_bw2str(ofdm->bandwidth));
+  htsmsg_add_str(m, "constellation",
+                 dvb_qam2str(ofdm->constellation));
+  htsmsg_add_str(m, "transmission_mode",
+                 dvb_mode2str(ofdm->transmission_mode));
+  htsmsg_add_str(m, "guard_interval",
+                 dvb_guard2str(ofdm->guard_interval));
+  htsmsg_add_str(m, "hierarchy",
+                 dvb_hier2str(ofdm->hierarchy_information));
+  htsmsg_add_str(m, "fec_hi",
+                 dvb_fec2str(ofdm->code_rate_HP));
+  htsmsg_add_str(m, "fec_lo",
+                 dvb_fec2str(ofdm->code_rate_LP));
+}
+
+static void
+dvb_mux_conf_save_dvbc ( dvb_mux_conf_t *dmc, htsmsg_t *m )
+{
+  struct dvb_qam_parameters *qam  = &dmc->dmc_fe_params.u.qam;
+  htsmsg_add_u32(m, "symbol_rate",   qam->symbol_rate);
+  htsmsg_add_str(m, "constellation", dvb_qam2str(qam->modulation));
+  htsmsg_add_str(m, "fec",           dvb_fec2str(qam->fec_inner));
+}
+
+static void
+dvb_mux_conf_save_dvbs ( dvb_mux_conf_t *dmc, htsmsg_t *m )
+{
+  struct dvb_qpsk_parameters *qpsk  = &dmc->dmc_fe_params.u.qpsk;
+  htsmsg_add_u32(m, "symbol_rate",   qpsk->symbol_rate);
+  htsmsg_add_str(m, "fec",           dvb_fec2str(qpsk->fec_inner));
+  htsmsg_add_str(m, "polarisation",  dvb_pol2str(dmc->dmc_fe_polarisation));
+#if DVB_API_VERSION >= 5
+  htsmsg_add_str(m, "modulation",    dvb_qam2str(dmc->dmc_fe_modulation));
+  htsmsg_add_str(m, "rolloff",       dvb_rolloff2str(dmc->dmc_fe_rolloff));
+#endif
+}
+
+static void
+dvb_mux_conf_save_atsc ( dvb_mux_conf_t *dmc, htsmsg_t *m )
+{
+  htsmsg_add_str(m, "constellation",
+                 dvb_qam2str(dmc->dmc_fe_params.u.vsb.modulation));
+}
+
+void
+dvb_mux_conf_save ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m )
+{
+  htsmsg_add_u32(m, "frequency", dmc->dmc_fe_params.frequency);
+#if DVB_API_VERSION >= 5
+  htsmsg_add_str(m, "delsys", dvb_delsys2str(dmc->dmc_fe_delsys));
+#endif
+       if (type == FE_OFDM) dvb_mux_conf_save_dvbt(dmc, m);
+  else if (type == FE_QAM)  dvb_mux_conf_save_dvbc(dmc, m);
+  else if (type == FE_QPSK) dvb_mux_conf_save_dvbs(dmc, m);
+  else if (type == FE_ATSC) dvb_mux_conf_save_atsc(dmc, m);
+}
+
 #endif /* ENABLE_DVBAPI */
index 4181a1f311b5d075c385bd086bab439852fde1d8..b129530a96c7dc1edad702d05967bedab5fb7b69 100644 (file)
@@ -284,6 +284,8 @@ linuxdvb_frontend_monitor ( void *aux )
                      NULL, "pat", MT_QUICKREQ | MT_CRC, DVB_PAT_PID);
     mpegts_table_add(mm, DVB_SDT_BASE, DVB_SDT_MASK, dvb_sdt_callback,
                      NULL, "sdt", MT_QUICKREQ | MT_CRC, DVB_SDT_PID);
+    mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback,
+                     NULL, "nit", MT_QUICKREQ | MT_CRC, DVB_NIT_PID);
     mpegts_table_add(mm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback,
                      NULL, "bat", MT_CRC, DVB_BAT_PID);
   } else {
index 3347f46093d4c931ba7c1fe729c65fe81764128a..4dabee541fd39ac67c1dd069755028d6bbd94664 100644 (file)
@@ -91,17 +91,29 @@ const idclass_t linuxdvb_mux_atsc_class =
 static void
 linuxdvb_mux_config_save ( mpegts_mux_t *mm )
 {
+  linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
+  linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network;
+  htsmsg_t *c = htsmsg_create_map();
+  idnode_save(&mm->mm_id, c);
+  dvb_mux_conf_save(ln->ln_type, &lm->lm_tuning, c);
+  hts_settings_save(c, "input/linuxdvb/networks/%s/muxes/%s/config",
+                    idnode_uuid_as_str(&mm->mm_network->mn_id),
+                    idnode_uuid_as_str(&mm->mm_id));
+  htsmsg_destroy(c);
 }
 
 static void
 linuxdvb_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len )
 {
-  size_t c = 0;
-  const char *unit = "Hz";
   linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
-  c = snprintf(buf+c, len-c, "%d %s [%04X:%04X]",
-               lm->lm_tuning.dmc_fe_params.frequency,
-               unit, mm->mm_onid, mm->mm_tsid);
+  linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network;
+  snprintf(buf, len, "%d %s%s [onid:%04X, tsid:%04X]",
+           lm->lm_tuning.dmc_fe_params.frequency,
+           (ln->ln_type == FE_QPSK) ? "MHz " : "Hz",
+           (ln->ln_type == FE_QPSK) 
+             ? dvb_pol2str(lm->lm_tuning.dmc_fe_polarisation)
+             : "",
+           mm->mm_onid, mm->mm_tsid);
 }
 
 static void
@@ -110,15 +122,11 @@ linuxdvb_mux_create_instances ( mpegts_mux_t *mm )
   extern const idclass_t mpegts_mux_instance_class;
   mpegts_input_t *mi;
   mpegts_mux_instance_t *mmi;
-  tvhtrace("linuxdvb", "mm %p create instances", mm);
   LIST_FOREACH(mi, &mm->mm_network->mn_inputs, mi_network_link) {
-    tvhtrace("linuxdvb", "  checking mi %p", mi);
     LIST_FOREACH(mmi, &mi->mi_mux_instances, mmi_input_link)
       if (mmi->mmi_mux == mm) break;
-    if (!mmi) {
+    if (!mmi)
       mmi = mpegts_mux_instance_create(mpegts_mux_instance, NULL, mi, mm);
-      tvhtrace("linuxdvb", "    created mmi %p", mmi);
-    }
     // TODO: we might eventually want to keep history!
   }
 }
@@ -180,7 +188,6 @@ linuxdvb_mux_t *
 linuxdvb_mux_create1
   ( linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf )
 {
-  uint32_t u32;
   const char *str;
   htsmsg_t *c, *e;
   htsmsg_field_t *f;
@@ -198,7 +205,6 @@ linuxdvb_mux_create1
 
   lm = linuxdvb_mux_create0(ln, MPEGTS_ONID_NONE,
                             MPEGTS_TSID_NONE, &dmc, uuid);
-  if (!lm) printf("OH DEAR\n");
   if (!lm) return NULL;
   
   /* No config */
@@ -206,15 +212,7 @@ linuxdvb_mux_create1
     return lm;
 
   /* Config */
-  // TODO: this could go in mpegts_mux
-  if (!htsmsg_get_u32(conf, "enabled", &u32) && u32)
-    lm->mm_enabled = 1;
-  if (!htsmsg_get_u32(conf, "onid", &u32))
-    lm->mm_onid = u32;
-  if (!htsmsg_get_u32(conf, "tsid", &u32))
-    lm->mm_tsid = u32;
-  if ((str = htsmsg_get_str(conf, "default_authority")))
-    lm->mm_dvb_default_authority = strdup(str);
+  idnode_load(&lm->mm_id, conf);
   memcpy(&lm->lm_tuning, &dmc, sizeof(dmc));
 
   /* Services */
@@ -228,5 +226,7 @@ linuxdvb_mux_create1
     htsmsg_destroy(c);
   }
 
+  lm->mm_config_save((mpegts_mux_t*)lm);
+
   return lm;
 }
index 5ca94fdd375a1756f1b9cbb09dc30ceb614b2f03..cc9b7d5cd0be34334ea1cfc97c052d3aafbbd7b2 100644 (file)
 #include <fcntl.h>
 
 extern const idclass_t mpegts_network_class;
+
+static const char *
+ln_type_getstr ( void *ptr )
+{
+  return dvb_type2str(((linuxdvb_network_t*)ptr)->ln_type);
+}
+
+static void 
+ln_type_setstr ( void *ptr, const char *str )
+{ 
+  ((linuxdvb_network_t*)ptr)->ln_type = dvb_str2type(str);
+}
+
 const idclass_t linuxdvb_network_class =
 {
   .ic_super      = &mpegts_network_class,
   .ic_class      = "linuxdvb_network",
   .ic_caption    = "LinuxDVB Network",
   .ic_properties = (const property_t[]){
-#if 0
     { PROPDEF2("type", "Network Type",
                PT_STR, linuxdvb_network_t, ln_type, 1),
-      .get_str },
-#endif
+      .str_get = ln_type_getstr,
+      .str_set = ln_type_setstr },
     {}
   }
 };
 
+static void
+linuxdvb_network_config_save ( mpegts_network_t *mn )
+{
+  htsmsg_t *c = htsmsg_create_map();
+  idnode_save(&mn->mn_id, c);
+  hts_settings_save(c, "input/linuxdvb/networks/%s/config",
+                    idnode_uuid_as_str(&mn->mn_id));
+  htsmsg_destroy(c);
+}
+
 static mpegts_mux_t *
 linuxdvb_network_find_mux
   ( linuxdvb_network_t *ln, dvb_mux_conf_t *dmc )
 {
+#define LINUXDVB_FREQ_TOL 2000 // TODO: fix this!
   mpegts_mux_t *mm;
   LIST_FOREACH(mm, &ln->mn_muxes, mm_network_link) {
     linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
-    if (abs(lm->lm_tuning.dmc_fe_params.frequency - dmc->dmc_fe_params.frequency) > 2000) continue;
+    if (abs(lm->lm_tuning.dmc_fe_params.frequency
+            - dmc->dmc_fe_params.frequency) > LINUXDVB_FREQ_TOL) continue;
     if (lm->lm_tuning.dmc_fe_polarisation != dmc->dmc_fe_polarisation) continue;
     break;
   }
@@ -62,12 +86,15 @@ linuxdvb_network_find_mux
 
 static mpegts_mux_t *
 linuxdvb_network_create_mux
-  ( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *conf )
+  ( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *dmc )
 {
   linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network;
-  mm = linuxdvb_network_find_mux(ln, conf);
-  if (!mm)
-    mm = (mpegts_mux_t*)linuxdvb_mux_create0(ln, onid, tsid, conf, NULL);
+  mm = linuxdvb_network_find_mux(ln, dmc);
+  if (!mm) {
+    mm = (mpegts_mux_t*)linuxdvb_mux_create0(ln, onid, tsid, dmc, NULL);
+    if (mm)
+      mm->mm_config_save(mm);
+  }
   return mm;
 }
 
@@ -78,17 +105,10 @@ linuxdvb_network_create_service
   return NULL;
 }
 
-static void
-linuxdvb_network_config_save ( mpegts_network_t *mn )
-{
-}
-
 static linuxdvb_network_t *
 linuxdvb_network_create0
   ( const char *uuid, htsmsg_t *conf )
 {
-  uint32_t u32;
-  const char *str;
   linuxdvb_network_t *ln;
   htsmsg_t *c, *e;
   htsmsg_field_t *f;
@@ -107,12 +127,7 @@ linuxdvb_network_create0
     return ln;
 
   /* Load configuration */
-  if ((str = htsmsg_get_str(conf, "type")))
-    ln->ln_type = dvb_str2type(str);
-  if ((str = htsmsg_get_str(conf, "name")))
-    ln->mn_network_name = strdup(str);
-  if (!htsmsg_get_u32(conf, "nid", &u32))
-    ln->mn_nid          = u32;
+  idnode_load(&ln->mn_id, conf);
 
   /* Load muxes */
   if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes", uuid))) {
@@ -123,6 +138,8 @@ linuxdvb_network_create0
     }
   }
 
+  linuxdvb_network_config_save((mpegts_network_t*)ln);
+
   return ln;
 }
 
@@ -147,4 +164,5 @@ void linuxdvb_network_init ( void )
     (void)linuxdvb_network_create0(f->hmf_name, e);
   }
   htsmsg_destroy(c);
+  exit(1);
 }
index 9040b3f57f1c100753442b651a819589204f76b5..402a6f455e4c13b1b6ca0fae0db95ea8a7d17a0c 100644 (file)
@@ -52,42 +52,60 @@ const idclass_t mpegts_mux_class =
   .ic_class      = "mpegts_mux",
   .ic_caption    = "MPEGTS Multiplex",
   .ic_properties = (const property_t[]){
+    {  PROPDEF1("enabled", "Enabled",
+                PT_BOOL, mpegts_mux_t, mm_enabled) },
     {  PROPDEF1("onid", "Original Network ID",
-               PT_INT, mpegts_mux_t, mm_onid) },
+                PT_INT, mpegts_mux_t, mm_onid) },
     {  PROPDEF1("tsid", "Transport Stream ID",
-               PT_INT, mpegts_mux_t, mm_tsid) },
-
+                PT_INT, mpegts_mux_t, mm_tsid) },
+    {  PROPDEF2("crid_authority", "CRID Authority",
+                PT_STR, mpegts_mux_t, mm_crid_authority, 1) },
+    {}
   }
 };
 
+static void
+mpegts_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len )
+{
+  snprintf(buf, len, "Multiplex [onid:%04X tsid:%04X]",
+           mm->mm_onid, mm->mm_tsid);
+}
+
+static void
+mpegts_mux_config_save ( mpegts_mux_t *mm )
+{
+}
+
+static int
+mpegts_mux_is_enabled ( mpegts_mux_t *mm )
+{
+  return mm->mm_enabled;
+}
+
 int
-mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid, int force )
+mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid )
 {
   if (onid == mm->mm_onid)
     return 0;
-  if (!force && mm->mm_onid != MPEGTS_ONID_NONE)
-    return 0;
   mm->mm_onid = onid;
   return 1;
 }
 
 int
-mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force )
+mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid )
 {
   if (tsid == mm->mm_tsid)
     return 0;
-  if (!force && mm->mm_tsid != MPEGTS_TSID_NONE)
-    return 0;
   mm->mm_tsid = tsid;
   return 1;
 }
 
 int 
-mpegts_mux_set_default_authority ( mpegts_mux_t *mm, const char *defauth )
+mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth )
 {
-  if (defauth && !strcmp(defauth, mm->mm_dvb_default_authority ?: ""))
+  if (defauth && !strcmp(defauth, mm->mm_crid_authority ?: ""))
     return 0;
-  tvh_str_update(&mm->mm_dvb_default_authority, defauth);
+  tvh_str_update(&mm->mm_crid_authority, defauth);
   return 1;
 }
 
@@ -336,6 +354,11 @@ mpegts_mux_create0
   mm->mm_network             = mn;
   mpegts_mux_initial_scan_link(mm);
 
+  /* Debug/Config */
+  mm->mm_display_name        = mpegts_mux_display_name;
+  mm->mm_config_save         = mpegts_mux_config_save;
+  mm->mm_is_enabled          = mpegts_mux_is_enabled;
+
   /* Start/stop */
   mm->mm_start               = mpegts_mux_start;
   mm->mm_stop                = mpegts_mux_stop;
index 787019e01008b7a06cce320b3c0f4ce9d2c8c036..0aa90cd6ba21d3dd2d344cba6b5cc6da02446944 100644 (file)
@@ -25,13 +25,28 @@ const idclass_t mpegts_network_class =
   .ic_class      = "mpegts_network",
   .ic_caption    = "MPEGTS Network",
   .ic_properties = (const property_t[]){
+    { PROPDEF1("networkname", "Network Name",
+               PT_STR, mpegts_network_t, mn_network_name) },
+    { PROPDEF1("nid", "Network ID (limit scanning)",
+               PT_INT, mpegts_network_t, mn_nid) },
+    { PROPDEF1("autodiscovery", "Network Discovery",
+               PT_BOOL, mpegts_network_t, mn_autodiscovery) },
+    {}
   }
 };
 
+static void
+mpegts_network_display_name
+  ( mpegts_network_t *mn, char *buf, size_t len )
+{
+  strncpy(buf, mn->mn_network_name ?: "unknown", len);
+}
+
 static void
 mpegts_network_config_save
   ( mpegts_network_t *mn )
 {
+  // Nothing - leave to child classes
 }
 
 static mpegts_mux_t *
@@ -41,6 +56,13 @@ mpegts_network_create_mux
   return NULL;
 }
 
+static mpegts_service_t *
+mpegts_network_create_service
+ ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid )
+{
+  return NULL;
+}
+
 static void
 mpegts_network_initial_scan(void *aux)
 {
@@ -76,8 +98,10 @@ mpegts_network_create0
     const char *netname )
 {
   idnode_insert(&mn->mn_id, uuid, idc);
-  mn->mn_create_mux   = mpegts_network_create_mux;
-  mn->mn_config_save  = mpegts_network_config_save;
+  mn->mn_display_name   = mpegts_network_display_name;
+  mn->mn_config_save    = mpegts_network_config_save;
+  mn->mn_create_mux     = mpegts_network_create_mux;
+  mn->mn_create_service = mpegts_network_create_service;
   if (netname) mn->mn_network_name = strdup(netname);
   TAILQ_INIT(&mn->mn_initial_scan_pending_queue);
   TAILQ_INIT(&mn->mn_initial_scan_current_queue);
index 899662b5c48923574c75292d05dc5fc268c963a8..8050f80c728d74e7b72e13e34fe724059c9c64b8 100644 (file)
@@ -53,11 +53,7 @@ prop_write_values(void *obj, const property_t *pl, htsmsg_t *m)
       continue;
     const property_t *p = prop_find(pl, f->hmf_name);
     if(p == NULL) {
-      fprintf(stderr, "Property %s unmappable\n", f->hmf_name);
-      continue;
-    }
-    if (p->rdonly) {
-      tvhlog(LOG_WARNING, "prop", "field %s is read-only", p->id);
+      //fprintf(stderr, "Property %s unmappable\n", f->hmf_name);
       continue;
     }