diff --git a/Makefile b/Makefile index 37145763..f073c5d5 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,7 @@ endif # SRCS = src/main.c \ src/idnode.c \ + src/prop.c \ src/utils.c \ src/wrappers.c \ src/version.c \ diff --git a/src/dvb/dvb_multiplex.c b/src/dvb/dvb_multiplex.c index b7f11589..3a3129bc 100644 --- a/src/dvb/dvb_multiplex.c +++ b/src/dvb/dvb_multiplex.c @@ -58,13 +58,18 @@ static struct strtab muxfestatustab[] = { -static htsmsg_t *dvb_mux_serialize(struct idnode *self, int full); static idnode_t **dvb_mux_get_childs(struct idnode *self); +static const char *dvb_mux_get_title(struct idnode *self); static const idclass_t dvb_mux_class = { .ic_class = "dvbmux", - .ic_serialize = dvb_mux_serialize, + .ic_get_title = dvb_mux_get_title, .ic_get_childs = dvb_mux_get_childs, + .ic_properties = { + { + "enabled", "Enabled", PT_BOOL, + offsetof(dvb_mux_t, dm_enabled) + }, {}} }; @@ -1244,14 +1249,10 @@ dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi, /** * */ -static htsmsg_t * -dvb_mux_serialize(struct idnode *self, int full) +static const char * +dvb_mux_get_title(struct idnode *self) { - dvb_mux_t *dm = (dvb_mux_t *)self; - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "id", idnode_uuid_as_str(&dm->dm_id)); - htsmsg_add_str(m, "text", dvb_mux_nicename(dm)); - return m; + return dvb_mux_nicename((dvb_mux_t *)self); } /** diff --git a/src/dvb/dvb_network.c b/src/dvb/dvb_network.c index c0818446..82feba0c 100644 --- a/src/dvb/dvb_network.c +++ b/src/dvb/dvb_network.c @@ -27,13 +27,23 @@ struct dvb_network_list dvb_networks; -static htsmsg_t *dvb_network_serialize(struct idnode *self, int full); static idnode_t **dvb_network_get_childs(struct idnode *self); static const idclass_t dvb_network_class = { .ic_class = "dvbnetwork", - .ic_serialize = dvb_network_serialize, .ic_get_childs = dvb_network_get_childs, + .ic_properties = { + { + "autodiscovery", "Auto discovery", PT_BOOL, + offsetof(dvb_network_t, dn_autodiscovery) + }, { + "nitoid", "NIT OID", PT_INT, + offsetof(dvb_network_t, dn_nitoid) + }, { + "disable_pmt_monitor", "Disable PMT monitor", PT_BOOL, + offsetof(dvb_network_t, dn_disable_pmt_monitor) + }, { + }}, }; /** @@ -42,15 +52,12 @@ static const idclass_t dvb_network_class = { dvb_network_t * dvb_network_create(int fe_type, const char *uuid) { - printf("Creating network %s\n", uuid); dvb_network_t *dn = calloc(1, sizeof(dvb_network_t)); if(idnode_insert(&dn->dn_id, uuid, &dvb_network_class)) { free(dn); return NULL; } - printf("Added network %s\n", idnode_uuid_as_str(&dn->dn_id)); - dn->dn_fe_type = fe_type; TAILQ_INIT(&dn->dn_initial_scan_pending_queue); TAILQ_INIT(&dn->dn_initial_scan_current_queue); @@ -62,20 +69,6 @@ dvb_network_create(int fe_type, const char *uuid) -/** - * - */ -static htsmsg_t * -dvb_network_serialize(struct idnode *self, int full) -{ - dvb_network_t *dn = (dvb_network_t *)self; - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "id", idnode_uuid_as_str(&dn->dn_id)); - htsmsg_add_str(m, "text", idnode_uuid_as_str(&dn->dn_id)); - return m; -} - - /** * */ @@ -161,68 +154,6 @@ dvb_network_save(dvb_network_t *dn) #endif -#if 0 -/** - * - */ -void -dvb_network_set_auto_discovery(dvb_network_t *dn, int on) -{ - if(dn->dn_autodiscovery == on) - return; - - lock_assert(&global_lock); - - tvhlog(LOG_NOTICE, "dvb", "Network \"%s\" mux autodiscovery set to: %s", - dn->dn_displayname, on ? "On" : "Off"); - - dn->dn_autodiscovery = on; - dvb_network_save(dn); -} - - - -/** - * - */ -void -dvb_network_set_nitoid(dvb_network_t *dn, int nitoid) -{ - lock_assert(&global_lock); - - if(dn->dn_nitoid == nitoid) - return; - - tvhlog(LOG_NOTICE, "dvb", "NIT-o network id \"%d\" changed to \"%d\"", - dn->dn_nitoid, nitoid); - - dn->dn_nitoid = nitoid; - dvb_network_save(dn); -} - - - -/** - * - */ -void -dvb_network_set_disable_pmt_monitor(th_dvb_network_t *dn, int on) -{ - if(dn->dn_disable_pmt_monitor == on) - return; - - lock_assert(&global_lock); - - tvhlog(LOG_NOTICE, "dvb", "Network \"%s\" disabled PMT monitoring set to: %s", - dn->dn_displayname, on ? "On" : "Off"); - - dn->dn_disable_pmt_monitor = on; - dvb_network_save(dn); -} - -#endif - - /** * @@ -268,9 +199,6 @@ dvb_network_init(void) if((l = hts_settings_load_r(1, "dvb/networks")) == NULL) return; - - htsmsg_print(l); - HTSMSG_FOREACH(f, l) { if((c = htsmsg_get_map_by_field(f)) == NULL) continue; diff --git a/src/dvb/dvb_service.c b/src/dvb/dvb_service.c index 8b8e1ffb..7fbb2a34 100644 --- a/src/dvb/dvb_service.c +++ b/src/dvb/dvb_service.c @@ -44,7 +44,7 @@ #include "dvb_support.h" #include "notify.h" -static htsmsg_t *dvb_service_serialize(service_t *s, int full); +static htsmsg_t *dvb_service_serialize(service_t *s); /** @@ -414,18 +414,19 @@ dvb_service_find2(dvb_mux_t *dm, uint16_t sid, int pmt_pid, * */ static htsmsg_t * -dvb_service_serialize(service_t *s, int full) +dvb_service_serialize(service_t *s) { dvb_mux_t *dm = s->s_dvb_mux; htsmsg_t *m = htsmsg_create_map(); char buf[100]; - htsmsg_add_str(m, "id", idnode_uuid_as_str(&s->s_id)); - - snprintf(buf, sizeof(buf), "%s (0x%04x)", - s->s_svcname ?: "", s->s_dvb_service_id); - htsmsg_add_str(m, "text", buf); - + if(s->s_svcname) { + htsmsg_add_str(m, "text", s->s_svcname); + } else { + snprintf(buf, sizeof(buf), "Service-0x%04x", + s->s_dvb_service_id); + htsmsg_add_str(m, "text", buf); + } htsmsg_add_u32(m, "enabled", s->s_enabled); htsmsg_add_u32(m, "channel", s->s_channel_number); diff --git a/src/idnode.c b/src/idnode.c index 58b3bbd4..e907b103 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -156,3 +156,29 @@ idnode_unlink(idnode_t *in) { RB_REMOVE(&idnodes, in, in_link); } + + +/** + * + */ +htsmsg_t * +idnode_serialize(struct idnode *self) +{ + const idclass_t *c = self->in_class; + htsmsg_t *m; + if(c->ic_serialize != NULL) { + m = c->ic_serialize(self); + } else { + m = 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)); + htsmsg_add_str(m, "id", idnode_uuid_as_str(self)); + } + return m; +} diff --git a/src/idnode.h b/src/idnode.h index a49b4382..3735801a 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -1,14 +1,17 @@ #pragma once #include "tvheadend.h" +#include "prop.h" struct htsmsg; struct idnode; typedef struct idclass { const char *ic_class; - struct htsmsg *(*ic_serialize)(struct idnode *self, int full); + 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[]; } idclass_t; @@ -27,3 +30,5 @@ const char *idnode_uuid_as_str(const idnode_t *in); idnode_t *idnode_find(const char *uuid); void idnode_unlink(idnode_t *in); + +htsmsg_t *idnode_serialize(struct idnode *self); diff --git a/src/prop.c b/src/prop.c new file mode 100644 index 00000000..7050e8cb --- /dev/null +++ b/src/prop.c @@ -0,0 +1,84 @@ +#include "prop.h" + +#if 0 +/** + * + */ +void +prop_write_values(void *ptr, const property_t p[], 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)); + break; + case PT_INT: + htsmsg_add_s32(m, p[i].id, *(int *)(ptr + p[i].off)); + break; + case PT_STR: + htsmsg_add_str(m, p[i].id, (const char *)(ptr + p[i].off)); + break; + } + } +} +#endif + + +/** + * + */ +void +prop_read_values(void *ptr, const property_t p[], 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)); + break; + case PT_INT: + htsmsg_add_s32(m, p[i].id, *(int *)(ptr + p[i].off)); + break; + case PT_STR: + htsmsg_add_str(m, p[i].id, (const char *)(ptr + p[i].off)); + break; + } + } +} + + +/** + * + */ +htsmsg_t * +prop_get_values(void *ptr, const property_t p[]) +{ + htsmsg_t *m = htsmsg_create_map(); + prop_read_values(ptr, p, m); + return m; +} + + +/** + * + */ +void +prop_read_names(const property_t p[], htsmsg_t *m) +{ + int i = 0; + for(;p[i].name; i++) + htsmsg_add_str(m, p[i].id, p[i].name); +} + + +/** + * + */ +htsmsg_t * +prop_get_names(const property_t p[]) +{ + htsmsg_t *m = htsmsg_create_map(); + prop_read_names(p, m); + return m; +} diff --git a/src/prop.h b/src/prop.h new file mode 100644 index 00000000..148d67ed --- /dev/null +++ b/src/prop.h @@ -0,0 +1,24 @@ +#pragma once +#include + +#include "htsmsg.h" + +typedef enum { + PT_BOOL, + PT_INT, + PT_STR, +} prop_type_t; + +typedef struct property { + const char *id; + const char *name; + prop_type_t type; + size_t off; +} 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[]); diff --git a/src/service.c b/src/service.c index 220f4cbc..89608b82 100644 --- a/src/service.c +++ b/src/service.c @@ -51,7 +51,7 @@ static void service_data_timeout(void *aux); -static htsmsg_t *service_serialize(struct idnode *self, int full); +static htsmsg_t *service_serialize(struct idnode *self); static const idclass_t service_class = { .ic_class = "service", @@ -261,11 +261,6 @@ service_find_instance(channel_t *ch, struct service_instance_list *sil, service_instance_destroy(si); } - printf("Service start, enlisted candidates\n"); - LIST_FOREACH(si, sil, si_link) - printf(" %s i:%d w:%d p:%d\n", si->si_s->s_nicename, si->si_instance, si->si_weight, si->si_prio); - - // Check if any service is already running, if so, use that LIST_FOREACH(si, sil, si_link) if(si->si_s->s_status == SERVICE_RUNNING) @@ -385,27 +380,6 @@ service_enlist(channel_t *ch) #endif -/** - * - */ -unsigned int -service_compute_weight(struct service_list *head) -{ - service_t *t; - th_subscription_t *s; - int w = 0; - - lock_assert(&global_lock); - - LIST_FOREACH(t, head, s_active_link) { - LIST_FOREACH(s, &t->s_subscriptions, ths_service_link) { - if(s->ths_weight > w) - w = s->ths_weight; - } - } - return w; -} - /** * @@ -1219,8 +1193,8 @@ htsmsg_t *servicetype_list ( void ) * */ static htsmsg_t * -service_serialize(struct idnode *self, int full) +service_serialize(struct idnode *self) { service_t *s = (service_t *)self; - return s->s_serialize(s, full); + return s->s_serialize(s); } diff --git a/src/service.h b/src/service.h index d045231a..bfaf1346 100644 --- a/src/service.h +++ b/src/service.h @@ -315,7 +315,7 @@ typedef struct service { void (*s_dtor)(struct service *t); - htsmsg_t *(*s_serialize)(struct service *s, int full); + htsmsg_t *(*s_serialize)(struct service *s); /* * Per source type structs @@ -549,8 +549,6 @@ typedef struct service { void service_init(void); -unsigned int service_compute_weight(struct service_list *head); - int service_start(service_t *t, int instance); service_t *service_create(const char *uuid, int source_type); diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index 408e2d3b..9f48ad33 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -715,7 +715,7 @@ extjs_dvbnetworks(http_connection_t *hc, const char *remain, void *opaque) int i; for(i = 0; v[i] != NULL; i++) { - htsmsg_t *m = v[i]->in_class->ic_serialize(v[i], 0); + 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); diff --git a/src/webui/static/app/dvb_networks.js b/src/webui/static/app/dvb_networks.js index 378df82b..be0ecab6 100644 --- a/src/webui/static/app/dvb_networks.js +++ b/src/webui/static/app/dvb_networks.js @@ -1,30 +1,68 @@ + + + +tvheadend.item_editor = function(item) { + var propsGrid = new Ext.grid.PropertyGrid({ + flex:1, + padding: 5, + propertyNames: item.propertynames, + source: item.properties + }); + return propsGrid; +} + + + + + + + /** * */ tvheadend.dvb_networks = function() { + var current = null; + var loader = new Ext.tree.TreeLoader({ dataUrl: 'dvb/networks' }); var tree = new Ext.tree.TreePanel({ - title: 'DVB Networks', loader: loader, + flex:1, + border: false, root : new Ext.tree.AsyncTreeNode({ id : 'root', text: 'DVB Networks' }), listeners: { click: function(n) { - Ext.Msg.alert('Navigation Tree Click', 'You clicked: "' + n.attributes.text + '"'); + if(current) + panel.remove(current); + current = panel.add(new tvheadend.item_editor(n.attributes)); + panel.doLayout(); } } }); + var panel = new Ext.Panel({ + title: 'DVB Networks', + layout: 'hbox', + flex: 1, + padding: 5, + border: false, + layoutConfig: { + align:'stretch' + }, + items: [tree] + }); + + tree.on('render', function() { tree.getRootNode().expand(); }); - return tree; + return panel; }