From eec7d0ebcf6a4d77d4ba13db0a023d76bfc0953b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Fri, 15 Mar 2013 12:45:22 +0100 Subject: [PATCH] Split service out in a superclass and a per-hw type class --- src/dvb/dvb.h | 2 +- src/dvb/dvb_adapter.c | 21 ---------- src/dvb/dvb_multiplex.c | 2 +- src/dvb/dvb_network.c | 20 ++++------ src/dvb/dvb_service.c | 40 +++++++++++++++++-- src/idnode.c | 26 +++++++++++-- src/idnode.h | 5 ++- src/iptv_input.c | 26 +++++-------- src/prop.c | 86 +++++++++++++++++++++++++++++++---------- src/prop.h | 13 +++++-- src/rawtsinput.c | 7 +++- src/service.c | 58 ++++++++++++++++++--------- src/service.h | 6 +-- src/serviceprobe.c | 2 +- src/tvheadend.h | 7 ++++ src/v4l.c | 6 ++- src/webui/extjs_dvb.c | 22 +++++------ 17 files changed, 225 insertions(+), 124 deletions(-) diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index cfb42e1a..db72f1cd 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -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; diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index 03cc15a2..eb6169bb 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -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); diff --git a/src/dvb/dvb_multiplex.c b/src/dvb/dvb_multiplex.c index 3a3129bc..5069549f 100644 --- a/src/dvb/dvb_multiplex.c +++ b/src/dvb/dvb_multiplex.c @@ -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) diff --git a/src/dvb/dvb_network.c b/src/dvb/dvb_network.c index 82feba0c..3dc45902 100644 --- a/src/dvb/dvb_network.c +++ b/src/dvb/dvb_network.c @@ -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 - /** diff --git a/src/dvb/dvb_service.c b/src/dvb/dvb_service.c index 7fbb2a34..748b445c 100644 --- a/src/dvb/dvb_service.c +++ b/src/dvb/dvb_service.c @@ -44,7 +44,20 @@ #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; + } +} /** diff --git a/src/idnode.c b/src/idnode.c index e907b103..ec3211ea 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -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; diff --git a/src/idnode.h b/src/idnode.h index 3735801a..a5a0901b 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -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); diff --git a/src/iptv_input.c b/src/iptv_input.c index 57c994e9..9851c202 100644 --- a/src/iptv_input.c +++ b/src/iptv_input.c @@ -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; diff --git a/src/prop.c b/src/prop.c index 7050e8cb..d148b43a 100644 --- a/src/prop.c +++ b/src/prop.c @@ -1,47 +1,91 @@ +#include +#include + +#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); diff --git a/src/prop.h b/src/prop.h index 148d67ed..4bfd89b2 100644 --- a/src/prop.h +++ b/src/prop.h @@ -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); diff --git a/src/rawtsinput.c b/src/rawtsinput.c index ee568302..ffc89e8d 100644 --- a/src/rawtsinput.c +++ b/src/rawtsinput.c @@ -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; diff --git a/src/service.c b/src/service.c index 89608b82..4e12c045 100644 --- a/src/service.c +++ b/src/service.c @@ -50,12 +50,23 @@ #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); -} diff --git a/src/service.h b/src/service.h index bfaf1346..be321aa3 100644 --- a/src/service.h +++ b/src/service.h @@ -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); diff --git a/src/serviceprobe.c b/src/serviceprobe.c index 2bdb5048..60909129 100644 --- a/src/serviceprobe.c +++ b/src/serviceprobe.c @@ -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...", diff --git a/src/tvheadend.h b/src/tvheadend.h index 6fddae3b..e6a4f6cc 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -27,6 +27,7 @@ #include #include #include +#include #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); diff --git a/src/v4l.c b/src/v4l.c index 1e76ba1a..2822fc63 100644 --- 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; diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index 9f48ad33..e3a3bd18 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -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);