]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Split service out in a superclass and a per-hw type class
authorAndreas Öman <andreas@lonelycoder.com>
Fri, 15 Mar 2013 11:45:22 +0000 (12:45 +0100)
committerAndreas Öman <andreas@lonelycoder.com>
Fri, 15 Mar 2013 11:45:22 +0000 (12:45 +0100)
17 files changed:
src/dvb/dvb.h
src/dvb/dvb_adapter.c
src/dvb/dvb_multiplex.c
src/dvb/dvb_network.c
src/dvb/dvb_service.c
src/idnode.c
src/idnode.h
src/iptv_input.c
src/prop.c
src/prop.h
src/rawtsinput.c
src/service.c
src/service.h
src/serviceprobe.c
src/tvheadend.h
src/v4l.c
src/webui/extjs_dvb.c

index cfb42e1a0d357cdd618ffed65a02f54f6d228157..db72f1cdc3f562cfe6bf98d88f5cc7e6d41abfe6 100644 (file)
@@ -108,6 +108,7 @@ typedef struct dvb_network {
   uint32_t dn_disable_pmt_monitor;
   uint32_t dn_autodiscovery;
   uint32_t dn_nitoid;
+  uint32_t dn_skip_checksubscr;
 
   struct th_dvb_adapter_list dn_adapters;
 
@@ -248,7 +249,6 @@ typedef struct th_dvb_adapter {
   char *tda_identifier;
   uint32_t tda_idleclose;
   uint32_t tda_skip_initialscan;
-  uint32_t tda_skip_checksubscr;
   uint32_t tda_qmon;
   uint32_t tda_poweroff;
   uint32_t tda_sidtochan;
index 03cc15a2f31e3bb528a70cfadc16ef435b0a19c6..eb6169bbca3fc659ac477fe3739b583fe0d04af2 100644 (file)
@@ -77,7 +77,6 @@ tda_save(th_dvb_adapter_t *tda)
   htsmsg_add_str(m, "type", dvb_adaptertype_to_str(tda->tda_fe_type));
   htsmsg_add_str(m, "displayname", tda->tda_displayname);
   htsmsg_add_u32(m, "idleclose", tda->tda_idleclose);
-  htsmsg_add_u32(m, "skip_checksubscr", tda->tda_skip_checksubscr);
   htsmsg_add_u32(m, "sidtochan", tda->tda_sidtochan);
   htsmsg_add_u32(m, "qmon", tda->tda_qmon);
   htsmsg_add_u32(m, "poweroff", tda->tda_poweroff);
@@ -151,25 +150,6 @@ dvb_adapter_set_idleclose(th_dvb_adapter_t *tda, int on)
   tda_save(tda);
 }
 
-
-/**
- *
- */
-void
-dvb_adapter_set_skip_checksubscr(th_dvb_adapter_t *tda, int on)
-{
-  if(tda->tda_skip_checksubscr == on)
-    return;
-
-  lock_assert(&global_lock);
-
-  tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" skip service availability check when mapping set to: %s",
-   tda->tda_displayname, on ? "On" : "Off");
-
-  tda->tda_skip_checksubscr = on;
-  tda_save(tda);
-}
-
 /**
  *
  */
@@ -609,7 +589,6 @@ dvb_adapter_init(uint32_t adapter_mask, const char *rawfile)
       tda->tda_displayname = strdup(name);
 
       htsmsg_get_u32(c, "idleclose", &tda->tda_idleclose);
-      htsmsg_get_u32(c, "skip_checksubscr", &tda->tda_skip_checksubscr);
       htsmsg_get_u32(c, "sidtochan", &tda->tda_sidtochan);
       htsmsg_get_u32(c, "qmon", &tda->tda_qmon);
       htsmsg_get_u32(c, "poweroff", &tda->tda_poweroff);
