From 53f8b5068e0a668b8ce69413cd138a66937ff68a Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 5 Feb 2015 16:49:44 +0100 Subject: [PATCH] mpegts dvb: add satellite position field to network, add proper interaction with predefined muxes --- src/api/api_mpegts.c | 39 ++++++++++++++ src/input/mpegts.h | 1 + src/input/mpegts/dvb.h | 2 + src/input/mpegts/dvb_support.c | 5 ++ src/input/mpegts/mpegts_network.c | 3 ++ src/input/mpegts/mpegts_network_dvb.c | 73 +++++++++++++++++++++++++-- src/input/mpegts/scanfile.c | 10 ++-- src/input/mpegts/scanfile.h | 1 + src/webui/static/app/idnode.js | 18 ++++--- 9 files changed, 138 insertions(+), 14 deletions(-) diff --git a/src/api/api_mpegts.c b/src/api/api_mpegts.c index 7614cf54..1a35e244 100644 --- a/src/api/api_mpegts.c +++ b/src/api/api_mpegts.c @@ -327,6 +327,42 @@ api_mpegts_mux_sched_create return err; } +static int +api_dvb_orbitalpos_list + ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) +{ + htsmsg_t *l, *e, *c; + htsmsg_field_t *f; + const char *s; + int satpos, i; + char buf[128]; + + if (!satellites) + return 0; + + l = htsmsg_create_list(); + HTSMSG_FOREACH(f, satellites) { + if((c = htsmsg_get_map_by_field(f)) == NULL) + continue; + if(htsmsg_get_s32(c, "pos", &satpos)) + continue; + if((s = htsmsg_get_str(c, "name")) == NULL) + continue; + e = htsmsg_create_map(); + dvb_sat_position_to_str(satpos, buf, sizeof(buf)); + htsmsg_add_str(e, "key", buf); + i = strlen(buf); + snprintf(buf + i, sizeof(buf) - i, " : %s", s); + htsmsg_add_str(e, "val", buf); + htsmsg_add_msg(l, NULL, e); + } + *resp = htsmsg_create_map(); + htsmsg_add_msg(*resp, "entries", l); + + return 0; +} + + #if ENABLE_MPEGTS_DVB static int api_dvb_scanfile_list @@ -334,6 +370,7 @@ api_dvb_scanfile_list { char buf[512]; const char *type = htsmsg_get_str(args, "type"); + int satpos = htsmsg_get_s32_or_default(args, "satpos", INT_MAX); scanfile_region_list_t *list = NULL; htsmsg_t *l, *e; scanfile_region_t *r; @@ -356,6 +393,7 @@ api_dvb_scanfile_list l = htsmsg_create_list(); LIST_FOREACH(r, list, sfr_link) { LIST_FOREACH(n, &r->sfr_networks, sfn_link) { + if (satpos != INT_MAX && n->sfn_satpos != satpos) continue; e = htsmsg_create_map(); sprintf(buf, "%s/%s/%s", type, r->sfr_id, n->sfn_id); htsmsg_add_str(e, "key", buf); @@ -401,6 +439,7 @@ api_mpegts_init ( void ) { "mpegts/mux_sched/class", ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_mux_sched_class }, { "mpegts/mux_sched/grid", ACCESS_ADMIN, api_idnode_grid, api_mpegts_mux_sched_grid }, { "mpegts/mux_sched/create", ACCESS_ADMIN, api_mpegts_mux_sched_create, NULL }, + { "dvb/orbitalpos/list", ACCESS_ADMIN, api_dvb_orbitalpos_list, NULL }, #if ENABLE_MPEGTS_DVB { "dvb/scanfile/list", ACCESS_ADMIN, api_dvb_scanfile_list, NULL }, #endif diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 1befbf6a..042ff0c1 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -300,6 +300,7 @@ struct mpegts_network int mn_ignore_chnum; int mn_sid_chnum; int mn_localtime; + int mn_satpos; }; typedef enum mpegts_mux_scan_state diff --git a/src/input/mpegts/dvb.h b/src/input/mpegts/dvb.h index f1eb9dd1..76e7f19b 100644 --- a/src/input/mpegts/dvb.h +++ b/src/input/mpegts/dvb.h @@ -236,6 +236,8 @@ void psi_tables_dvb ( struct mpegts_mux *mm ); void psi_tables_atsc_t ( struct mpegts_mux *mm ); void psi_tables_atsc_c ( struct mpegts_mux *mm ); +extern htsmsg_t *satellites; + /* * */ diff --git a/src/input/mpegts/dvb_support.c b/src/input/mpegts/dvb_support.c index 7e88b437..1673cebb 100644 --- a/src/input/mpegts/dvb_support.c +++ b/src/input/mpegts/dvb_support.c @@ -31,6 +31,7 @@ #include "dvb_charset_tables.h" #include "input.h" #include "intlconv.h" +#include "settings.h" static int convert_iso_8859[16] = { -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, 13 @@ -923,8 +924,11 @@ dvb_sat_position_from_str( const char *buf ) /** * */ +htsmsg_t *satellites; + void dvb_init( void ) { + satellites = hts_settings_load("satellites"); } void dvb_done( void ) @@ -932,4 +936,5 @@ void dvb_done( void ) extern SKEL_DECLARE(mpegts_table_state_skel, struct mpegts_table_state); SKEL_FREE(mpegts_table_state_skel); + htsmsg_destroy(satellites); } diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index 481bb9d6..4c0b90e7 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -357,6 +357,9 @@ mpegts_network_create0 TAILQ_INIT(&mn->mn_scan_active); gtimer_arm(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, 0); + /* Defaults */ + mn->mn_satpos = INT_MAX; + /* Load config */ if (conf) idnode_load(&mn->mn_id, conf); diff --git a/src/input/mpegts/mpegts_network_dvb.c b/src/input/mpegts/mpegts_network_dvb.c index afe7f78b..f7e2641a 100644 --- a/src/input/mpegts/mpegts_network_dvb.c +++ b/src/input/mpegts/mpegts_network_dvb.c @@ -76,6 +76,10 @@ dvb_network_class_scanfile_set ( void *o, const void *s ) if (!(sfn = scanfile_find(s))) return 0; + /* Set satellite position */ + if (sfn->sfn_satpos != INT_MAX && ln->mn_satpos == INT_MAX) + ln->mn_satpos = sfn->sfn_satpos; + /* Create */ LIST_FOREACH(dmc, &sfn->sfn_muxes, dmc_link) { if (!(mm = dvb_network_find_mux(ln, dmc, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE))) { @@ -103,35 +107,86 @@ dvb_network_class_scanfile_set ( void *o, const void *s ) return 0; } static htsmsg_t * -dvb_network_class_scanfile_list ( const char *type ) +dvb_network_class_scanfile_list ( void *o, const char *type ) { + dvb_network_t *ln = o; htsmsg_t *e, *m = htsmsg_create_map(); htsmsg_add_str(m, "type", "api"); htsmsg_add_str(m, "uri", "dvb/scanfile/list"); + htsmsg_add_str(m, "stype", "none"); e = htsmsg_create_map(); htsmsg_add_str(e, "type", type); + if (ln && ln->mn_satpos != INT_MAX) + htsmsg_add_s32(e, "satpos", ln->mn_satpos); htsmsg_add_msg(m, "params", e); return m; } + static htsmsg_t * dvb_network_dvbt_class_scanfile_list ( void *o ) { - return dvb_network_class_scanfile_list("dvbt"); + return dvb_network_class_scanfile_list(o, "dvbt"); } static htsmsg_t * dvb_network_dvbc_class_scanfile_list ( void *o ) { - return dvb_network_class_scanfile_list("dvbc"); + return dvb_network_class_scanfile_list(o, "dvbc"); } static htsmsg_t * dvb_network_dvbs_class_scanfile_list ( void *o ) { - return dvb_network_class_scanfile_list("dvbs"); + return dvb_network_class_scanfile_list(o, "dvbs"); } static htsmsg_t * dvb_network_atsc_class_scanfile_list ( void *o ) { - return dvb_network_class_scanfile_list("atsc"); + return dvb_network_class_scanfile_list(o, "atsc"); +} + +static const void * +dvb_network_class_orbital_pos_get ( void *o ) +{ + dvb_network_t *ln = o; + static char buf[16]; + static const char *s; + s = NULL; + if (ln->mn_satpos != INT_MAX) { + dvb_sat_position_to_str(ln->mn_satpos, buf, sizeof(buf)); + s = buf; + } else + s = ""; + return &s; +} + +static int +dvb_network_class_orbital_pos_set ( void *o, const void *s ) +{ + dvb_network_t *ln = o; + int satpos; + + /* Find */ + if (!s) + return 0; + + satpos = dvb_sat_position_from_str(s); + if (satpos != ln->mn_satpos) { + ln->mn_satpos = satpos; + return 1; + } + + return 0; +} + +static htsmsg_t * +dvb_network_class_orbital_pos_list ( void *o ) +{ + htsmsg_t *e, *m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "dvb/orbitalpos/list"); + htsmsg_add_str(m, "stype", "none"); + e = htsmsg_create_map(); + htsmsg_add_msg(m, "params", e); + return m; } const idclass_t dvb_network_class = @@ -198,6 +253,14 @@ const idclass_t dvb_network_dvbs_class = .list = dvb_network_dvbs_class_scanfile_list, .opts = PO_NOSAVE, }, + { + .type = PT_STR, + .id = "orbital_pos", + .name = "Orbital Position", + .set = dvb_network_class_orbital_pos_set, + .get = dvb_network_class_orbital_pos_get, + .list = dvb_network_class_orbital_pos_list, + }, {} } }; diff --git a/src/input/mpegts/scanfile.c b/src/input/mpegts/scanfile.c index 2ac82842..187ed2c5 100644 --- a/src/input/mpegts/scanfile.c +++ b/src/input/mpegts/scanfile.c @@ -227,7 +227,7 @@ scanfile_network_dvbs_pos(char *n, int *rpos) { int len = strlen(n), pos = len - 1, frac = 0; - if (len > 0 && n[pos] != 'W' && n[pos] != 'E') + if (len > 0 && toupper(n[pos]) != 'W' && toupper(n[pos]) != 'E') return 0; pos--; while (pos >= 0 && isdigit(n[pos])) @@ -248,7 +248,7 @@ scanfile_network_dvbs_pos(char *n, int *rpos) n[pos] = '\0'; *rpos *= 10; *rpos += frac; - if (n[len-1] == 'W') + if (toupper(n[len-1]) == 'W') *rpos = -*rpos; return 1; } @@ -257,7 +257,9 @@ static int scanfile_network_cmp ( scanfile_network_t *a, scanfile_network_t *b ) { - return strcmp(a->sfn_name, b->sfn_name); + if (a->sfn_satpos == b->sfn_satpos) + return strcmp(a->sfn_name, b->sfn_name); + return b->sfn_satpos - a->sfn_satpos; } static int scanfile_region_cmp @@ -601,6 +603,7 @@ scanfile_load_file str++; } *str = '\0'; + opos = INT_MAX; if (!strcmp(type, "dvb-s") && scanfile_network_dvbs_pos(buf, &opos)) { snprintf(buf3, sizeof(buf3), "%c%3i.%i%c:%s", opos < 0 ? '<' : '>', abs(opos) / 10, abs(opos) % 10, @@ -611,6 +614,7 @@ scanfile_load_file net = calloc(1, sizeof(scanfile_network_t)); net->sfn_id = strdup(buf2); net->sfn_name = strdup(buf); + net->sfn_satpos = opos; LIST_INSERT_SORTED(®->sfr_networks, net, sfn_link, scanfile_network_cmp); /* Process file */ diff --git a/src/input/mpegts/scanfile.h b/src/input/mpegts/scanfile.h index b8547758..5db08469 100644 --- a/src/input/mpegts/scanfile.h +++ b/src/input/mpegts/scanfile.h @@ -22,6 +22,7 @@ typedef struct scanfile_network { const char *sfn_id; const char *sfn_name; + int sfn_satpos; LIST_ENTRY(scanfile_network) sfn_link; LIST_HEAD(,dvb_mux_conf) sfn_muxes; } scanfile_network_t; diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js index bf13d169..4b01a74c 100644 --- a/src/webui/static/app/idnode.js +++ b/src/webui/static/app/idnode.js @@ -16,6 +16,13 @@ tvheadend.idnode_get_enum = function(conf) if (key in tvheadend.idnode_enum_stores) return tvheadend.idnode_enum_stores[key]; + var stype = Ext.data.SortTypes.none; + var sinfo = conf.sort; + if (conf.stype !== 'none') { + stype = Ext.data.SortTypes.asUCString; + sinfo = { field: 'val', 'direction': 'ASC' }; + } + /* Build store */ var st = new Ext.data.JsonStore({ root: conf.root || 'entries', @@ -24,18 +31,16 @@ tvheadend.idnode_get_enum = function(conf) fields: conf.fields || [ 'key', + 'val', { name: 'val', - sortType: Ext.data.SortTypes.asUCString + sortType: stype } ], id: conf.id || 'key', autoLoad: true, listeners: conf.listeners || {}, - sortInfo: conf.sort || { - field: 'val', - direction: 'ASC' - } + sortInfo: sinfo }); tvheadend.idnode_enum_stores[key] = st; @@ -75,7 +80,8 @@ tvheadend.idnode_enum_store = function(f) return tvheadend.idnode_get_enum({ url: 'api/' + f['enum'].uri, params: f['enum'].params, - event: f['enum'].event + event: f['enum'].event, + stype: f['enum'].stype }); }