diff --git a/src/input/mpegts.h b/src/input/mpegts.h index f268e6b7..611f5e7d 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -411,10 +411,10 @@ mpegts_input_t *mpegts_input_create0 mpegts_network_t *mpegts_network_create0 ( mpegts_network_t *mn, const idclass_t *idc, const char *uuid, - const char *name ); + const char *name, htsmsg_t *conf ); -#define mpegts_network_create(t, u, n)\ - (struct t*)mpegts_network_create0(calloc(1, sizeof(struct t)), &t##_class, u, n) +#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 ); @@ -439,7 +439,7 @@ mpegts_mux_t *mpegts_mux_create0 void mpegts_mux_initial_scan_done ( mpegts_mux_t *mm ); -void mpegts_mux_load_one ( mpegts_mux_t *mm, htsmsg_t *c ); +void mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c ); mpegts_mux_instance_t *mpegts_mux_instance_create0 ( mpegts_mux_instance_t *mmi, const idclass_t *class, const char *uuid, diff --git a/src/input/mpegts/linuxdvb/linuxdvb_mux.c b/src/input/mpegts/linuxdvb/linuxdvb_mux.c index 9315aa42..37eb4cbb 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_mux.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_mux.c @@ -30,10 +30,12 @@ #include #include -/* +/* ************************************************************************** * Class definition - */ + * *************************************************************************/ + extern const idclass_t mpegts_mux_class; + const idclass_t linuxdvb_mux_class = { .ic_super = &mpegts_mux_class, @@ -84,9 +86,9 @@ const idclass_t linuxdvb_mux_atsc_class = } }; -/* - * Mux Objects - */ +/* ************************************************************************** + * Class methods + * *************************************************************************/ static void linuxdvb_mux_config_save ( mpegts_mux_t *mm ) @@ -94,7 +96,7 @@ linuxdvb_mux_config_save ( mpegts_mux_t *mm ) linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm; linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network; htsmsg_t *c = htsmsg_create_map(); - idnode_save(&mm->mm_id, c); + mpegts_mux_save(mm, c); dvb_mux_conf_save(ln->ln_type, &lm->lm_tuning, c); hts_settings_save(c, "input/linuxdvb/networks/%s/muxes/%s/config", idnode_uuid_as_str(&mm->mm_network->mn_id), @@ -143,6 +145,10 @@ linuxdvb_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) } #endif +/* ************************************************************************** + * Creation/Config + * *************************************************************************/ + linuxdvb_mux_t * linuxdvb_mux_create0 ( linuxdvb_network_t *ln, @@ -150,10 +156,12 @@ linuxdvb_mux_create0 const char *uuid, htsmsg_t *conf ) { const idclass_t *idc; + const char *str; mpegts_mux_t *mm; linuxdvb_mux_t *lm; - - /* Search for existing */ + dvb_mux_conf_t dmc0; + htsmsg_t *c, *e; + htsmsg_field_t *f; /* Class */ if (ln->ln_type == FE_QPSK) @@ -165,7 +173,20 @@ linuxdvb_mux_create0 else if (ln->ln_type == FE_ATSC) idc = &linuxdvb_mux_atsc_class; else { - tvhlog(LOG_ERR, "linuxdvb", "unknown FE type %d", ln->ln_type); + tvherror("linuxdvb", "unknown FE type %d", ln->ln_type); + return NULL; + } + + /* Load mux config */ + if (conf && !dmc) { + dmc = &dmc0; + if ((str = dvb_mux_conf_load(ln->ln_type, &dmc0, conf))) { + tvherror( "linuxdvb", "failed to load mux config [%s]", str); + return NULL; + } + } + if (!dmc) { + tvherror("linuxdvb", "no mux configuration provided"); return NULL; } @@ -174,49 +195,23 @@ linuxdvb_mux_create0 (mpegts_network_t*)ln, onid, tsid, conf))) return NULL; lm = (linuxdvb_mux_t*)mm; + + /* Tuning */ memcpy(&lm->lm_tuning, dmc, sizeof(dvb_mux_conf_t)); /* Callbacks */ lm->mm_display_name = linuxdvb_mux_display_name; lm->mm_config_save = linuxdvb_mux_config_save; lm->mm_create_instances = linuxdvb_mux_create_instances; - - return (linuxdvb_mux_t*)mm; -} - -linuxdvb_mux_t * -linuxdvb_mux_create1 - ( linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf ) -{ - const char *str; - htsmsg_t *c, *e; - htsmsg_field_t *f; - linuxdvb_mux_t *lm; - dvb_mux_conf_t dmc; - - /* Check tuning */ - memset(&dmc, 0, sizeof(dmc)); - if (conf) { - if ((str = dvb_mux_conf_load(ln->ln_type, &dmc, conf))) { - tvhlog(LOG_ERR, "linuxdvb", "failed to load mux config [%s]", str); - return NULL; - } - } - - lm = linuxdvb_mux_create0(ln, MPEGTS_ONID_NONE, - MPEGTS_TSID_NONE, &dmc, uuid, conf); - if (!lm) return NULL; /* No config */ - if (!conf) - return lm; - - /* Config */ - memcpy(&lm->lm_tuning, &dmc, sizeof(dmc)); + if (!conf) return lm; /* Services */ - if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes/%s/services", - "TODO", uuid))) { + c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes/%s/services", + idnode_uuid_as_str(&ln->mn_id), + idnode_uuid_as_str(&mm->mm_id)); + if (c) { HTSMSG_FOREACH(f, c) { if (!(e = htsmsg_get_map_by_field(f))) continue; if (!(e = htsmsg_get_map(e, "config"))) continue; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_network.c b/src/input/mpegts/linuxdvb/linuxdvb_network.c index d094bff4..eefa36a0 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_network.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_network.c @@ -30,16 +30,22 @@ #include #include +/* **************************************************************************** + * Class definition + * ***************************************************************************/ + extern const idclass_t mpegts_network_class; static const char * -ln_type_getstr ( void *ptr ) +mpegts_network_class_get_lntype + ( void * ptr ) { return dvb_type2str(((linuxdvb_network_t*)ptr)->ln_type); } -static void -ln_type_setstr ( void *ptr, const char *str ) +static void +mpegts_network_class_set_lntype + ( void *ptr, const char *str ) { ((linuxdvb_network_t*)ptr)->ln_type = dvb_str2type(str); } @@ -52,21 +58,15 @@ const idclass_t linuxdvb_network_class = .ic_properties = (const property_t[]){ { PROPDEF2("type", "Network Type", PT_STR, linuxdvb_network_t, ln_type, 1), - .str_get = ln_type_getstr, - .str_set = ln_type_setstr }, + .str_get = mpegts_network_class_get_lntype, + .str_set = mpegts_network_class_set_lntype }, {} } }; -static void -linuxdvb_network_config_save ( mpegts_network_t *mn ) -{ - htsmsg_t *c = htsmsg_create_map(); - idnode_save(&mn->mn_id, c); - hts_settings_save(c, "input/linuxdvb/networks/%s/config", - idnode_uuid_as_str(&mn->mn_id)); - htsmsg_destroy(c); -} +/* **************************************************************************** + * Class methods + * ***************************************************************************/ static mpegts_mux_t * linuxdvb_network_find_mux @@ -84,10 +84,21 @@ linuxdvb_network_find_mux return mm; } +static void +linuxdvb_network_config_save ( mpegts_network_t *mn ) +{ + htsmsg_t *c = htsmsg_create_map(); + idnode_save(&mn->mn_id, c); + hts_settings_save(c, "input/linuxdvb/networks/%s/config", + idnode_uuid_as_str(&mn->mn_id)); + htsmsg_destroy(c); +} + static mpegts_mux_t * linuxdvb_network_create_mux ( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *dmc ) { + // TODO: should we have a mux_find wrapper? linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network; mm = linuxdvb_network_find_mux(ln, dmc); if (!mm) { @@ -102,9 +113,14 @@ static mpegts_service_t * linuxdvb_network_create_service ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid ) { - return linuxdvb_service_create0((linuxdvb_mux_t*)mm, sid, pmt_pid, NULL, NULL); + return linuxdvb_service_create0((linuxdvb_mux_t*)mm, sid, + pmt_pid, NULL, NULL); } +/* **************************************************************************** + * Creation/Config + * ***************************************************************************/ + static linuxdvb_network_t * linuxdvb_network_create0 ( const char *uuid, htsmsg_t *conf ) @@ -114,7 +130,7 @@ linuxdvb_network_create0 htsmsg_field_t *f; /* Create */ - if (!(ln = mpegts_network_create(linuxdvb_network, uuid, NULL))) + if (!(ln = mpegts_network_create(linuxdvb_network, uuid, NULL, conf))) return NULL; /* Callbacks */ @@ -126,9 +142,6 @@ linuxdvb_network_create0 if (!conf) return ln; - /* Load configuration */ - idnode_load(&ln->mn_id, conf); - /* Load muxes */ if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes", uuid))) { HTSMSG_FOREACH(f, c) { @@ -138,18 +151,9 @@ linuxdvb_network_create0 } } - linuxdvb_network_config_save((mpegts_network_t*)ln); - return ln; } -linuxdvb_network_t* -linuxdvb_network_find_by_uuid(const char *uuid) -{ - idnode_t *in = idnode_find(uuid, &linuxdvb_network_class); - return (linuxdvb_network_t*)in; -} - void linuxdvb_network_init ( void ) { htsmsg_t *c, *e; @@ -165,3 +169,20 @@ void linuxdvb_network_init ( void ) } htsmsg_destroy(c); } + +/* **************************************************************************** + * Search + * ***************************************************************************/ + +linuxdvb_network_t* +linuxdvb_network_find_by_uuid(const char *uuid) +{ + idnode_t *in = idnode_find(uuid, &linuxdvb_network_class); + return (linuxdvb_network_t*)in; +} + +/****************************************************************************** + * Editor Configuration + * + * vim:sts=2:ts=2:sw=2:et + *****************************************************************************/ diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 2744d338..70dd2ad1 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -186,8 +186,10 @@ struct linuxdvb_mux linuxdvb_mux_t *linuxdvb_mux_create0 (linuxdvb_network_t *ln, uint16_t onid, uint16_t tsid, const dvb_mux_conf_t *dmc, const char *uuid, htsmsg_t *conf); -linuxdvb_mux_t *linuxdvb_mux_create1 - (linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf); + +#define linuxdvb_mux_create1(n, u, c)\ + linuxdvb_mux_create0(n, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE,\ + NULL, u, c) /* * Service diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index fb6a1a5d..285efa12 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -109,9 +109,9 @@ mpegts_input_recv_packets /* Re-sync */ } else { // TODO: set flag (to avoid spam) - tvhlog(LOG_DEBUG, "tsdemux", "%s ts sync lost", "TODO"); + tvhdebug("tsdemux", "%s ts sync lost", "TODO"); if (ts_resync(tsb, &len, &i)) break; - tvhlog(LOG_DEBUG, "tsdemux", "%s ts sync found", "TODO"); + tvhdebug("tsdemux", "%s ts sync found", "TODO"); } } diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index f0318c25..c31df8c8 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -23,6 +23,13 @@ #include +static void +mpegts_mux_initial_scan_timeout ( void *aux ); + +/* **************************************************************************** + * Mux instance (input linkage) + * ***************************************************************************/ + const idclass_t mpegts_mux_instance_class = { .ic_class = "mpegts_mux_instance", @@ -37,16 +44,21 @@ mpegts_mux_instance_create0 mpegts_input_t *mi, mpegts_mux_t *mm ) { idnode_insert(&mmi->mmi_id, uuid, class); + // TODO: does this need to be an idnode? /* Setup links */ mmi->mmi_mux = mm; - mmi->mmi_input = mi; // TODO: is this required? + mmi->mmi_input = mi; LIST_INSERT_HEAD(&mm->mm_instances, mmi, mmi_mux_link); return mmi; } +/* **************************************************************************** + * Class definition + * ***************************************************************************/ + static void mpegts_mux_class_save ( idnode_t *self ) { @@ -74,6 +86,10 @@ const idclass_t mpegts_mux_class = } }; +/* **************************************************************************** + * Class methods + * ***************************************************************************/ + static void mpegts_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len ) { @@ -92,124 +108,34 @@ mpegts_mux_is_enabled ( mpegts_mux_t *mm ) return mm->mm_enabled; } -int -mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid ) -{ - char buf[256]; - if (onid == mm->mm_onid) - return 0; - mm->mm_onid = onid; - mm->mm_display_name(mm, buf, sizeof(buf)); - mm->mm_config_save(mm); - tvhtrace("mpegts", "%s onid set to %d", buf, onid); - return 1; -} - -int -mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid ) -{ - char buf[256]; - if (tsid == mm->mm_tsid) - return 0; - mm->mm_tsid = tsid; - mm->mm_display_name(mm, buf, sizeof(buf)); - mm->mm_config_save(mm); - tvhtrace("mpegts", "%s tsid set to %d", buf, tsid); - return 1; -} - -int -mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth ) -{ - char buf[256]; - if (defauth && !strcmp(defauth, mm->mm_crid_authority ?: "")) - return 0; - tvh_str_update(&mm->mm_crid_authority, defauth); - mm->mm_display_name(mm, buf, sizeof(buf)); - mm->mm_config_save(mm); - tvhtrace("mpegts", "%s crid authority set to %s", buf, defauth); - return 1; -} - static void -mpegts_mux_initial_scan_link ( mpegts_mux_t *mm ) +mpegts_mux_create_instances ( mpegts_mux_t *mm ) { - mpegts_network_t *mn = mm->mm_network; - - assert(mn != NULL); - assert(mm->mm_initial_scan_status == MM_SCAN_DONE); - - mm->mm_initial_scan_status = MM_SCAN_PENDING; - TAILQ_INSERT_TAIL(&mn->mn_initial_scan_pending_queue, mm, - mm_initial_scan_link); - mn->mn_initial_scan_num++; - tvhtrace("mpegts", "added mm %p to initial scan for mn %p pending %d", - mm, mn, mn->mn_initial_scan_num); - mpegts_network_schedule_initial_scan(mn); -} - -static void -mpegts_mux_initial_scan_timeout ( void *aux ) -{ - mpegts_mux_t *mm = aux; - tvhlog(LOG_DEBUG, "mpegts", "initial scan timed out for mm %p", mm); - mpegts_mux_initial_scan_done(mm); -} - -static int -mpegts_mux_has_subscribers ( mpegts_mux_t *mm ) -{ - service_t *t; - mpegts_mux_instance_t *mmi = mm->mm_active; - if (mmi) { - LIST_FOREACH(t, &mmi->mmi_input->mi_transports, s_active_link) - if (((mpegts_service_t*)t)->s_dvb_mux == mm) - return 1; - } - return 0; -} - -void -mpegts_mux_initial_scan_done ( mpegts_mux_t *mm ) -{ - mpegts_network_t *mn = mm->mm_network; - tvhlog(LOG_DEBUG, "mpegts", "initial scan complete for mm %p", mm); - gtimer_disarm(&mm->mm_initial_scan_timeout); - assert(mm->mm_initial_scan_status == MM_SCAN_CURRENT); - mn->mn_initial_scan_num--; - mm->mm_initial_scan_status = MM_SCAN_DONE; - TAILQ_REMOVE(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link); - mpegts_network_schedule_initial_scan(mn); - - /* Stop */ - if (!mpegts_mux_has_subscribers(mm)) - mm->mm_stop(mm); - - /* Save */ - mm->mm_initial_scan_done = 1; - mm->mm_config_save(mm); } static int mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) { - char buf[128]; + char buf[256], buf2[256]; mpegts_network_t *mn = mm->mm_network; mpegts_mux_instance_t *mmi; - tvhtrace("mpegts", "mm %p starting for '%s' (weight %d)", - mm, reason, weight); + mm->mm_display_name(mm, buf, sizeof(buf)); + tvhinfo("mpegts", "%s - starting for '%s' (weight %d)", + buf, reason, weight); /* Already tuned */ if (mm->mm_active) { - tvhtrace("mpegts", "mm %p already active", mm); + tvhtrace("mpegts", "%s - already active", buf); return 0; } /* Create mux instances (where needed) */ mm->mm_create_instances(mm); - if (!LIST_FIRST(&mm->mm_instances)) - tvhtrace("mpegts", "mm %p has no instances", mm); + if (!LIST_FIRST(&mm->mm_instances)) { + tvhtrace("mpegts", "%s - has no instances", buf); + return SM_CODE_NO_FREE_ADAPTER; + } /* Find */ // TODO: don't like this is unbounded, if for some reason mi_start_mux() @@ -224,13 +150,12 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) break; } if (mmi) - tvhtrace("mpegts", "found free mmi %p", mmi); + tvhtrace("mpegts", "%s - found free mmi %p", buf, mmi); else - tvhtrace("mpegts", "no input is free"); + tvhtrace("mpegts", "%s - no input is free", buf); /* Try and remove a lesser instance */ if (!mmi) { -#if 0 LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link) { /* Bad - skip */ @@ -243,30 +168,30 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) } if (mmi) - tvhtrace("mpegts", "found mmi %p to boot", mmi); -#endif + tvhtrace("mpegts", "%s - found mmi %p to boot", buf, mmi); /* No free input */ - if (!mmi) { - tvhlog(LOG_DEBUG, "mpegts", "no input available"); + else { + tvhdebug("mpegts", "%s - no input available", buf); return SM_CODE_NO_FREE_ADAPTER; } } /* Tune */ - mm->mm_display_name(mm, buf, sizeof(buf)); - tvhlog(LOG_INFO, "mpegts", "tuning %s", buf); + mmi->mmi_input->mi_display_name(mmi->mmi_input, buf2, sizeof(buf2)); + tvhinfo("mpegts", "%s - tuning on %s", buf, buf2); if (!mmi->mmi_input->mi_start_mux(mmi->mmi_input, mmi)) { + tvhdebug("mpegts", "%s - started", buf); LIST_INSERT_HEAD(&mmi->mmi_input->mi_mux_active, mmi, mmi_active_link); mm->mm_active = mmi; break; } - tvhtrace("mpegts", "failed to run mmi %p", mmi); + tvhwarn("mpegts", "%s - failed to start, try another", buf); } /* Initial scanning */ if (mm->mm_initial_scan_status == MM_SCAN_PENDING) { - tvhtrace("mpegts", "adding mm %p to current scan Q", mm); + tvhtrace("mpegts", "%s - adding to current scan Q", buf); TAILQ_REMOVE(&mn->mn_initial_scan_pending_queue, mm, mm_initial_scan_link); mm->mm_initial_scan_status = MM_SCAN_CURRENT; TAILQ_INSERT_TAIL(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link); @@ -279,20 +204,22 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) static void mpegts_mux_stop ( mpegts_mux_t *mm ) { + char buf[256]; service_t *s, *t; mpegts_mux_instance_t *mmi = mm->mm_active; mpegts_input_t *mi; - tvhtrace("mpegts", "stopping mux %p", mm); + mm->mm_display_name(mm, buf, sizeof(buf)); + tvhdebug("mpegts", "%s - stopping mux", buf); if (mmi) { mi = mmi->mmi_input; mi->mi_stop_mux(mi, mmi); mm->mm_active = NULL; LIST_REMOVE(mmi, mmi_active_link); - tvhtrace("mpegts", "active first = %p", LIST_FIRST(&mi->mi_mux_active)); /* Flush all subscribers */ + tvhtrace("mpegts", "%s - flush subscribers", buf); s = LIST_FIRST(&mi->mi_transports); while (s) { t = s; @@ -304,6 +231,7 @@ mpegts_mux_stop ( mpegts_mux_t *mm ) } /* Flush all tables */ + tvhtrace("mpegts", "%s - flush tables", buf); mpegts_table_flush_all(mm); /* Alert listeners */ @@ -311,6 +239,7 @@ mpegts_mux_stop ( mpegts_mux_t *mm ) /* Scanning */ if (mm->mm_initial_scan_status == MM_SCAN_CURRENT) { + tvhtrace("mpegts", "%s - add to pending scan Q", buf); mpegts_network_t *mn = mm->mm_network; TAILQ_REMOVE(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link); mm->mm_initial_scan_status = MM_SCAN_PENDING; @@ -322,51 +251,114 @@ mpegts_mux_stop ( mpegts_mux_t *mm ) mm->mm_active = NULL; } -static void -mpegts_mux_create_instances ( mpegts_mux_t *mm ) -{ -} - static void mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) { + char buf[256]; if (mt->mt_pid >= 0x2000) return; + mm->mm_display_name(mm, buf, sizeof(buf)); if (!mm->mm_table_filter[mt->mt_pid]) - tvhtrace("mpegts", "mm %p opened table pid %04X (%d)", - mm, mt->mt_pid, mt->mt_pid); + tvhtrace("mpegts", "%s - opened table %s pid %04X (%d)", + buf, mt->mt_name, mt->mt_pid, mt->mt_pid); mm->mm_table_filter[mt->mt_pid] = 1; } static void mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) { + char buf[256]; if (mt->mt_pid >= 0x2000) return; - tvhtrace("mpegts", "mm %p closed table pid %04X (%d)", - mm, mt->mt_pid, mt->mt_pid); + mm->mm_display_name(mm, buf, sizeof(buf)); + tvhtrace("mpegts", "%s - closed table %s pid %04X (%d)", + buf, mt->mt_name, mt->mt_pid, mt->mt_pid); mm->mm_table_filter[mt->mt_pid] = 0; } -void -mpegts_mux_load_one ( mpegts_mux_t *mm, htsmsg_t *c ) -{ - uint32_t u32; - - /* ONID */ - if (!htsmsg_get_u32(c, "onid", &u32)) - mm->mm_onid = u32; +/* ************************************************************************** + * Scanning + * *************************************************************************/ - /* TSID */ - if (!htsmsg_get_u32(c, "tsid", &u32)) - mm->mm_tsid = u32; +static int +mpegts_mux_has_subscribers ( mpegts_mux_t *mm ) +{ + service_t *t; + mpegts_mux_instance_t *mmi = mm->mm_active; + if (mmi) { + LIST_FOREACH(t, &mmi->mmi_input->mi_transports, s_active_link) + if (((mpegts_service_t*)t)->s_dvb_mux == mm) + return 1; + } + return 0; } +static void +mpegts_mux_initial_scan_link ( mpegts_mux_t *mm ) +{ + char buf1[256], buf2[256]; + mpegts_network_t *mn = mm->mm_network; + + assert(mn != NULL); + assert(mm->mm_initial_scan_status == MM_SCAN_DONE); + + mm->mm_initial_scan_status = MM_SCAN_PENDING; + TAILQ_INSERT_TAIL(&mn->mn_initial_scan_pending_queue, mm, + mm_initial_scan_link); + mn->mn_initial_scan_num++; + + mn->mn_display_name(mn, buf1, sizeof(buf1)); + mm->mm_display_name(mm, buf2, sizeof(buf2)); + tvhdebug("mpegts", "%s - added %s to scan pending q", + buf1, buf2); + mpegts_network_schedule_initial_scan(mn); +} + +static void +mpegts_mux_initial_scan_timeout ( void *aux ) +{ + char buf[256]; + mpegts_mux_t *mm = aux; + mm->mm_display_name(mm, buf, sizeof(buf)); + tvhdebug("mpegts", "%s - initial scan timed", buf); + mpegts_mux_initial_scan_done(mm); +} + +void +mpegts_mux_initial_scan_done ( mpegts_mux_t *mm ) +{ + char buf[256]; + mpegts_network_t *mn = mm->mm_network; + mm->mm_display_name(mm, buf, sizeof(buf)); + tvhinfo("mpegts", "%s - initial scan complete", buf); + gtimer_disarm(&mm->mm_initial_scan_timeout); + assert(mm->mm_initial_scan_status == MM_SCAN_CURRENT); + mn->mn_initial_scan_num--; + mm->mm_initial_scan_status = MM_SCAN_DONE; + TAILQ_REMOVE(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link); + mpegts_network_schedule_initial_scan(mn); + + /* Stop */ + if (!mpegts_mux_has_subscribers(mm)) { + tvhtrace("mpegts", "%s - no active subscribers, stop", buf); + mm->mm_stop(mm); + } + + /* Save */ + mm->mm_initial_scan_done = 1; + mm->mm_config_save(mm); +} + +/* ************************************************************************** + * Creation / Config + * *************************************************************************/ + mpegts_mux_t * mpegts_mux_create0 ( mpegts_mux_t *mm, const idclass_t *class, const char *uuid, mpegts_network_t *mn, uint16_t onid, uint16_t tsid, htsmsg_t *conf ) { + char buf[256]; idnode_insert(&mm->mm_id, uuid, class); /* Enabled by default */ @@ -403,9 +395,56 @@ mpegts_mux_create0 if (!mm->mm_initial_scan_done || !mn->mn_skipinitscan) mpegts_mux_initial_scan_link(mm); + mm->mm_display_name(mm, buf, sizeof(buf)); + tvhtrace("mpegts", "%s - created", buf); + return mm; } +void +mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c ) +{ + idnode_save(&mm->mm_id, c); +} + +int +mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid ) +{ + char buf[256]; + if (onid == mm->mm_onid) + return 0; + mm->mm_onid = onid; + mm->mm_display_name(mm, buf, sizeof(buf)); + mm->mm_config_save(mm); + tvhtrace("mpegts", "%s - set onid %04X (%d)", buf, onid, onid); + return 1; +} + +int +mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid ) +{ + char buf[256]; + if (tsid == mm->mm_tsid) + return 0; + mm->mm_tsid = tsid; + mm->mm_display_name(mm, buf, sizeof(buf)); + mm->mm_config_save(mm); + tvhtrace("mpegts", "%s - set tsid %04X (%d)", buf, tsid, tsid); + return 1; +} + +int +mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth ) +{ + char buf[256]; + if (defauth && !strcmp(defauth, mm->mm_crid_authority ?: "")) + return 0; + tvh_str_update(&mm->mm_crid_authority, defauth); + mm->mm_display_name(mm, buf, sizeof(buf)); + mm->mm_config_save(mm); + tvhtrace("mpegts", "%s - set crid authority %s", buf, defauth); + return 1; +} /****************************************************************************** * Editor Configuration diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index a94cfad7..9b9b9f2c 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -20,10 +20,23 @@ #include +/* **************************************************************************** + * Class definition + * ***************************************************************************/ + +static void +mpegts_network_class_save + ( idnode_t *in ) +{ + mpegts_network_t *mn = (mpegts_network_t*)in; + mn->mn_config_save(mn); +} + const idclass_t mpegts_network_class = { .ic_class = "mpegts_network", .ic_caption = "MPEGTS Network", + .ic_save = mpegts_network_class_save, .ic_properties = (const property_t[]){ { PROPDEF1("networkname", "Network Name", PT_STR, mpegts_network_t, mn_network_name) }, @@ -37,6 +50,10 @@ const idclass_t mpegts_network_class = } }; +/* **************************************************************************** + * Class methods + * ***************************************************************************/ + static void mpegts_network_display_name ( mpegts_network_t *mn, char *buf, size_t len ) @@ -65,6 +82,10 @@ mpegts_network_create_service return NULL; } +/* **************************************************************************** + * Scanning + * ***************************************************************************/ + static void mpegts_network_initial_scan(void *aux) { @@ -87,36 +108,61 @@ mpegts_network_schedule_initial_scan ( mpegts_network_t *mn ) gtimer_arm(&mn->mn_initial_scan_timer, mpegts_network_initial_scan, mn, 0); } -void -mpegts_network_add_input ( mpegts_network_t *mn, mpegts_input_t *mi ) -{ - mi->mi_network = mn; - LIST_INSERT_HEAD(&mn->mn_inputs, mi, mi_network_link); -} +/* **************************************************************************** + * Creation/Config + * ***************************************************************************/ mpegts_network_t * mpegts_network_create0 ( mpegts_network_t *mn, const idclass_t *idc, const char *uuid, - const char *netname ) + const char *netname, htsmsg_t *conf ) { + char buf[256]; + + /* Setup idnode */ idnode_insert(&mn->mn_id, uuid, idc); + if (conf) + idnode_load(&mn->mn_id, conf); + + /* Default callbacks */ mn->mn_display_name = mpegts_network_display_name; mn->mn_config_save = mpegts_network_config_save; mn->mn_create_mux = mpegts_network_create_mux; mn->mn_create_service = mpegts_network_create_service; + + /* Network name */ if (netname) mn->mn_network_name = strdup(netname); + + /* Init Qs */ TAILQ_INIT(&mn->mn_initial_scan_pending_queue); TAILQ_INIT(&mn->mn_initial_scan_current_queue); + + mn->mn_display_name(mn, buf, sizeof(buf)); + tvhtrace("mpegts", "created network %s", buf); return mn; } +void +mpegts_network_add_input ( mpegts_network_t *mn, mpegts_input_t *mi ) +{ + char buf1[256], buf2[265]; + mi->mi_network = mn; + LIST_INSERT_HEAD(&mn->mn_inputs, mi, mi_network_link); + mn->mn_display_name(mn, buf1, sizeof(buf1)); + mi->mi_display_name(mi, buf2, sizeof(buf2)); + tvhdebug("mpegts", "%s - added input %s", buf1, buf2); +} + int mpegts_network_set_nid ( mpegts_network_t *mn, uint16_t nid ) { + char buf[256]; if (mn->mn_nid == nid) return 0; mn->mn_nid = nid; + mn->mn_display_name(mn, buf, sizeof(buf)); + tvhdebug("mpegts", "%s - set nid %04X (%d)", buf, nid, nid); return 1; } @@ -124,9 +170,12 @@ int mpegts_network_set_network_name ( mpegts_network_t *mn, const char *name ) { + char buf[256]; if (!name || !strcmp(name, mn->mn_network_name ?: "")) return 0; tvh_str_update(&mn->mn_network_name, name); + mn->mn_display_name(mn, buf, sizeof(buf)); + tvhdebug("mpegts", "%s - set name %s", buf, name); return 1; } diff --git a/src/tvhlog.h b/src/tvhlog.h index d2e6844a..761d2c24 100644 --- a/src/tvhlog.h +++ b/src/tvhlog.h @@ -82,8 +82,9 @@ void _tvhlog_hexdump ( const char *file, int line, #define tvhlog_hexdump(...) (void)0 #endif -#define tvhdebug(...) tvhlog(LOG_DEBUG, ##__VA_ARGS__) +#define tvhdebug(...) tvhlog(LOG_DEBUG, ##__VA_ARGS__) #define tvhinfo(...) tvhlog(LOG_INFO, ##__VA_ARGS__) #define tvhwarn(...) tvhlog(LOG_WARNING, ##__VA_ARGS__) +#define tvherror(...) tvhlog(LOG_ERR, ##__VA_ARGS__) #endif /* __TVH_LOGGING_H__ */