index 3a3129bcc8c9e255e3087bbe66e159772699487d..5069549fa4d44d0c4721c05cfcd60e0b4e140de0 100644 (file)
@@ -65,7 +65,7 @@ static const idclass_t dvb_mux_class = {
   .ic_class = "dvbmux",
   .ic_get_title = dvb_mux_get_title,
   .ic_get_childs = dvb_mux_get_childs,
-  .ic_properties = {
+  .ic_properties = (const property_t[]){
     {
       "enabled", "Enabled", PT_BOOL,
       offsetof(dvb_mux_t, dm_enabled)
index 82feba0ce54b39d9d3412a9b24a99f07d933dbe7..3dc45902ff48e02a9a40c6078f0aa4a4c9eee8bc 100644 (file)
@@ -32,7 +32,7 @@ static idnode_t **dvb_network_get_childs(struct idnode *self);
 static const idclass_t dvb_network_class = {
   .ic_class = "dvbnetwork",
   .ic_get_childs = dvb_network_get_childs,
-  .ic_properties = {
+  .ic_properties = (const property_t[]){
     {
       "autodiscovery", "Auto discovery", PT_BOOL,
       offsetof(dvb_network_t, dn_autodiscovery)
@@ -42,6 +42,9 @@ static const idclass_t dvb_network_class = {
     }, {
       "disable_pmt_monitor", "Disable PMT monitor", PT_BOOL,
       offsetof(dvb_network_t, dn_disable_pmt_monitor)
+    }, {
+      "disable_pmt_monitor", "Disable PMT monitor", PT_BOOL,
+      offsetof(dvb_network_t, dn_disable_pmt_monitor)
     }, {
     }},
 };
@@ -122,16 +125,12 @@ dvb_network_load(htsmsg_t *m, const char *uuid)
   if(dn == NULL)
     return;
 
-  htsmsg_get_u32(m, "autodiscovery",       &dn->dn_autodiscovery);
-  htsmsg_get_u32(m, "nitoid",              &dn->dn_nitoid);
-  htsmsg_get_u32(m, "disable_pmt_monitor", &dn->dn_disable_pmt_monitor);
-
+  prop_write_values(dn, dvb_network_class.ic_properties, m);
   dvb_mux_load(dn);
-
   dvb_network_schedule_initial_scan(dn);
 }
 
-#if 1
+
 /**
  *
  */
@@ -142,17 +141,12 @@ dvb_network_save(dvb_network_t *dn)
 
   lock_assert(&global_lock);
 
-  htsmsg_add_u32(m, "fetype",              dn->dn_fe_type);
-  htsmsg_add_u32(m, "autodiscovery",       dn->dn_autodiscovery);
-  htsmsg_add_u32(m, "nitoid",              dn->dn_nitoid);
-  htsmsg_add_u32(m, "disable_pmt_monitor", dn->dn_disable_pmt_monitor);
+  prop_read_values(dn, dvb_network_class.ic_properties, m);
 
   hts_settings_save(m, "dvb/networks/%s/config",
                     idnode_uuid_as_str(&dn->dn_id));
   htsmsg_destroy(m);
 }
-#endif
-
 
 
 /**
index 7fbb2a34c9cc65cbac977b62bc507be3bd5b585a..748b445c56f71bd72668a01ccc7432be332c5fa6 100644 (file)
 #include "dvb_support.h"
 #include "notify.h"
 
-static htsmsg_t *dvb_service_serialize(service_t *s);
+static const char *dvb_service_get_title(struct idnode *self);
+
+const idclass_t dvb_service_class = {
+  .ic_super = &service_class,
+  .ic_class = "dvbservice",
+  .ic_get_title = dvb_service_get_title,
+  //  .ic_get_childs = dvb_service_get_childs,
+  .ic_properties = (const property_t[]){
+    {
+      "dvb_eit_enable", "Use EPG", PT_BOOL,
+      offsetof(service_t, s_dvb_eit_enable)
+    }, {
+    }}
+};
 
 
 /**
@@ -385,7 +398,8 @@ dvb_service_find2(dvb_mux_t *dm, uint16_t sid, int pmt_pid,
   tvhlog(LOG_DEBUG, "dvb", "Add service \"0x%x\" on \"%s\"", sid,
          dvb_mux_nicename(dm));
 
-  t = service_create(uuid, S_MPEG_TS);
+  t = service_create(uuid, S_MPEG_TS, &dvb_service_class);
+
   if (save) *save = 1;
 
   t->s_dvb_service_id = sid;
@@ -397,7 +411,6 @@ dvb_service_find2(dvb_mux_t *dm, uint16_t sid, int pmt_pid,
   t->s_config_save   = dvb_service_save;
   t->s_setsourceinfo = dvb_service_setsourceinfo;
   t->s_grace_period  = dvb_grace_period;
-  t->s_serialize     = dvb_service_serialize;
   t->s_enlist        = dvb_service_enlist;
 
   t->s_dvb_mux = dm;
@@ -409,7 +422,7 @@ dvb_service_find2(dvb_mux_t *dm, uint16_t sid, int pmt_pid,
   return t;
 }
 
-
+#if 0
 /**
  *
  */
@@ -454,6 +467,25 @@ dvb_service_serialize(service_t *s)
 
   return m;
 }
+#endif
+
+
+/**
+ *
+ */
+static const char *
+dvb_service_get_title(struct idnode *self)
+{
+  service_t *s = (service_t *)self;
+  static char buf[100];
+
+  if(s->s_svcname) {
+    return s->s_svcname;
+  } else {
+    snprintf(buf, sizeof(buf), "Service-0x%04x", s->s_dvb_service_id);
+    return buf;
+  }
+}
 
 
 /**
index e907b1036c9022dfbc00be66ee25abcdc7b9e673..ec3211eabb65a57b1e7075bacf9f3c4389900040 100644 (file)
@@ -136,14 +136,22 @@ idnode_uuid_as_str(const idnode_t *in)
 /**
  *
  */
-idnode_t *
-idnode_find(const char *uuid)
+void *
+idnode_find(const char *uuid, const idclass_t *idc)
 {
   idnode_t skel, *r;
 
   if(hex2bin(skel.in_uuid, 16, uuid))
     return NULL;
   r = RB_FIND(&idnodes, &skel, in_link, in_cmp);
+  if(r != NULL && idc != NULL) {
+    const idclass_t *c = r->in_class;
+    for(;c != NULL; c = c->ic_super) {
+      if(idc == c)
+        return r;
+    }
+    return NULL;
+  }
   return r;
 }
 
@@ -171,13 +179,23 @@ idnode_serialize(struct idnode *self)
   } else {
     m = htsmsg_create_map();
 
+    htsmsg_t *p  = htsmsg_create_map();
+    htsmsg_t *pn = htsmsg_create_map();
+
     if(c->ic_get_title != NULL) {
       htsmsg_add_str(m, "text", c->ic_get_title(self));
     } else {
       htsmsg_add_str(m, "text", idnode_uuid_as_str(self));
     }
-    htsmsg_add_msg(m, "properties", prop_get_values(self, c->ic_properties));
-    htsmsg_add_msg(m, "propertynames", prop_get_names(c->ic_properties));
+
+    for(;c != NULL; c = c->ic_super) {
+      prop_read_values(self, c->ic_properties, p);
+      prop_read_names(c->ic_properties, pn);
+    }
+
+    htsmsg_add_msg(m, "properties", p);
+    htsmsg_add_msg(m, "propertynames", pn);
+
     htsmsg_add_str(m, "id", idnode_uuid_as_str(self));
   }
   return m;
index 3735801a11620e61e24374323c5db36f2a0c3dec..a5a0901be08fc7cc6192db0cd534d7f9e4a419b6 100644 (file)
@@ -7,11 +7,12 @@ struct htsmsg;
 struct idnode;
 
 typedef struct idclass {
+  const struct idclass *ic_super;
   const char *ic_class;
   struct htsmsg *(*ic_serialize)(struct idnode *self);
   struct idnode **(*ic_get_childs)(struct idnode *self);
   const char *(*ic_get_title)(struct idnode *self);
-  const property_t ic_properties[];
+  const property_t *ic_properties;
 } idclass_t;
 
 
@@ -27,7 +28,7 @@ int idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class);
 
 const char *idnode_uuid_as_str(const idnode_t *in);
 
-idnode_t *idnode_find(const char *uuid);
+void *idnode_find(const char *uuid, const idclass_t *class);
 
 void idnode_unlink(idnode_t *in);
 
index 57c994e970dec5468245ae5f81d966c43c79538e..9851c2029cbffc138c5070e6ea683b22f59c3548 100644 (file)
@@ -48,6 +48,11 @@ static pthread_mutex_t iptv_recvmutex;
 struct service_list iptv_all_services; /* All IPTV services */
 static struct service_list iptv_active_services; /* Currently enabled */
 
+const idclass_t iptv_class = {
+  .ic_super = &service_class,
+  .ic_class = "iptv",
+};
+
 /**
  * PAT parser. We only parse a single program. CRC has already been verified
  */
@@ -496,32 +501,19 @@ iptv_service_dtor(service_t *t)
 service_t *
 iptv_service_find(const char *id, int create)
 {
-  static int tally;
   service_t *t;
-  char buf[20];
 
   if(id != NULL) {
 
-    if(strncmp(id, "iptv_", 5))
-      return NULL;
-
-    LIST_FOREACH(t, &iptv_all_services, s_group_link)
-      if(!strcmp(t->s_nicename, id)) // XXX(dvbreorg)
-       return t;
+    t = idnode_find(id, &iptv_class);
+    if(t != NULL)
+      return t;
   }
 
   if(create == 0)
     return NULL;
-  
-  if(id == NULL) {
-    tally++;
-    snprintf(buf, sizeof(buf), "iptv_%d", tally);
-    id = buf;
-  } else {
-    tally = MAX(atoi(id + 5), tally);
-  }
 
-  t = service_create(id, S_MPEG_TS);
+  t = service_create(id, S_MPEG_TS, &iptv_class);
 
   t->s_servicetype   = ST_SDTV;
   t->s_start_feed    = iptv_service_start;
index 7050e8cb88009c883ae558a9cae1d68ef0f37c5d..d148b43abfbcb981e7379fa0db0035a88affb8e0 100644 (file)
@@ -1,47 +1,91 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "tvheadend.h"
 #include "prop.h"
 
-#if 0
+
+
+
+static const property_t *
+prop_find(const property_t *p, const char *id)
+{
+  int i;
+  for(;p[i].id; i++)
+    if(!strcmp(id, p[i].id))
+      return p;
+  return NULL;
+}
+
+
+
+#define TO_FROM(x, y) ((x) << 16 | (y))
+
 /**
  *
  */
 void
-prop_write_values(void *ptr, const property_t p[], htsmsg_t *m)
+prop_write_values(void *obj, const property_t *pl, htsmsg_t *m)
 {
-  int i = 0;
-  for(;p[i].id; i++) {
-    switch(p[i].type) {
-    case PT_BOOL:
-      htsmsg_add_bool(m, p[i].id, *(int *)(ptr + p[i].off));
+  htsmsg_field_t *f;
+  HTSMSG_FOREACH(f, m) {
+    if(f->hmf_name == NULL)
+      continue;
+    const property_t *p = prop_find(pl, f->hmf_name);
+    if(p == NULL) {
+      fprintf(stderr, "Property %s unmappable\n", f->hmf_name);
+      continue;
+    }
+
+    void *val = obj + p->off;
+    switch(TO_FROM(p->type, f->hmf_type)) {
+    case TO_FROM(PT_BOOL, HMF_BOOL):
+      *(int *)val = f->hmf_bool;
       break;
-    case PT_INT:
-      htsmsg_add_s32(m, p[i].id, *(int *)(ptr + p[i].off));
+    case TO_FROM(PT_BOOL, HMF_S64):
+      *(int *)val = !!f->hmf_s64;
       break;
-    case PT_STR:
-      htsmsg_add_str(m, p[i].id, (const char *)(ptr + p[i].off));
+    case TO_FROM(PT_INT, HMF_S64):
+      *(int *)val = f->hmf_s64;
+      break;
+    case TO_FROM(PT_STR, HMF_STR):
+      if(p->str_set != NULL)
+        p->str_set(obj, f->hmf_str);
+      else
+        mystrset(val, f->hmf_str);
       break;
     }
   }
 }
-#endif
+
 
 
 /**
  *
  */
 void
-prop_read_values(void *ptr, const property_t p[], htsmsg_t *m)
+prop_read_values(void *obj, const property_t *p, htsmsg_t *m)
 {
+  const char *s;
+  if(p == NULL)
+    return;
   int i = 0;
   for(;p[i].id; i++) {
+    void *val = obj + p[i].off;
     switch(p[i].type) {
     case PT_BOOL:
-      htsmsg_add_bool(m, p[i].id, *(int *)(ptr + p[i].off));
+      htsmsg_add_bool(m, p[i].id, *(int *)val);
       break;
     case PT_INT:
-      htsmsg_add_s32(m, p[i].id, *(int *)(ptr + p[i].off));
+      htsmsg_add_s32(m, p[i].id, *(int *)val);
       break;
     case PT_STR:
-      htsmsg_add_str(m, p[i].id, (const char *)(ptr + p[i].off));
+      if(p->str_get != NULL)
+        s = p->str_get(obj);
+      else
+        s = *(const char **)val;
+      if(s != NULL)
+        htsmsg_add_str(m, p[i].id, s);
       break;
     }
   }
@@ -52,7 +96,7 @@ prop_read_values(void *ptr, const property_t p[], htsmsg_t *m)
  *
  */
 htsmsg_t *
-prop_get_values(void *ptr, const property_t p[])
+prop_get_values(void *ptr, const property_t *p)
 {
   htsmsg_t *m = htsmsg_create_map();
   prop_read_values(ptr, p, m);
@@ -64,10 +108,12 @@ prop_get_values(void *ptr, const property_t p[])
  *
  */
 void
-prop_read_names(const property_t p[], htsmsg_t *m)
+prop_read_names(const property_t *p, htsmsg_t *m)
 {
+  if(p == NULL)
+    return;
   int i = 0;
-  for(;p[i].name; i++)
+  for(;p[i].id; i++)
     htsmsg_add_str(m, p[i].id, p[i].name);
 }
 
@@ -76,7 +122,7 @@ prop_read_names(const property_t p[], htsmsg_t *m)
  *
  */
 htsmsg_t *
-prop_get_names(const property_t p[])
+prop_get_names(const property_t *p)
 {
   htsmsg_t *m = htsmsg_create_map();
   prop_read_names(p, m);
index 148d67ed27018a54235f931978bf95aa6e3230b9..4bfd89b28fcca7b8ddd01c490d28599ab983bdda 100644 (file)
@@ -14,11 +14,16 @@ typedef struct property {
   const char *name;
   prop_type_t type;
   size_t off;
+
+  const char *(*str_get)(void *ptr);
+  void (*str_set)(void *ptr, const char *str);
+
 } property_t;
 
 
 
-void prop_read_values(void *ptr, const property_t p[], htsmsg_t *m);
-htsmsg_t *prop_get_values(void *ptr, const property_t p[]);
-void prop_read_names(const property_t p[], htsmsg_t *m);
-htsmsg_t *prop_get_names(const property_t p[]);
+void prop_read_values(void *ptr, const property_t *p, htsmsg_t *m);
+htsmsg_t *prop_get_values(void *ptr, const property_t *p);
+void prop_read_names(const property_t *p, htsmsg_t *m);
+htsmsg_t *prop_get_names(const property_t *p);
+void prop_write_values(void *ptr, const property_t *pl, htsmsg_t *m);
index ee5683028822d48efb1db146a08c37f3d20a2797..ffc89e8d5775856def8ebe6cbbfce58e6c0c5cf1 100644 (file)
@@ -48,6 +48,11 @@ typedef struct rawts {
 } rawts_t;
 
 
+const idclass_t rawts_class = {
+  .ic_super = &service_class,
+  .ic_class = "rawts",
+};
+
 /**
  *
  */
@@ -112,7 +117,7 @@ rawts_service_add(rawts_t *rt, uint16_t sid, int pmt_pid)
   
   snprintf(tmp, sizeof(tmp), "%s_%04x", rt->rt_identifier, sid);
 
-  t = service_create(tmp, S_MPEG_TS);
+  t = service_create(NULL, S_MPEG_TS, &rawts_class);
   t->s_flags |= S_DEBUG;
 
   t->s_dvb_service_id = sid;
index 89608b82d10392e045e7bd77b93661c0778ca2bf..4e12c0450a99b73993f70b8dcbcf799d947b4212 100644 (file)
 #include "lang_codes.h"
 
 static void service_data_timeout(void *aux);
+static const char *service_channel_get(void *obj);
+static void service_channel_set(void *obj, const char *str);
 
-static htsmsg_t *service_serialize(struct idnode *self);
 
-static const idclass_t service_class = {
+const idclass_t service_class = {
   .ic_class = "service",
-  .ic_serialize = service_serialize,
+  .ic_properties = (const property_t[]){
+    {
+      "channel", "Channel", PT_STR,
+
+      .str_get = service_channel_get,
+      .str_set = service_channel_set,
+    }, {
+      "enabled", "Enabled", PT_BOOL,
+      offsetof(service_t, s_enabled)
+    }, {
+    }}
 };
 
 /**
@@ -70,7 +81,7 @@ stream_init(elementary_stream_t *st)
   st->es_curdts = PTS_UNSET;
   st->es_curpts = PTS_UNSET;
   st->es_prevdts = PTS_UNSET;
-  
+
   st->es_pcr_real_last = PTS_UNSET;
   st->es_pcr_last      = PTS_UNSET;
   st->es_pcr_drift     = 0;
@@ -466,7 +477,7 @@ service_destroy(service_t *t)
  * Create and initialize a new service struct
  */
 service_t *
-service_create(const char *uuid, int source_type)
+service_create(const char *uuid, int source_type, const idclass_t *idc)
 {
   service_t *t = calloc(1, sizeof(service_t));
 
@@ -486,7 +497,7 @@ service_create(const char *uuid, int source_type)
 
   streaming_pad_init(&t->s_streaming_pad);
 
-  idnode_insert(&t->s_id, uuid, &service_class);
+  idnode_insert(&t->s_id, uuid, idc);
 
   return t;
 }
@@ -497,8 +508,7 @@ service_create(const char *uuid, int source_type)
 service_t *
 service_find_by_identifier(const char *identifier)
 {
-  idnode_t *id = idnode_find(identifier);
-  return id->in_class == &service_class ? (service_t *)id : NULL;
+  return idnode_find(identifier, &service_class);
 }
 
 
@@ -648,6 +658,27 @@ service_map_channel(service_t *t, channel_t *ch, int save)
     t->s_config_save(t);
 }
 
+
+/**
+ *
+ */
+static const char *service_channel_get(void *obj)
+{
+  service_t *s = obj;
+  return s->s_ch ? s->s_ch->ch_name : NULL;
+}
+
+
+/**
+ *
+ */
+static void
+service_channel_set(void *obj, const char *str)
+{
+  service_map_channel(obj, str ? channel_find_by_name(str, 1, 0) : NULL, 1);
+}
+
+
 /**
  *
  */
@@ -1187,14 +1218,3 @@ htsmsg_t *servicetype_list ( void )
   }
   return ret;
 }
-
-
-/**
- *
- */
-static htsmsg_t *
-service_serialize(struct idnode *self)
-{
-  service_t *s = (service_t *)self;
-  return s->s_serialize(s);
-}
index bfaf1346d8d5c8f4d019b78c51ab3952b8fd519a..be321aa3263c120520299f7a8f6aeb61efc4798d 100644 (file)
@@ -25,6 +25,8 @@
 #include "idnode.h"
 
 
+extern const idclass_t service_class;
+
 /**
  * Descrambler superclass
  *
@@ -315,8 +317,6 @@ typedef struct service {
 
   void (*s_dtor)(struct service *t);
 
-  htsmsg_t *(*s_serialize)(struct service *s);
-
   /*
    * Per source type structs
    */
@@ -551,7 +551,7 @@ void service_init(void);
 
 int service_start(service_t *t, int instance);
 
-service_t *service_create(const char *uuid, int source_type);
+service_t *service_create(const char *uuid, int source_type, const idclass_t *idc);
 
 void service_unref(service_t *t);
 
index 2bdb504874eb0b091bc93876348bbecb85f678af..609091298c47844ef240773323b7c36d34e74b02 100644 (file)
@@ -109,7 +109,7 @@ serviceprobe_thread(void *aux)
     }
 
     // XXX(dvbreorg)
-    checksubscr = 1; // !t->s_dvb_mux->tdmi_adapter->tda_skip_checksubscr;
+    checksubscr = !t->s_dvb_mux->dm_dn->dn_skip_checksubscr;
 
     if (checksubscr) {
       tvhlog(LOG_INFO, "serviceprobe", "%20s: checking...",
index 6fddae3bb6e42237dc8c402acdbe8afff8369603..e6a4f6cca0b68023489b8a985270bd4d64a31436 100644 (file)
@@ -27,6 +27,7 @@
 #include <netinet/in.h>
 #include <sys/time.h>
 #include <libgen.h>
+#include <string.h>
 
 #include "queue.h"
 #include "avg.h"
@@ -441,6 +442,12 @@ static inline const char *tvh_strbegins(const char *s1, const char *s2)
   return s1;
 }
 
+static inline void mystrset(char **p, const char *s)
+{
+  free(*p);
+  *p = s ? strdup(s) : NULL;
+}
+
 int tvh_open(const char *pathname, int flags, mode_t mode);
 
 int tvh_socket(int domain, int type, int protocol);
index 1e76ba1a8f59caa64c7500f6ac46323d2890e006..2822fc63d59cb644f4c99310a155fb834ef52aca 100644 (file)
--- a/src/v4l.c
+++ b/src/v4l.c
@@ -45,6 +45,10 @@ struct v4l_adapter_queue v4l_adapters;
 
 static void v4l_adapter_notify(v4l_adapter_t *va);
 
+const idclass_t v4l_class = {
+  .ic_super = &service_class,
+  .ic_class = "v4l",
+};
 
 /**
  *
@@ -354,7 +358,7 @@ v4l_service_find(v4l_adapter_t *va, const char *id, int create)
     va->va_tally = MAX(atoi(id + vaidlen + 1), va->va_tally);
   }
 
-  t = service_create(id, 0);
+  t = service_create(id, 0, &v4l_class);
 
   t->s_start_feed    = v4l_service_start;
   t->s_refresh_feed  = v4l_service_refresh;
index 9f48ad331e68367ee15a229be73b1dea663ac629..e3a3bd18ffb76ca08d10fa2dcb8084a30fcc6c4e 100644 (file)
@@ -151,7 +151,6 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque)
     htsmsg_add_str(r, "name", tda->tda_displayname);
     htsmsg_add_u32(r, "skip_initialscan", tda->tda_skip_initialscan);
     htsmsg_add_u32(r, "idleclose", tda->tda_idleclose);
-    htsmsg_add_u32(r, "skip_checksubscr", tda->tda_skip_checksubscr);
     htsmsg_add_u32(r, "qmon", tda->tda_qmon);
     htsmsg_add_u32(r, "poweroff", tda->tda_poweroff);
     htsmsg_add_u32(r, "sidtochan", tda->tda_sidtochan);
@@ -177,9 +176,6 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque)
     s = http_arg_get(&hc->hc_req_args, "idleclose");
     dvb_adapter_set_idleclose(tda, !!s);
 
-    s = http_arg_get(&hc->hc_req_args, "skip_checksubscr");
-    dvb_adapter_set_skip_checksubscr(tda, !!s);
-
     s = http_arg_get(&hc->hc_req_args, "qmon");
     dvb_adapter_set_qmon(tda, !!s);
 
@@ -708,17 +704,19 @@ extjs_dvbnetworks(http_connection_t *hc, const char *remain, void *opaque)
   if(!strcmp(s, "root")) {
     v = dvb_network_root();
   } else {
-    idnode_t *n = idnode_find(s);
-    v = n != NULL && n->in_class->ic_get_childs != NULL ? 
+    idnode_t *n = idnode_find(s, NULL);
+    v = n != NULL && n->in_class->ic_get_childs != NULL ?
       n->in_class->ic_get_childs(n) : NULL;
   }
 
-  int i;
-  for(i = 0; v[i] != NULL; i++) {
-    htsmsg_t *m = idnode_serialize(v[i]);
-    if(v[i]->in_class->ic_get_childs == NULL)
-      htsmsg_add_u32(m, "leaf", 1);
-    htsmsg_add_msg(out, NULL, m);
+  if(v != NULL) {
+    int i;
+    for(i = 0; v[i] != NULL; i++) {
+      htsmsg_t *m = idnode_serialize(v[i]);
+      if(v[i]->in_class->ic_get_childs == NULL)
+        htsmsg_add_u32(m, "leaf", 1);
+      htsmsg_add_msg(out, NULL, m);
+    }
   }
 
   pthread_mutex_unlock(&global_lock);