diff --git a/Makefile b/Makefile index 79cfc911..f5d064bb 100644 --- a/Makefile +++ b/Makefile @@ -132,6 +132,7 @@ SRCS += src/dvr/dvr_db.c \ SRCS += src/webui/webui.c \ src/webui/comet.c \ src/webui/extjs.c \ + src/webui/extjs_dvb.c \ src/webui/simpleui.c \ src/webui/statedump.c \ src/webui/html.c\ diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 5d78e4e0..a7f674fc 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -38,6 +38,7 @@ typedef struct mpegts_input mpegts_input_t; typedef struct mpegts_table_feed mpegts_table_feed_t; /* Lists */ +typedef LIST_HEAD (,mpegts_network) mpegts_network_list_t; typedef LIST_HEAD (mpegts_input_list,mpegts_input) mpegts_input_list_t; typedef TAILQ_HEAD(mpegts_mux_queue,mpegts_mux) mpegts_mux_queue_t; typedef LIST_HEAD (mpegts_mux_list,mpegts_mux) mpegts_mux_list_t; @@ -393,6 +394,12 @@ struct mpegts_input #endif /* __TVH_MPEGTS_H__ */ +/* **************************************************************************** + * Lists + * ***************************************************************************/ + +extern mpegts_network_list_t mpegts_network_all; + /* **************************************************************************** * Functions * ***************************************************************************/ @@ -413,7 +420,7 @@ mpegts_network_t *mpegts_network_create0 #define mpegts_network_create(t, u, n, c)\ (struct t*)mpegts_network_create0(calloc(1, sizeof(struct t)), &t##_class, u, n, c) - + void mpegts_network_schedule_initial_scan ( mpegts_network_t *mm ); diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index 8ebd1c5d..659790d2 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -112,6 +112,8 @@ mpegts_network_schedule_initial_scan ( mpegts_network_t *mn ) * Creation/Config * ***************************************************************************/ +mpegts_network_list_t mpegts_network_all; + mpegts_network_t * mpegts_network_create0 ( mpegts_network_t *mn, const idclass_t *idc, const char *uuid, @@ -137,6 +139,9 @@ mpegts_network_create0 TAILQ_INIT(&mn->mn_initial_scan_pending_queue); TAILQ_INIT(&mn->mn_initial_scan_current_queue); + /* Add to global list */ + LIST_INSERT_HEAD(&mpegts_network_all, mn, mn_global_link); + mn->mn_display_name(mn, buf, sizeof(buf)); tvhtrace("mpegts", "created network %s", buf); return mn; diff --git a/src/webui/extjs.c b/src/webui/extjs.c index e9593a9e..67c0c4dc 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -134,6 +134,7 @@ extjs_root(http_connection_t *hc, const char *remain, void *opaque) #if ENABLE_LINUXDVB extjs_load(hq, "static/app/dvb.js"); extjs_load(hq, "static/app/dvb_networks.js"); + extjs_load(hq, "static/app/networks.js"); #endif extjs_load(hq, "static/app/iptv.js"); #if ENABLE_V4L @@ -2387,9 +2388,7 @@ extjs_start(void) http_path_add("/tvadapters", NULL, extjs_tvadapters, ACCESS_ADMIN); -#if 0//ENABLE_LINUXDVB extjs_start_dvb(); -#endif #if ENABLE_V4L extjs_start_v4l(); diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index 16aa0964..620abf26 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -35,14 +35,9 @@ #include "access.h" #include "dtable.h" #include "channels.h" -#include "psi.h" #include "serviceprobe.h" -#include "dvb/dvb.h" -#include "dvb/dvb_support.h" -#include "dvb/dvb_preconf.h" -#include "dvr/dvr.h" - +#include "input.h" #if 0 @@ -685,11 +680,141 @@ extjs_dvb_copymux(http_connection_t *hc, const char *remain, void *opaque) /** * */ +#if 0 static int extjs_dvbnetworks(http_connection_t *hc, const char *remain, void *opaque) { return extjs_get_idnode(hc, remain, opaque, &dvb_network_root); } +#endif + +static int +extjs_mpegts_services + (http_connection_t *hc, const char *remain, void *opaque) +{ + char buf[256]; + mpegts_network_t *mn; + mpegts_mux_t *mm; + mpegts_service_t *ms; + htsmsg_t *out, *list = htsmsg_create_list(); + htsbuf_queue_t *hq = &hc->hc_reply; + pthread_mutex_lock(&global_lock); + LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { + LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { + LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) { + htsmsg_t *e = htsmsg_create_map(); + htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&ms->s_id)); + mm->mm_display_name(mm, buf, sizeof(buf)); + htsmsg_add_str(e, "mux", buf); + htsmsg_add_bool(e, "enabled", ms->s_enabled); + htsmsg_add_u32(e, "sid", ms->s_dvb_service_id); + htsmsg_add_u32(e, "pmt", ms->s_pmt_pid); + htsmsg_add_u32(e, "lcn", ms->s_dvb_channel_num); + if (ms->s_dvb_svcname) + htsmsg_add_str(e, "name", ms->s_dvb_svcname); + if (ms->s_dvb_provider) + htsmsg_add_str(e, "provider", ms->s_dvb_provider); + if (ms->s_dvb_cridauth) + htsmsg_add_str(e, "crid_auth", ms->s_dvb_cridauth); + if (ms->s_dvb_charset) + htsmsg_add_str(e, "charset", ms->s_dvb_charset); + htsmsg_add_u32(e, "type", ms->s_dvb_servicetype); + htsmsg_add_msg(list, NULL, e); + } + } + } + pthread_mutex_unlock(&global_lock); + out = htsmsg_create_map(); + htsmsg_add_msg(out, "entries", list); + htsmsg_json_serialize(out, hq, 0); + http_output_content(hc, "text/x-json; charset=UTF-8"); + htsmsg_destroy(out); + + return 0; +} + + +static int +extjs_mpegts_muxes + (http_connection_t *hc, const char *remain, void *opaque) +{ + char buf[256]; + mpegts_network_t *mn; + mpegts_mux_t *mm; + mpegts_service_t *ms; + int s; + htsmsg_t *out, *list = htsmsg_create_list(); + htsbuf_queue_t *hq = &hc->hc_reply; + pthread_mutex_lock(&global_lock); + LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { + LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { + s = 0; + htsmsg_t *e = htsmsg_create_map(); + htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&mm->mm_id)); + mn->mn_display_name(mn, buf, sizeof(buf)); + htsmsg_add_str(e, "network", buf); + mm->mm_display_name(mm, buf, sizeof(buf)); + htsmsg_add_str(e, "name", buf); + htsmsg_add_bool(e, "enabled", mm->mm_enabled); + htsmsg_add_u32(e, "onid", mm->mm_onid); + htsmsg_add_u32(e, "tsid", mm->mm_tsid); + htsmsg_add_bool(e, "initscan", mm->mm_initial_scan_done); + htsmsg_add_str(e, "crid_auth", mm->mm_crid_authority ?: ""); + LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) + s++; + htsmsg_add_u32(e, "num_svc", s); + htsmsg_add_msg(list, NULL, e); + } + } + pthread_mutex_unlock(&global_lock); + out = htsmsg_create_map(); + htsmsg_add_msg(out, "entries", list); + htsmsg_json_serialize(out, hq, 0); + http_output_content(hc, "text/x-json; charset=UTF-8"); + htsmsg_destroy(out); + + return 0; +} + +static int +extjs_mpegts_networks + (http_connection_t *hc, const char *remain, void *opaque) +{ + char buf[256]; + mpegts_network_t *mn; + mpegts_mux_t *mm; + mpegts_service_t *ms; + int m, s; + htsmsg_t *out, *list = htsmsg_create_list(); + htsbuf_queue_t *hq = &hc->hc_reply; + pthread_mutex_lock(&global_lock); + LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { + m = s = 0; + htsmsg_t *e = htsmsg_create_map(); + htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&mn->mn_id)); + mn->mn_display_name(mn, buf, sizeof(buf)); + htsmsg_add_str(e, "name", buf); + htsmsg_add_u32(e, "nid", mn->mn_nid); + htsmsg_add_u32(e, "autodiscovery", mn->mn_autodiscovery); + htsmsg_add_u32(e, "skipinitscan", mn->mn_skipinitscan); + LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { + m++; + LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) + s++; + } + htsmsg_add_u32(e, "num_mux", m); + htsmsg_add_u32(e, "num_svc", s); + htsmsg_add_msg(list, NULL, e); + } + pthread_mutex_unlock(&global_lock); + out = htsmsg_create_map(); + htsmsg_add_msg(out, "entries", list); + htsmsg_json_serialize(out, hq, 0); + http_output_content(hc, "text/x-json; charset=UTF-8"); + htsmsg_destroy(out); + + return 0; +} /** @@ -698,8 +823,13 @@ extjs_dvbnetworks(http_connection_t *hc, const char *remain, void *opaque) void extjs_start_dvb(void) { - http_path_add("/dvb/networks", - NULL, extjs_dvbnetworks, ACCESS_WEB_INTERFACE); + printf("extjs_start_dvb()\n"); + http_path_add("/api/mpegts/networks", + NULL, extjs_mpegts_networks, ACCESS_WEB_INTERFACE); + http_path_add("/api/mpegts/muxes", + NULL, extjs_mpegts_muxes, ACCESS_WEB_INTERFACE); + http_path_add("/api/mpegts/services", + NULL, extjs_mpegts_services, ACCESS_WEB_INTERFACE); #if 0 http_path_add("/dvb/locations", NULL, extjs_dvblocations, ACCESS_WEB_INTERFACE); diff --git a/src/webui/static/app/dvb.js b/src/webui/static/app/dvb.js index 45d3f47b..2612c90d 100644 --- a/src/webui/static/app/dvb.js +++ b/src/webui/static/app/dvb.js @@ -515,7 +515,7 @@ tvheadend.dvb_services = function(adapterData, satConfStore) { header : "Multiplex", dataIndex : 'mux', width : 100 - }); + }]}); if (adapterData.satConf) { // Include DVB-S specific stuff diff --git a/src/webui/static/app/networks.js b/src/webui/static/app/networks.js new file mode 100644 index 00000000..6489967b --- /dev/null +++ b/src/webui/static/app/networks.js @@ -0,0 +1,242 @@ +/* + * DVB Networks + */ + +tvheadend.networks = function() +{ + // TODO: build this from mpegts_network_class? + + var model = new Ext.grid.ColumnModel({ + defaultSortable: true, + columns : [ + { + header : 'Name', + dataIndex : 'name', + width : 200, + editor : new Ext.form.TextField({ + allowBlank : true + }) + }, + { + header : 'Network ID', + dataIndex : 'nid', + width : 100, + editor : new Ext.form.NumberField({ + minValue : 0, + maxValue : 65536 + }) + }, + { + header : 'Auto Discovery', + dataIndex : 'autodiscovery', + width : 50, + editor : new Ext.form.Checkbox({}) + }, + { + header : 'Auto Discovery', + dataIndex : 'skipinitscan', + width : 50, + editor : new Ext.form.Checkbox({}) + }, + { + header : '# Muxes', + dataIndex : 'num_mux', + width : 100, + }, + { + header : '# Services', + dataIndex : 'num_svc', + width : 100, + }, + ] + }); + + var store = new Ext.data.JsonStore({ + root : 'entries', + url : 'api/mpegts/networks', + autoLoad : true, + id : 'uuid', + fields : [ + 'uuid', 'name', 'nid', 'autodiscovery', 'skipinitscan', 'num_mux', 'num_svc' + ], + baseParams : { + op : 'list', + } + }); + + var grid = new Ext.grid.EditorGridPanel({ + stripeRows : true, + title : 'Networks', + store : store, + cm : model, + viewConfig : { + forceFit : true + }, + }); + + return grid; +} + +/* + * DVB Muxes + */ + +tvheadend.muxes = function() +{ + // TODO: build this from mpegts_network_class? + + var model = new Ext.grid.ColumnModel({ + defaultSortable: true, + columns : [ + { + header : 'Enabled', + dataIndex : 'enabled', + width : 50, + editor : new Ext.form.Checkbox({}) + }, + { + header : 'Name', + dataIndex : 'name', + width : 100, + }, + { + header : 'ONID', + dataIndex : 'onid', + width : 50, + }, + { + header : 'TSID', + dataIndex : 'tsid', + width : 50, + editor : new Ext.form.Checkbox({}) + }, + { + header : 'CRID Authority', + dataIndex : 'crid_auth', + width : 100, + editor : new Ext.form.Checkbox({}) + }, + { + header : 'Initial Scan', + dataIndex : 'initscan', + width : 50, + }, + { + header : '# Services', + dataIndex : 'num_svc', + width : 50, + }, + ] + }); + + var store = new Ext.data.JsonStore({ + root : 'entries', + url : 'api/mpegts/muxes', + autoLoad : true, + id : 'uuid', + fields : [ + 'uuid', 'network', 'name', 'onid', 'tsid', 'initscan', 'crid_auth', 'num_svc' + ], + baseParams : { + op : 'list', + } + }); + + var grid = new Ext.grid.EditorGridPanel({ + stripeRows : true, + title : 'Muxes', + store : store, + cm : model, + viewConfig : { + forceFit : true + }, + }); + + return grid; +} + +/* + * DVB Services + */ + +tvheadend.services = function() +{ + // TODO: build this from mpegts_network_class? + + var model = new Ext.grid.ColumnModel({ + defaultSortable: true, + columns : [ + { + header : 'Enabled', + dataIndex : 'enabled', + width : 50, + editor : new Ext.form.Checkbox({}) + }, + { + header : 'Name', + dataIndex : 'name', + width : 100, + }, + { + header : 'Mux', + dataIndex : 'mux', + width : 100, + }, + { + header : 'SID', + dataIndex : 'sid', + width : 50, + }, + { + header : 'PMT PID', + dataIndex : 'pmt', + width : 50, + }, + { + header : 'Type', + dataIndex : 'type', + width : 50, + }, + { + header : 'Provider', + dataIndex : 'provider', + width : 100, + }, + { + header : 'CRID Authority', + dataIndex : 'crid_auth', + width : 100, + }, + { + header : 'Charset', + dataIndex : 'charset', + width : 100, + }, + ] + }); + + var store = new Ext.data.JsonStore({ + root : 'entries', + url : 'api/mpegts/services', + autoLoad : true, + id : 'uuid', + fields : [ + 'uuid', 'mux', 'name', 'sid', 'pmt', 'type', 'provider', 'crid_auth', 'charset' + ], + baseParams : { + op : 'list', + } + }); + + var grid = new Ext.grid.EditorGridPanel({ + stripeRows : true, + title : 'Services', + store : store, + cm : model, + viewConfig : { + forceFit : true + }, + }); + + return grid; +} diff --git a/src/webui/static/app/tvheadend.js b/src/webui/static/app/tvheadend.js index 761be214..2c7d7c54 100644 --- a/src/webui/static/app/tvheadend.js +++ b/src/webui/static/app/tvheadend.js @@ -268,6 +268,9 @@ function accessUpdate(o) { tabs2.push(new tvheadend.tvadapters); } tabs2.push(new tvheadend.iptv); + tabs2.push(new tvheadend.networks); + tabs2.push(new tvheadend.muxes); + tabs2.push(new tvheadend.services); tvheadend.conf_dvbin = new Ext.TabPanel({ activeTab: 0, autoScroll: true,