diff --git a/src/capmt.c b/src/capmt.c index 1bfc0300..1565309a 100644 --- a/src/capmt.c +++ b/src/capmt.c @@ -629,7 +629,7 @@ capmt_table_input(struct th_descrambler *td, struct service *t, { capmt_service_t *ct = (capmt_service_t *)td; capmt_t *capmt = ct->ct_capmt; - int adapter_num = t->s_dvb_mux_instance->tdmi_adapter->tda_adapter_num; + int adapter_num = t->s_dvb_mux->dm_current_tdmi->tdmi_adapter->tda_adapter_num; int total_caids = 0, current_caid = 0; int i; @@ -893,7 +893,7 @@ capmt_service_start(service_t *t) tvhlog(LOG_INFO, "capmt", "Starting capmt server for service \"%s\" on tuner %d", t->s_svcname, - t->s_dvb_mux_instance->tdmi_adapter->tda_adapter_num); + t->s_dvb_mux->dm_current_tdmi->tdmi_adapter->tda_adapter_num); elementary_stream_t *st; diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index c1bc22f9..4c4594b2 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -41,6 +41,7 @@ LIST_HEAD(th_dvb_mux_instance_list, th_dvb_mux_instance); TAILQ_HEAD(dvb_satconf_queue, dvb_satconf); LIST_HEAD(dvb_mux_list, dvb_mux); TAILQ_HEAD(dvb_mux_queue, dvb_mux); +LIST_HEAD(dvb_network_list, dvb_network); /** * Satconf @@ -89,7 +90,7 @@ typedef struct dvb_mux_conf { */ typedef struct dvb_network { - struct th_dvb_mux_instance_list dn_mux_instances; // Should go away + LIST_ENTRY(dvb_network) dn_global_link; struct dvb_mux_queue dn_initial_scan_queue; int dn_initial_num_mux; @@ -102,6 +103,12 @@ typedef struct dvb_network { gtimer_t dn_mux_scanner_timer; + uint32_t dn_disable_pmt_monitor; + uint32_t dn_autodiscovery; + uint32_t dn_nitoid; + + char *dn_uuid; + } dvb_network_t; @@ -125,8 +132,6 @@ typedef struct dvb_mux { TAILQ_HEAD(, epggrab_ota_mux) dm_epg_grab; - struct th_dvb_mux_instance *dm_tdmi; // wrong - TAILQ_ENTRY(dvb_mux) dm_scan_link; struct dvb_mux_queue *dm_scan_queue; @@ -138,6 +143,15 @@ typedef struct dvb_mux { struct th_dvb_mux_instance *dm_current_tdmi; + struct th_dvb_mux_instance_list dm_tdmis; + + // Derived from dm_conf (more or less) + char *dm_local_identifier; + + char *dm_uuid; + + int dm_enabled; + } dvb_mux_t; @@ -149,12 +163,11 @@ typedef struct dvb_mux { typedef struct th_dvb_mux_instance { dvb_mux_t *tdmi_mux; - - RB_ENTRY(th_dvb_mux_instance) tdmi_global_link; - - LIST_ENTRY(th_dvb_mux_instance) tdmi_adapter_link; // wrong + LIST_ENTRY(th_dvb_mux_instance) tdmi_mux_link; struct th_dvb_adapter *tdmi_adapter; + LIST_ENTRY(th_dvb_mux_instance) tdmi_adapter_link; + uint16_t tdmi_snr, tdmi_signal; uint32_t tdmi_ber, tdmi_unc; @@ -177,10 +190,8 @@ typedef struct th_dvb_mux_instance { int tdmi_quality; - int tdmi_enabled; - - - char *tdmi_identifier; + int tdmi_tune_failed; // Adapter failed to tune this frequency + // Don't try again struct th_subscription_list tdmi_subscriptions; @@ -216,6 +227,8 @@ typedef struct th_dvb_adapter { dvb_network_t *tda_dn; + struct th_dvb_mux_instance_list tda_tdmis; + th_dvb_mux_instance_t *tda_current_tdmi; char *tda_tune_reason; // Reason for last tune @@ -223,17 +236,14 @@ typedef struct th_dvb_adapter { const char *tda_rootpath; char *tda_identifier; - uint32_t tda_autodiscovery; 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; - uint32_t tda_nitoid; uint32_t tda_diseqc_version; uint32_t tda_diseqc_repeats; - uint32_t tda_disable_pmt_monitor; int32_t tda_full_mux_rx; char *tda_displayname; @@ -340,8 +350,9 @@ typedef struct th_dvb_table { } th_dvb_table_t; +extern struct dvb_network_list dvb_networks; extern struct th_dvb_adapter_queue dvb_adapters; -extern struct th_dvb_mux_instance_tree dvb_muxes; +//extern struct th_dvb_mux_instance_tree dvb_muxes; void dvb_init(uint32_t adapter_mask, const char *rawfile); @@ -418,17 +429,17 @@ int dvb_mux_str2mode(const char *str); int dvb_mux_str2guard(const char *str); int dvb_mux_str2hier(const char *str); -void dvb_mux_save(th_dvb_mux_instance_t *tdmi); +void dvb_mux_save(dvb_mux_t *dm); -void dvb_mux_load(th_dvb_adapter_t *tda); +void dvb_mux_load(dvb_network_t *dn); -void dvb_mux_destroy(th_dvb_mux_instance_t *tdmi); +void dvb_mux_destroy(dvb_mux_t *dm); -th_dvb_mux_instance_t *dvb_mux_create(th_dvb_adapter_t *tda, - const struct dvb_mux_conf *dmc, - uint16_t onid, uint16_t tsid, const char *network, - const char *logprefix, int enabled, - int initialscan, const char *identifier); +dvb_mux_t *dvb_mux_create(dvb_network_t *tda, + const struct dvb_mux_conf *dmc, + uint16_t onid, uint16_t tsid, const char *network, + const char *logprefix, int enabled, + int initialscan, const char *uuid); void dvb_mux_set_networkname(dvb_mux_t *dm, const char *name); @@ -441,11 +452,11 @@ void dvb_mux_set_enable(th_dvb_mux_instance_t *tdmi, int enabled); void dvb_mux_set_satconf(th_dvb_mux_instance_t *tdmi, const char *scid, int save); -htsmsg_t *dvb_mux_build_msg(th_dvb_mux_instance_t *tdmi); +htsmsg_t *dvb_mux_build_msg(dvb_mux_t *dm); -void dvb_mux_notify(th_dvb_mux_instance_t *tdmi); +void dvb_mux_notify(dvb_mux_t *dm); -const char *dvb_mux_add_by_params(th_dvb_adapter_t *tda, +const char *dvb_mux_add_by_params(dvb_network_t *dn, int freq, int symrate, int bw, @@ -464,27 +475,33 @@ int dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src, dvb_satconf_t *satconf); #endif -th_dvb_mux_instance_t *dvb_mux_find - (th_dvb_adapter_t *tda, const char *netname, uint16_t onid, uint16_t tsid, - int enabled ); +dvb_mux_t *dvb_mux_find(dvb_network_t *dn, const char *netname, uint16_t onid, + uint16_t tsid, int enabled); + /** * DVB Transport (aka DVB service) */ -void dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier); +void dvb_tdmi_destroy(th_dvb_mux_instance_t *tdmi); -struct service *dvb_service_find(th_dvb_mux_instance_t *tdmi, - uint16_t sid, int pmt_pid, - const char *identifier); +/** + * DVB Transport (aka DVB service) + */ +void dvb_service_load(dvb_mux_t *dm); -struct service *dvb_service_find2(th_dvb_mux_instance_t *tdmi, - uint16_t sid, int pmt_pid, - const char *identifier, int *save); +struct service *dvb_service_find(dvb_mux_t *dm, + uint16_t sid, int pmt_pid, + const char *identifier); -struct service *dvb_service_find3 - (th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi, - const char *netname, uint16_t onid, uint16_t tsid, uint16_t sid, - int enabled, int epgprimary); +struct service *dvb_service_find2(dvb_mux_t *dm, + uint16_t sid, int pmt_pid, + const char *identifier, int *save); + +struct service *dvb_service_find3(dvb_network_t *dn, + dvb_mux_t *dm, + const char *netname, uint16_t onid, + uint16_t tsid, uint16_t sid, + int enabled, int epgprimary); void dvb_service_notify(struct service *t); diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index eeb9b749..b7029fb3 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -76,18 +76,15 @@ 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, "autodiscovery", tda->tda_autodiscovery); 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); - htsmsg_add_u32(m, "nitoid", tda->tda_nitoid); htsmsg_add_u32(m, "diseqc_version", tda->tda_diseqc_version); htsmsg_add_u32(m, "diseqc_repeats", tda->tda_diseqc_repeats); htsmsg_add_u32(m, "extrapriority", tda->tda_extrapriority); htsmsg_add_u32(m, "skip_initialscan", tda->tda_skip_initialscan); - htsmsg_add_u32(m, "disable_pmt_monitor", tda->tda_disable_pmt_monitor); htsmsg_add_s32(m, "full_mux_rx", tda->tda_full_mux_rx); hts_settings_save(m, "dvbadapters/%s", tda->tda_identifier); htsmsg_destroy(m); @@ -117,25 +114,6 @@ dvb_adapter_set_displayname(th_dvb_adapter_t *tda, const char *s) } -/** - * - */ -void -dvb_adapter_set_auto_discovery(th_dvb_adapter_t *tda, int on) -{ - if(tda->tda_autodiscovery == on) - return; - - lock_assert(&global_lock); - - tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" mux autodiscovery set to: %s", - tda->tda_displayname, on ? "On" : "Off"); - - tda->tda_autodiscovery = on; - tda_save(tda); -} - - /** * */ @@ -247,26 +225,6 @@ dvb_adapter_set_poweroff(th_dvb_adapter_t *tda, int on) } -/** - * - */ -void -dvb_adapter_set_nitoid(th_dvb_adapter_t *tda, int nitoid) -{ - lock_assert(&global_lock); - - if(tda->tda_nitoid == nitoid) - return; - - tvhlog(LOG_NOTICE, "dvb", "NIT-o network id \"%d\" changed to \"%d\"", - tda->tda_nitoid, nitoid); - - tda->tda_nitoid = nitoid; - - tda_save(tda); - -} - /** * @@ -322,25 +280,6 @@ dvb_adapter_set_extrapriority(th_dvb_adapter_t *tda, int extrapriority) tda_save(tda); } -/** - * - */ -void -dvb_adapter_set_disable_pmt_monitor(th_dvb_adapter_t *tda, int on) -{ - if(tda->tda_disable_pmt_monitor == on) - return; - - lock_assert(&global_lock); - - tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" disabled PMT monitoring set to: %s", - tda->tda_displayname, on ? "On" : "Off"); - - tda->tda_disable_pmt_monitor = on; - tda_save(tda); -} - - /** * */ @@ -475,8 +414,6 @@ tda_add(int adapter_num) tda->tda_identifier = strdup(buf); - tda->tda_autodiscovery = tda->tda_fe_type != FE_QPSK; - tda->tda_sat = tda->tda_fe_type == FE_QPSK; /* Come up with an initial displayname, user can change it and it will @@ -521,11 +458,7 @@ tda_add_from_file(const char *filename) buf[i] = '_'; tda->tda_identifier = strdup(buf); - - tda->tda_autodiscovery = 0; - tda->tda_sat = 0; - tda->tda_full_mux_rx = 1; /* Come up with an initial displayname, user can change it and it will @@ -661,18 +594,15 @@ dvb_adapter_init(uint32_t adapter_mask, const char *rawfile) free(tda->tda_displayname); tda->tda_displayname = strdup(name); - htsmsg_get_u32(c, "autodiscovery", &tda->tda_autodiscovery); 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); - htsmsg_get_u32(c, "nitoid", &tda->tda_nitoid); htsmsg_get_u32(c, "diseqc_version", &tda->tda_diseqc_version); htsmsg_get_u32(c, "diseqc_repeats", &tda->tda_diseqc_repeats); htsmsg_get_u32(c, "extrapriority", &tda->tda_extrapriority); htsmsg_get_u32(c, "skip_initialscan", &tda->tda_skip_initialscan); - htsmsg_get_u32(c, "disable_pmt_monitor", &tda->tda_disable_pmt_monitor); if (htsmsg_get_s32(c, "full_mux_rx", &tda->tda_full_mux_rx)) if (!htsmsg_get_u32(c, "disable_full_mux_rx", &u32) && u32) tda->tda_full_mux_rx = 0; @@ -685,8 +615,6 @@ dvb_adapter_init(uint32_t adapter_mask, const char *rawfile) if(tda->tda_sat) dvb_satconf_init(tda); - - dvb_mux_load(tda); } } @@ -776,6 +704,7 @@ dvb_adapter_clone(th_dvb_adapter_t *dst, th_dvb_adapter_t *src) /** * */ +#if 0 int dvb_adapter_destroy(th_dvb_adapter_t *tda) { @@ -788,8 +717,8 @@ dvb_adapter_destroy(th_dvb_adapter_t *tda) hts_settings_remove("dvbadapters/%s", tda->tda_identifier); - while((tdmi = LIST_FIRST(&tda->tda_dn->dn_mux_instances)) != NULL) - dvb_mux_destroy(tdmi); + while((tdmi = LIST_FIRST(&tda->tda_tdmis)) != NULL) + dvb_tdmi_destroy(tdmi); TAILQ_REMOVE(&dvb_adapters, tda, tda_global_link); @@ -801,6 +730,7 @@ dvb_adapter_destroy(th_dvb_adapter_t *tda) return 0; } +#endif /** @@ -940,8 +870,7 @@ dvb_adapter_input_dvr(void *aux) } } else { LIST_FOREACH(t, &tda->tda_transports, s_active_link) - if(t->s_dvb_mux_instance == tda->tda_current_tdmi) - ts_recv_packet1(t, tsb + i, NULL); + ts_recv_packet1(t, tsb + i, NULL); } i += 188; @@ -981,33 +910,17 @@ dvb_adapter_build_msg(th_dvb_adapter_t *tda) { char buf[100]; htsmsg_t *m = htsmsg_create_map(); - th_dvb_mux_instance_t *tdmi; - service_t *t; - int nummux = 0; - int numsvc = 0; int fdiv; htsmsg_add_str(m, "identifier", tda->tda_identifier); htsmsg_add_str(m, "name", tda->tda_displayname); - // XXX: bad bad bad slow slow slow - LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) { - nummux++; - LIST_FOREACH(t, &tdmi->tdmi_mux->dm_services, s_group_link) { - numsvc++; - } - } - htsmsg_add_str(m, "type", "dvb"); - htsmsg_add_u32(m, "services", numsvc); - htsmsg_add_u32(m, "muxes", nummux); - htsmsg_add_u32(m, "initialMuxes", tda->tda_dn->dn_initial_num_mux); - if(tda->tda_current_tdmi != NULL) { th_dvb_mux_instance_t *tdmi = tda->tda_current_tdmi; - dvb_mux_nicename(buf, sizeof(buf), tda->tda_current_tdmi); + dvb_mux_nicename(buf, sizeof(buf), tda->tda_current_tdmi->tdmi_mux); htsmsg_add_str(m, "currentMux", buf); htsmsg_add_u32(m, "signal", MIN(tdmi->tdmi_signal * 100 / 65535, 100)); diff --git a/src/dvb/dvb_fe.c b/src/dvb/dvb_fe.c index 09d52098..dafca714 100644 --- a/src/dvb/dvb_fe.c +++ b/src/dvb/dvb_fe.c @@ -97,7 +97,6 @@ dvb_fe_monitor(void *aux) streaming_message_t sm; struct service *t; - int store = 0; int notify = 0; gtimer_arm(&tda->tda_fe_monitor_timer, dvb_fe_monitor, tda, 1); @@ -191,11 +190,10 @@ dvb_fe_monitor(void *aux) if(status != tdmi->tdmi_fe_status) { tdmi->tdmi_fe_status = status; - dvb_mux_nicename(buf, sizeof(buf), tdmi); + dvb_mux_nicename(buf, sizeof(buf), tdmi->tdmi_mux); tvhlog(LOG_DEBUG, "dvb", "\"%s\" on adapter \"%s\", status changed to %s", buf, tda->tda_displayname, dvb_mux_status(tdmi)); - store = 1; notify = 1; } @@ -208,12 +206,13 @@ dvb_fe_monitor(void *aux) } if(q != tdmi->tdmi_quality) { tdmi->tdmi_quality = q; - store = 1; notify = 1; } } if(notify) { + +#if 0 // XXX(dvbreorg) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "id", tdmi->tdmi_identifier); htsmsg_add_u32(m, "quality", tdmi->tdmi_quality); @@ -222,8 +221,9 @@ dvb_fe_monitor(void *aux) htsmsg_add_u32(m, "ber", tdmi->tdmi_ber); htsmsg_add_u32(m, "unc", tdmi->tdmi_unc); notify_by_msg("dvbMux", m); +#endif - m = htsmsg_create_map(); + htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "identifier", tda->tda_identifier); htsmsg_add_u32(m, "signal", MIN(tdmi->tdmi_signal * 100 / 65535, 100)); htsmsg_add_u32(m, "snr", tdmi->tdmi_snr); @@ -233,8 +233,10 @@ dvb_fe_monitor(void *aux) notify_by_msg("tvAdapter", m); } +#if 0 // XXX(dvbreorg) if(store) dvb_mux_save(tdmi); +#endif /* Streaming message */ sigstat.status_text = dvb_mux_status(tdmi); @@ -244,14 +246,11 @@ dvb_fe_monitor(void *aux) sigstat.unc = tdmi->tdmi_unc; sm.sm_type = SMT_SIGNAL_STATUS; sm.sm_data = &sigstat; - LIST_FOREACH(t, &tda->tda_transports, s_active_link) - if(t->s_dvb_mux_instance == tda->tda_current_tdmi && - t->s_status == SERVICE_RUNNING ) { - pthread_mutex_lock(&t->s_stream_mutex); - streaming_pad_deliver(&t->s_streaming_pad, &sm); - pthread_mutex_unlock(&t->s_stream_mutex); - } - + LIST_FOREACH(t, &tda->tda_transports, s_active_link) { + pthread_mutex_lock(&t->s_stream_mutex); + streaming_pad_deliver(&t->s_streaming_pad, &sm); + pthread_mutex_unlock(&t->s_stream_mutex); + } } @@ -270,7 +269,7 @@ dvb_fe_stop(th_dvb_adapter_t *tda, int retune) if(dm->dm_table_initial) { dm->dm_table_initial = 0; dm->dm_dn->dn_initial_num_mux--; - dvb_mux_save(dm->dm_tdmi); + dvb_mux_save(dm); } dvb_table_flush_all(dm); @@ -395,10 +394,10 @@ dvb_fe_tune_s2(th_dvb_mux_instance_t *tdmi, dvb_mux_conf_t *dmc) int dvb_fe_tune(dvb_mux_t *dm, const char *reason) { - th_dvb_adapter_t *tda = dm->dm_tdmi->tdmi_adapter; dvb_network_t *dn = dm->dm_dn; - th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; + th_dvb_mux_instance_t *tdmi = NULL; // dm->dm_tdmi; + th_dvb_adapter_t *tda = tdmi->tdmi_adapter; // copy dmc, cause frequency may be change with FE_QPSK dvb_mux_conf_t dmc = dm->dm_conf; @@ -475,7 +474,7 @@ dvb_fe_tune(dvb_mux_t *dm, const char *reason) tvhlog(LOG_ERR, "dvb", "diseqc setup failed %d\n", r); } - dvb_mux_nicename(buf, sizeof(buf), tdmi); + dvb_mux_nicename(buf, sizeof(buf), tdmi->tdmi_mux); tda->tda_fe_monitor_hold = 4; @@ -507,9 +506,9 @@ dvb_fe_tune(dvb_mux_t *dm, const char *reason) } /* Mark as bad */ - dvb_mux_set_enable(tdmi, 0); + tdmi->tdmi_tune_failed = 1; return SM_CODE_TUNING_FAILED; - } + } tda->tda_current_tdmi = tdmi; diff --git a/src/dvb/dvb_input_filtered.c b/src/dvb/dvb_input_filtered.c index 2943e4e1..68abf7bf 100644 --- a/src/dvb/dvb_input_filtered.c +++ b/src/dvb/dvb_input_filtered.c @@ -59,7 +59,7 @@ open_service(th_dvb_adapter_t *tda, service_t *s) st->es_demuxer_fd = -1; tvhlog(LOG_ERR, "dvb", "\"%s\" unable to open demuxer \"%s\" for pid %d -- %s", - s->s_identifier, tda->tda_demux_path, + s->s_uuid, tda->tda_demux_path, st->es_pid, strerror(errno)); continue; } @@ -74,7 +74,7 @@ open_service(th_dvb_adapter_t *tda, service_t *s) if(ioctl(fd, DMX_SET_PES_FILTER, &dmx_param)) { tvhlog(LOG_ERR, "dvb", "\"%s\" unable to configure demuxer \"%s\" for pid %d -- %s", - s->s_identifier, tda->tda_demux_path, + s->s_uuid, tda->tda_demux_path, st->es_pid, strerror(errno)); close(fd); fd = -1; diff --git a/src/dvb/dvb_multiplex.c b/src/dvb/dvb_multiplex.c index c3e1d096..69424837 100644 --- a/src/dvb/dvb_multiplex.c +++ b/src/dvb/dvb_multiplex.c @@ -58,9 +58,6 @@ static struct strtab muxfestatustab[] = { { "OK", TDMI_FE_OK }, }; -static void tdmi_set_enable(th_dvb_mux_instance_t *tdmi, int enabled); - - /** * */ @@ -87,18 +84,8 @@ dvb_mux_status(th_dvb_mux_instance_t *tdmi) * */ static int -tdmi_global_cmp(th_dvb_mux_instance_t *a, th_dvb_mux_instance_t *b) -{ - return strcmp(a->tdmi_identifier, b->tdmi_identifier); -} - - -/** - * - */ -static int -tdmi_compare_key(const struct dvb_mux_conf *a, - const struct dvb_mux_conf *b) +dmc_compare_key(const struct dvb_mux_conf *a, + const struct dvb_mux_conf *b) { int32_t fd = (int32_t)a->dmc_fe_params.frequency - (int32_t)b->dmc_fe_params.frequency; @@ -112,9 +99,9 @@ tdmi_compare_key(const struct dvb_mux_conf *a, * Return 0 if configuration does not differ. return 1 if it does */ static int -tdmi_compare_conf(int adapter_type, - const struct dvb_mux_conf *a, - const struct dvb_mux_conf *b) +dcm_compare_conf(int adapter_type, + const struct dvb_mux_conf *a, + const struct dvb_mux_conf *b) { switch(adapter_type) { case FE_OFDM: @@ -146,60 +133,60 @@ tdmi_compare_conf(int adapter_type, /** * Create a new mux on the given adapter, return NULL if it already exists */ -th_dvb_mux_instance_t * -dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc, - uint16_t onid, uint16_t tsid, const char *network, const char *source, - int enabled, int initialscan, const char *identifier) +dvb_mux_t * +dvb_mux_create(dvb_network_t *dn, const struct dvb_mux_conf *dmc, + uint16_t onid, uint16_t tsid, const char *network, + const char *source, int enabled, int initialscan, + const char *uuid) { - dvb_network_t *dn = tda->tda_dn; - th_dvb_mux_instance_t *tdmi, *c; - char buf[200]; + dvb_mux_t *dm; lock_assert(&global_lock); /* HACK - we hash/compare based on 2KHz spacing and compare on +/-500Hz */ - LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) { - if(tdmi_compare_key(&tdmi->tdmi_mux->dm_conf, dmc)) + LIST_FOREACH(dm, &dn->dn_muxes, dm_network_link) { + if(dmc_compare_key(&dm->dm_conf, dmc)) break; /* Mux already exist */ } - if(tdmi != NULL) { + if(dm != NULL) { /* Update stuff ... */ int save = 0; char buf2[1024]; buf2[0] = 0; - if(tdmi_compare_conf(tda->tda_fe_type, &tdmi->tdmi_mux->dm_conf, dmc)) { + if(dcm_compare_conf(dn->dn_fe_type, &dm->dm_conf, dmc)) { #if DVB_API_VERSION >= 5 snprintf(buf2, sizeof(buf2), " ("); - if (tdmi->tdmi_mux->dm_conf.dmc_fe_modulation != dmc->dmc_fe_modulation) + if (dm->dm_conf.dmc_fe_modulation != dmc->dmc_fe_modulation) sprintf(buf2, "%s %s->%s, ", buf2, - dvb_mux_qam2str(tdmi->tdmi_mux->dm_conf.dmc_fe_modulation), + dvb_mux_qam2str(dm->dm_conf.dmc_fe_modulation), dvb_mux_qam2str(dmc->dmc_fe_modulation)); - if (tdmi->tdmi_mux->dm_conf.dmc_fe_delsys != dmc->dmc_fe_delsys) + if (dm->dm_conf.dmc_fe_delsys != dmc->dmc_fe_delsys) sprintf(buf2, "%s %s->%s, ", buf2, - dvb_mux_delsys2str(tdmi->tdmi_mux->dm_conf.dmc_fe_delsys), + dvb_mux_delsys2str(dm->dm_conf.dmc_fe_delsys), dvb_mux_delsys2str(dmc->dmc_fe_delsys)); - if (tdmi->tdmi_mux->dm_conf.dmc_fe_rolloff != dmc->dmc_fe_rolloff) + if (dm->dm_conf.dmc_fe_rolloff != dmc->dmc_fe_rolloff) sprintf(buf2, "%s %s->%s, ", buf2, - dvb_mux_rolloff2str(tdmi->tdmi_mux->dm_conf.dmc_fe_rolloff), + dvb_mux_rolloff2str(dm->dm_conf.dmc_fe_rolloff), dvb_mux_rolloff2str(dmc->dmc_fe_rolloff)); sprintf(buf2, "%s)", buf2); #endif - memcpy(&tdmi->tdmi_mux->dm_conf, dmc, sizeof(struct dvb_mux_conf)); + memcpy(&dm->dm_conf, dmc, sizeof(struct dvb_mux_conf)); save = 1; } - if(tsid != 0xFFFF && tdmi->tdmi_mux->dm_transport_stream_id != tsid) { - tdmi->tdmi_mux->dm_transport_stream_id = tsid; + if(tsid != 0xFFFF && dm->dm_transport_stream_id != tsid) { + dm->dm_transport_stream_id = tsid; save = 1; } - if(onid && tdmi->tdmi_mux->dm_network_id != onid) { - tdmi->tdmi_mux->dm_network_id = onid; + if(onid && dm->dm_network_id != onid) { + dm->dm_network_id = onid; save = 1; } +#if 0 // XXX(dvbreorg) /* HACK - load old transports and remove old mux config */ if(identifier) { save = 1; @@ -207,20 +194,22 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc, hts_settings_remove("dvbmuxes/%s/%s", tda->tda_identifier, identifier); } +#endif if(save) { - dvb_mux_save(tdmi); - dvb_mux_nicename(buf, sizeof(buf), tdmi); + char buf[128]; + dvb_mux_save(dm); + dvb_mux_nicename(buf, sizeof(buf), dm); tvhlog(LOG_DEBUG, "dvb", "Configuration for mux \"%s\" updated by %s%s", buf, source, buf2); - dvb_mux_notify(tdmi); + dvb_mux_notify(dm); } return NULL; } - dvb_mux_t *dm = calloc(1, sizeof(dvb_mux_t)); + dm = calloc(1, sizeof(dvb_mux_t)); dm->dm_network_id = onid; dm->dm_transport_stream_id = tsid; @@ -228,103 +217,67 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc, TAILQ_INIT(&dm->dm_epg_grab); TAILQ_INIT(&dm->dm_table_queue); - dm->dm_dn = tda->tda_dn; - LIST_INSERT_HEAD(&tda->tda_dn->dn_muxes, dm, dm_network_link); + dm->dm_dn = dn; + LIST_INSERT_HEAD(&dn->dn_muxes, dm, dm_network_link); - tdmi = calloc(1, sizeof(th_dvb_mux_instance_t)); - tdmi->tdmi_mux = dm; - dm->dm_tdmi = tdmi; + char identifier[128]; + snprintf(identifier, sizeof(identifier), + "%d%s", dmc->dmc_fe_params.frequency, + dn->dn_fe_type == FE_QPSK ? + dvb_polarisation_to_str(dmc->dmc_polarisation) : ""); + dm->dm_local_identifier = strdup(identifier); - if(identifier == NULL) { - char qpsktxt[20]; - - if(tda->tda_sat) - snprintf(qpsktxt, sizeof(qpsktxt), "_%s", - dvb_polarisation_to_str(dmc->dmc_polarisation)); - else - qpsktxt[0] = 0; - - snprintf(buf, sizeof(buf), "%s%d%s", - tda->tda_identifier, dmc->dmc_fe_params.frequency, qpsktxt); - tdmi->tdmi_identifier = strdup(buf); - } else { - tdmi->tdmi_identifier = strdup(identifier); - } + dm->dm_enabled = enabled; - c = RB_INSERT_SORTED(&dvb_muxes, tdmi, tdmi_global_link, tdmi_global_cmp); + memcpy(&dm->dm_conf, dmc, sizeof(struct dvb_mux_conf)); - if(c != NULL) { - /* Global identifier collision, not good, not good at all */ - - tvhlog(LOG_ERR, "dvb", - "Multiple DVB multiplexes with same identifier \"%s\" " - "one is skipped", tdmi->tdmi_identifier); - free(tdmi->tdmi_identifier); - free(tdmi); - return NULL; - } - - - tdmi->tdmi_enabled = enabled; - - - - tdmi->tdmi_adapter = tda; - tdmi->tdmi_quality = 100; - - memcpy(&tdmi->tdmi_mux->dm_conf, dmc, sizeof(struct dvb_mux_conf)); - - LIST_INSERT_HEAD(&tda->tda_dn->dn_mux_instances, tdmi, tdmi_adapter_link); dm->dm_table_initial = initialscan; if(source != NULL) { - dvb_mux_nicename(buf, sizeof(buf), tdmi); + char buf[128]; + dvb_mux_nicename(buf, sizeof(buf), dm); tvhlog(LOG_NOTICE, "dvb", "New mux \"%s\" created by %s", buf, source); - dvb_mux_save(tdmi); - dvb_adapter_notify(tda); + dvb_mux_save(dm); } - dvb_service_load(tdmi, identifier); - dvb_mux_notify(tdmi); + dvb_service_load(dm); if(enabled && dm->dm_table_initial) { dn->dn_initial_num_mux++; mux_link_initial(dn, dm); } - return tdmi; + return dm; } + +/** + * + */ +void +dvb_tdmi_destroy(th_dvb_mux_instance_t *tdmi) +{ + LIST_REMOVE(tdmi, tdmi_mux_link); + LIST_REMOVE(tdmi, tdmi_adapter_link); + free(tdmi); +} + + /** * Destroy a DVB mux (it might come back by itself very soon though :) */ void -dvb_mux_destroy(th_dvb_mux_instance_t *tdmi) +dvb_mux_destroy(dvb_mux_t *dm) { - th_dvb_adapter_t *tda = tdmi->tdmi_adapter; - dvb_mux_t *dm = tdmi->tdmi_mux; - service_t *t; + th_dvb_mux_instance_t *tdmi; lock_assert(&global_lock); - - hts_settings_remove("dvbmuxes/%s/%s", - tda->tda_identifier, tdmi->tdmi_identifier); - while((t = LIST_FIRST(&tdmi->tdmi_mux->dm_services)) != NULL) { - hts_settings_remove("dvbtransports/%s/%s", - t->s_dvb_mux_instance->tdmi_identifier, - t->s_identifier); - service_destroy(t); - } + LIST_REMOVE(dm, dm_network_link); - dvb_service_notify_by_adapter(tda); - - if(tda->tda_current_tdmi == tdmi) - dvb_fe_stop(tda, 0); - - RB_REMOVE(&dvb_muxes, tdmi, tdmi_global_link); - LIST_REMOVE(tdmi, tdmi_adapter_link); + while((tdmi = LIST_FIRST(&dm->dm_tdmis)) != NULL) + dvb_tdmi_destroy(tdmi); if(dm->dm_scan_queue != NULL) TAILQ_REMOVE(dm->dm_scan_queue, dm, dm_scan_link); @@ -334,28 +287,9 @@ dvb_mux_destroy(th_dvb_mux_instance_t *tdmi) epggrab_mux_delete(dm); - hts_settings_remove("dvbmuxes/%s", tdmi->tdmi_identifier); - - // free(tdmi->tdmi_network_name); // XXX(dvbreorg) - free(tdmi->tdmi_identifier); - free(tdmi); - - dvb_adapter_notify(tda); -} - - -/** - * - */ -th_dvb_mux_instance_t * -dvb_mux_find_by_identifier(const char *identifier) -{ - th_dvb_mux_instance_t skel; - - lock_assert(&global_lock); - - skel.tdmi_identifier = (char *)identifier; - return RB_FIND(&dvb_muxes, &skel, tdmi_global_link, tdmi_global_cmp); + free(dm->dm_local_identifier); + free(dm->dm_uuid); + free(dm); } @@ -542,30 +476,28 @@ int dvb_mux_str2hier(const char *str) * */ void -dvb_mux_save(th_dvb_mux_instance_t *tdmi) +dvb_mux_save(dvb_mux_t *dm) { - const dvb_mux_conf_t *dmc = &tdmi->tdmi_mux->dm_conf; + const dvb_mux_conf_t *dmc = &dm->dm_conf; const struct dvb_frontend_parameters *f = &dmc->dmc_fe_params; htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_u32(m, "quality", tdmi->tdmi_adapter->tda_qmon ? tdmi->tdmi_quality : 100); - htsmsg_add_u32(m, "enabled", tdmi->tdmi_enabled); - htsmsg_add_str(m, "status", dvb_mux_status(tdmi)); + htsmsg_add_u32(m, "enabled", dm->dm_enabled); - htsmsg_add_u32(m, "transportstreamid", tdmi->tdmi_mux->dm_transport_stream_id); - htsmsg_add_u32(m, "originalnetworkid", tdmi->tdmi_mux->dm_network_id); - if(tdmi->tdmi_mux->dm_network_name != NULL) - htsmsg_add_str(m, "network", tdmi->tdmi_mux->dm_network_name); + htsmsg_add_u32(m, "transportstreamid", dm->dm_transport_stream_id); + htsmsg_add_u32(m, "originalnetworkid", dm->dm_network_id); + if(dm->dm_network_name != NULL) + htsmsg_add_str(m, "network", dm->dm_network_name); htsmsg_add_u32(m, "frequency", f->frequency); - htsmsg_add_u32(m, "initialscan", tdmi->tdmi_mux->dm_table_initial); + htsmsg_add_u32(m, "initialscan", dm->dm_table_initial); - if(tdmi->tdmi_mux->dm_default_authority) - htsmsg_add_str(m, "default_authority", tdmi->tdmi_mux->dm_default_authority); + if(dm->dm_default_authority) + htsmsg_add_str(m, "default_authority", dm->dm_default_authority); - switch(tdmi->tdmi_adapter->tda_fe_type) { + switch(dm->dm_dn->dn_fe_type) { case FE_OFDM: htsmsg_add_str(m, "bandwidth", val2str(f->u.ofdm.bandwidth, bwtab)); @@ -626,31 +558,30 @@ dvb_mux_save(th_dvb_mux_instance_t *tdmi) break; } - hts_settings_save(m, "dvbmuxes/%s/%s", - tdmi->tdmi_adapter->tda_identifier, tdmi->tdmi_identifier); + hts_settings_save(m, "dvb/networks/%s/muxes/%s/config", + dm->dm_dn->dn_uuid, + dm->dm_local_identifier); + htsmsg_destroy(m); } - /** * */ static const char * -tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m, const char *identifier) +dvb_mux_create_by_msg(dvb_network_t *dn, htsmsg_t *m, const char *fname) { - th_dvb_mux_instance_t *tdmi; + dvb_mux_t *dm; struct dvb_mux_conf dmc; const char *s; int r; - unsigned int onid, tsid, u32, enabled, initscan; + unsigned int onid, tsid, enabled, initscan; memset(&dmc, 0, sizeof(dmc)); - dmc.dmc_fe_params.inversion = INVERSION_AUTO; htsmsg_get_u32(m, "frequency", &dmc.dmc_fe_params.frequency); - - switch(tda->tda_fe_type) { + switch(dn->dn_fe_type) { case FE_OFDM: s = htsmsg_get_str(m, "bandwidth"); if(s == NULL || (r = str2val(s, bwtab)) < 0) @@ -764,48 +695,43 @@ tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m, const char *identifier) enabled = 1; initscan = htsmsg_get_u32_or_default(m, "initialscan", 0); - tdmi = dvb_mux_create(tda, &dmc, - onid, tsid, htsmsg_get_str(m, "network"), NULL, enabled, - initscan, - identifier); - if(tdmi != NULL) { - - if((s = htsmsg_get_str(m, "status")) != NULL) - tdmi->tdmi_fe_status = str2val(s, muxfestatustab); - - if(tda->tda_qmon && !htsmsg_get_u32(m, "quality", &u32)) - tdmi->tdmi_quality = u32; + dm = dvb_mux_create(dn, &dmc, + onid, tsid, htsmsg_get_str(m, "network"), NULL, enabled, + initscan, + htsmsg_get_str(m, "uuid")); + if(dm != NULL) { if((s = htsmsg_get_str(m, "default_authority"))) - tdmi->tdmi_mux->dm_default_authority = strdup(s); + dm->dm_default_authority = strdup(s); } return NULL; } - /** * */ void -dvb_mux_load(th_dvb_adapter_t *tda) +dvb_mux_load(dvb_network_t *dn) { htsmsg_t *l, *c; htsmsg_field_t *f; - if((l = hts_settings_load("dvbmuxes/%s", tda->tda_identifier)) == NULL) + if((l = hts_settings_load_r(1, "dvb/networks/%s/muxes", + dn->dn_uuid)) == NULL) return; - + HTSMSG_FOREACH(f, l) { if((c = htsmsg_get_map_by_field(f)) == NULL) continue; - - tdmi_create_by_msg(tda, c, f->hmf_name); + + dvb_mux_create_by_msg(dn, c, f->hmf_name); } htsmsg_destroy(l); } + /** * */ @@ -817,13 +743,11 @@ dvb_mux_set_networkname(dvb_mux_t *dm, const char *networkname) free(dm->dm_network_name); dm->dm_network_name = strdup(networkname); - th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; - - dvb_mux_save(tdmi); + dvb_mux_save(dm); m = htsmsg_create_map(); - htsmsg_add_str(m, "id", tdmi->tdmi_identifier); - htsmsg_add_str(m, "network", tdmi->tdmi_mux->dm_network_name ?: ""); + htsmsg_add_str(m, "id", dm->dm_local_identifier); + htsmsg_add_str(m, "network", dm->dm_network_name ?: ""); notify_by_msg("dvbMux", m); } @@ -838,13 +762,11 @@ dvb_mux_set_tsid(dvb_mux_t *dm, uint16_t tsid) dm->dm_transport_stream_id = tsid; - th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; - - dvb_mux_save(tdmi); + dvb_mux_save(dm); m = htsmsg_create_map(); - htsmsg_add_str(m, "id", tdmi->tdmi_identifier); - htsmsg_add_u32(m, "muxid", tdmi->tdmi_mux->dm_transport_stream_id); + htsmsg_add_str(m, "uuid", dm->dm_uuid); + htsmsg_add_u32(m, "muxid", dm->dm_transport_stream_id); notify_by_msg("dvbMux", m); } @@ -858,17 +780,15 @@ dvb_mux_set_onid(dvb_mux_t *dm, uint16_t onid) dm->dm_network_id = onid; - th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; - - dvb_mux_save(tdmi); + dvb_mux_save(dm); m = htsmsg_create_map(); - htsmsg_add_str(m, "id", tdmi->tdmi_identifier); - htsmsg_add_u32(m, "onid", tdmi->tdmi_mux->dm_network_id); + htsmsg_add_str(m, "uuid", dm->dm_uuid); + htsmsg_add_u32(m, "onid", dm->dm_network_id); notify_by_msg("dvbMux", m); } - +#if 0 /** * */ @@ -909,8 +829,9 @@ dvb_mux_set_enable(th_dvb_mux_instance_t *tdmi, int enabled) tdmi_set_enable(tdmi, enabled); dvb_mux_save(tdmi); } +#endif - +#if 0 /** * */ @@ -942,17 +863,18 @@ dvb_mux_fe_status(char *buf, size_t size, th_dvb_mux_instance_t *tdmi) break; } } +#endif /** * */ static void -dvb_mux_modulation(char *buf, size_t size, th_dvb_mux_instance_t *tdmi) +dvb_mux_modulation(char *buf, size_t size, const dvb_mux_t *dm) { - const dvb_mux_conf_t *dmc = &tdmi->tdmi_mux->dm_conf; + const dvb_mux_conf_t *dmc = &dm->dm_conf; const struct dvb_frontend_parameters *f = &dmc->dmc_fe_params; - switch(tdmi->tdmi_adapter->tda_fe_type) { + switch(dm->dm_dn->dn_fe_type) { case FE_OFDM: snprintf(buf, size, "%s, %s, %s-mode", val2str(f->u.ofdm.constellation, qamtab), @@ -990,37 +912,32 @@ dvb_mux_modulation(char *buf, size_t size, th_dvb_mux_instance_t *tdmi) * */ htsmsg_t * -dvb_mux_build_msg(th_dvb_mux_instance_t *tdmi) +dvb_mux_build_msg(dvb_mux_t *dm) { htsmsg_t *m = htsmsg_create_map(); char buf[100]; - htsmsg_add_str(m, "id", tdmi->tdmi_identifier); - htsmsg_add_u32(m, "enabled", tdmi->tdmi_enabled); - htsmsg_add_str(m, "network", tdmi->tdmi_mux->dm_network_name ?: ""); + htsmsg_add_str(m, "uuid", dm->dm_uuid); + htsmsg_add_u32(m, "enabled", dm->dm_enabled); + htsmsg_add_str(m, "network", dm->dm_network_name ?: ""); - dvb_mux_nicefreq(buf, sizeof(buf), tdmi->tdmi_mux); + dvb_mux_nicefreq(buf, sizeof(buf), dm); htsmsg_add_str(m, "freq", buf); - dvb_mux_modulation(buf, sizeof(buf), tdmi); + dvb_mux_modulation(buf, sizeof(buf), dm); htsmsg_add_str(m, "mod", buf); - dvb_mux_fe_status(buf, sizeof(buf), tdmi); - htsmsg_add_str(m, "fe_status", buf); + const dvb_mux_conf_t *dmc = &dm->dm_conf; - const dvb_mux_conf_t *dmc = &tdmi->tdmi_mux->dm_conf; - - - htsmsg_add_str(m, "pol", + htsmsg_add_str(m, "pol", dvb_polarisation_to_str_long(dmc->dmc_polarisation)); - if(tdmi->tdmi_mux->dm_transport_stream_id != 0xffff) - htsmsg_add_u32(m, "muxid", tdmi->tdmi_mux->dm_transport_stream_id); + if(dm->dm_transport_stream_id != 0xffff) + htsmsg_add_u32(m, "muxid", dm->dm_transport_stream_id); - if(tdmi->tdmi_mux->dm_network_id) - htsmsg_add_u32(m, "onid", tdmi->tdmi_mux->dm_network_id); + if(dm->dm_network_id) + htsmsg_add_u32(m, "onid", dm->dm_network_id); - htsmsg_add_u32(m, "quality", tdmi->tdmi_quality); return m; } @@ -1029,9 +946,9 @@ dvb_mux_build_msg(th_dvb_mux_instance_t *tdmi) * */ void -dvb_mux_notify(th_dvb_mux_instance_t *tdmi) +dvb_mux_notify(dvb_mux_t *dm) { - notify_by_msg("dvbMux", dvb_mux_build_msg(tdmi)); + // notify_by_msg("dvbMux", dvb_mux_build_msg(tdmi)); } @@ -1039,7 +956,7 @@ dvb_mux_notify(th_dvb_mux_instance_t *tdmi) * */ const char * -dvb_mux_add_by_params(th_dvb_adapter_t *tda, +dvb_mux_add_by_params(dvb_network_t *dn, int freq, int symrate, int bw, @@ -1054,13 +971,12 @@ dvb_mux_add_by_params(th_dvb_adapter_t *tda, int polarisation, const char *satconf) { - th_dvb_mux_instance_t *tdmi; struct dvb_mux_conf dmc; memset(&dmc, 0, sizeof(dmc)); dmc.dmc_fe_params.inversion = INVERSION_AUTO; - switch(tda->tda_fe_type) { + switch(dn->dn_fe_type) { case FE_OFDM: dmc.dmc_fe_params.frequency = freq * 1000; if(!val2str(bw, bwtab)) @@ -1146,14 +1062,14 @@ dvb_mux_add_by_params(th_dvb_adapter_t *tda, dmc.dmc_polarisation = polarisation; - tdmi = dvb_mux_create(tda, &dmc, 0, 0xffff, NULL, NULL, 1, 1, NULL); + dvb_mux_t *dm = dvb_mux_create(dn, &dmc, 0, 0xffff, NULL, NULL, 1, 1, NULL); - if(tdmi == NULL) + if(dm == NULL) return "Mux already exist"; return NULL; } - + #if 0 /** * @@ -1234,23 +1150,33 @@ dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src, } #endif -th_dvb_mux_instance_t *dvb_mux_find - ( th_dvb_adapter_t *tda, const char *netname, uint16_t onid, uint16_t tsid, - int enabled ) +dvb_mux_t * +dvb_mux_find(dvb_network_t *dn, const char *netname, uint16_t onid, + uint16_t tsid, int enabled) { - th_dvb_mux_instance_t *tdmi; - if (tda) { - LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) { - if (enabled && !tdmi->tdmi_enabled) continue; - if (onid && onid != tdmi->tdmi_mux->dm_network_id) continue; - if (tsid && tsid != tdmi->tdmi_mux->dm_transport_stream_id) continue; - if (netname && strcmp(netname, tdmi->tdmi_mux->dm_network_name ?: "")) continue; - return tdmi; + dvb_mux_t *dm; + + if(dn != NULL) { + LIST_FOREACH(dm, &dn->dn_muxes, dm_network_link) { + + if (enabled && !dm->dm_enabled) + continue; + + if (onid && onid != dm->dm_network_id) + continue; + + if (tsid && tsid != dm->dm_transport_stream_id) + continue; + + if (netname && strcmp(netname, dm->dm_network_name ?: "")) + continue; + return dm; } } else { - TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) - if ((tdmi = dvb_mux_find(tda, netname, onid, tsid, enabled))) - return tdmi; + dvb_network_t *dn; + LIST_FOREACH(dn, &dvb_networks, dn_global_link) + if ((dm = dvb_mux_find(dn, netname, onid, tsid, enabled))) + return dm; } return NULL; } diff --git a/src/dvb/dvb_network.c b/src/dvb/dvb_network.c index 9dd2239a..ed140fdb 100644 --- a/src/dvb/dvb_network.c +++ b/src/dvb/dvb_network.c @@ -21,7 +21,7 @@ #include "dvb.h" #include "epggrab.h" - +struct dvb_network_list dvb_networks; /** * @@ -33,9 +33,96 @@ dvb_network_create(int fe_type) dn->dn_fe_type = fe_type; TAILQ_INIT(&dn->dn_initial_scan_queue); gtimer_arm(&dn->dn_mux_scanner_timer, dvb_network_mux_scanner, dn, 1); + + dn->dn_autodiscovery = fe_type != FE_QPSK; + LIST_INSERT_HEAD(&dvb_networks, dn, dn_global_link); return dn; } +#if 0 + htsmsg_get_u32(c, "autodiscovery", &tda->tda_autodiscovery); + htsmsg_get_u32(c, "nitoid", &tda->tda_nitoid); + htsmsg_get_u32(c, "disable_pmt_monitor", &tda->tda_disable_pmt_monitor); +#endif + +#if 0 +/** + * + */ +static void +dvb_network_save(dvb_network_t *dn) +{ + htsmsg_t *m = htsmsg_create_map(); + + lock_assert(&global_lock); + + 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); + abort(); +} +#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 /** diff --git a/src/dvb/dvb_preconf.c b/src/dvb/dvb_preconf.c index 1dfb5234..bbcd3deb 100644 --- a/src/dvb/dvb_preconf.c +++ b/src/dvb/dvb_preconf.c @@ -35,7 +35,7 @@ * */ static void -dvb_mux_preconf_add(th_dvb_adapter_t *tda, const network_t *net, +dvb_mux_preconf_add(dvb_network_t *dn, const network_t *net, const char *source) { const mux_t *m; @@ -48,7 +48,7 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const network_t *net, dmc.dmc_fe_params.inversion = INVERSION_AUTO; dmc.dmc_fe_params.frequency = m->freq; - switch(tda->tda_fe_type) { + switch(dn->dn_fe_type) { case FE_OFDM: dmc.dmc_fe_params.u.ofdm.bandwidth = m->bw; dmc.dmc_fe_params.u.ofdm.constellation = m->constellation; @@ -96,7 +96,7 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const network_t *net, break; } - dvb_mux_create(tda, &dmc, 0, 0xffff, NULL, source, 1, 1, NULL); + dvb_mux_create(dn, &dmc, 0, 0xffff, NULL, source, 1, 1, NULL); } } @@ -105,7 +105,7 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const network_t *net, * */ int -dvb_mux_preconf_add_network(th_dvb_adapter_t *tda, const char *id) +dvb_mux_preconf_add_network(dvb_network_t *dn, const char *id) { region_list_t *list; const region_t *r; @@ -114,7 +114,7 @@ dvb_mux_preconf_add_network(th_dvb_adapter_t *tda, const char *id) snprintf(source, sizeof(source), "built-in configuration from \"%s\"", id); - switch(tda->tda_fe_type) { + switch(dn->dn_fe_type) { case FE_QAM: list = ®ions_DVBC; break; @@ -134,7 +134,7 @@ dvb_mux_preconf_add_network(th_dvb_adapter_t *tda, const char *id) LIST_FOREACH(r, list, link) { LIST_FOREACH(n, &r->networks, link) { if(!strcmp(n->id, id)) { - dvb_mux_preconf_add(tda, n, source); + dvb_mux_preconf_add(dn, n, source); break; } } diff --git a/src/dvb/dvb_preconf.h b/src/dvb/dvb_preconf.h index a76f3a7e..a3c14da3 100644 --- a/src/dvb/dvb_preconf.h +++ b/src/dvb/dvb_preconf.h @@ -23,6 +23,6 @@ htsmsg_t *dvb_mux_preconf_get_node(int fetype, const char *node); -int dvb_mux_preconf_add_network(th_dvb_adapter_t *tda, const char *id); +int dvb_mux_preconf_add_network(dvb_network_t *dn, const char *id); #endif /* DVB_MUXCONFIG_H */ diff --git a/src/dvb/dvb_service.c b/src/dvb/dvb_service.c index 2399e50d..e771d898 100644 --- a/src/dvb/dvb_service.c +++ b/src/dvb/dvb_service.c @@ -46,6 +46,14 @@ +/** + * + */ + + + + + /** * Switch the adapter (which is implicitly tied to our transport) @@ -57,6 +65,7 @@ static int dvb_service_start(service_t *t, unsigned int weight, int force_start) { +#if 0 int w, r; th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter; th_dvb_mux_instance_t *tdmi = tda->tda_current_tdmi; @@ -100,6 +109,8 @@ dvb_service_start(service_t *t, unsigned int weight, int force_start) dvb_table_add_pmt(t->s_dvb_mux_instance->tdmi_mux, t->s_pmt_pid); return r; +#endif + return SM_CODE_NO_HW_ATTACHED; } @@ -109,6 +120,7 @@ dvb_service_start(service_t *t, unsigned int weight, int force_start) static void dvb_service_stop(service_t *t) { +#if 0 th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter; lock_assert(&global_lock); @@ -120,6 +132,7 @@ dvb_service_stop(service_t *t) tda->tda_close_service(tda, t); t->s_status = SERVICE_IDLE; +#endif } @@ -129,10 +142,12 @@ dvb_service_stop(service_t *t) static void dvb_service_refresh(service_t *t) { +#if 0 th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter; lock_assert(&global_lock); tda->tda_open_service(tda, t); +#endif } @@ -165,7 +180,7 @@ dvb_service_save(service_t *t) if(t->s_dvb_charset != NULL) htsmsg_add_str(m, "dvb_charset", t->s_dvb_charset); - + htsmsg_add_u32(m, "dvb_eit_enable", t->s_dvb_eit_enable); if(t->s_default_authority) @@ -174,13 +189,15 @@ dvb_service_save(service_t *t) pthread_mutex_lock(&t->s_stream_mutex); psi_save_service_settings(m, t); pthread_mutex_unlock(&t->s_stream_mutex); - - hts_settings_save(m, "dvbtransports/%s/%s", - t->s_dvb_mux_instance->tdmi_identifier, - t->s_identifier); + + dvb_mux_t *dm = t->s_dvb_mux; + + hts_settings_save(m, "dvb/networks/%s/muxes/%s/services/%04x", + dm->dm_dn->dn_uuid, + dm->dm_local_identifier, + t->s_dvb_service_id); htsmsg_destroy(m); - dvb_service_notify(t); } @@ -188,7 +205,7 @@ dvb_service_save(service_t *t) * Load config for the given mux */ void -dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier) +dvb_service_load(dvb_mux_t *dm) { htsmsg_t *l, *c; htsmsg_field_t *f; @@ -196,19 +213,14 @@ dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier) const char *s; unsigned int u32; service_t *t; - int old; lock_assert(&global_lock); - /* HACK - use provided identifier to load config incase we've migrated - * mux freq */ - if (!tdmi_identifier) - tdmi_identifier = tdmi->tdmi_identifier; - old = strcmp(tdmi_identifier, tdmi->tdmi_identifier); - - if((l = hts_settings_load("dvbtransports/%s", tdmi_identifier)) == NULL) + l = hts_settings_load("dvb/networks/%s/muxes/%s/services", + dm->dm_dn->dn_uuid, dm->dm_local_identifier); + if(l == NULL) return; - + HTSMSG_FOREACH(f, l) { if((c = htsmsg_get_map_by_field(f)) == NULL) continue; @@ -218,8 +230,8 @@ dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier) if(htsmsg_get_u32(c, "pmt", &pmt)) continue; - - t = dvb_service_find(tdmi, sid, pmt, f->hmf_name); + + t = dvb_service_find(dm, sid, pmt, f->hmf_name); htsmsg_get_u32(c, "stype", &t->s_servicetype); if(htsmsg_get_u32(c, "scrambled", &u32)) @@ -258,39 +270,11 @@ dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier) if(s && u32) service_map_channel(t, channel_find_by_name(s, 1, 0), 0); - - /* HACK - force save for old config */ - if(old) - dvb_service_save(t); } - - /* HACK - remove old settings */ - if(old) { - HTSMSG_FOREACH(f, l) - hts_settings_remove("dvbtransports/%s/%s", tdmi_identifier, f->hmf_name); - hts_settings_remove("dvbtransports/%s", tdmi_identifier); - } - htsmsg_destroy(l); } -/** - * Called to get quality for the given transport - * - * We keep track of this for the entire mux (if we see errors), soo.. - * return that value - */ -static int -dvb_service_quality(service_t *t) -{ - th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance; - - lock_assert(&global_lock); - - return tdmi->tdmi_adapter->tda_qmon ? tdmi->tdmi_quality : 100; -} - /** * Generate a descriptive name for the source @@ -298,7 +282,7 @@ dvb_service_quality(service_t *t) static void dvb_service_setsourceinfo(service_t *t, struct source_info *si) { - th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance; + dvb_mux_t *dm = t->s_dvb_mux; char buf[100]; memset(si, 0, sizeof(struct source_info)); @@ -307,15 +291,10 @@ dvb_service_setsourceinfo(service_t *t, struct source_info *si) si->si_type = S_MPEG_TS; - if(tdmi->tdmi_adapter->tda_rootpath != NULL) - si->si_device = strdup(tdmi->tdmi_adapter->tda_rootpath); + if(dm->dm_network_name != NULL) + si->si_network = strdup(dm->dm_network_name); - si->si_adapter = strdup(tdmi->tdmi_adapter->tda_displayname); - - if(tdmi->tdmi_mux->dm_network_name != NULL) - si->si_network = strdup(tdmi->tdmi_mux->dm_network_name); - - dvb_mux_nicename(buf, sizeof(buf), tdmi); + dvb_mux_nicename(buf, sizeof(buf), dm); si->si_mux = strdup(buf); if(t->s_provider != NULL) @@ -335,36 +314,37 @@ dvb_grace_period(service_t *t) return 10; } + + /* * Find transport based on the DVB identification */ service_t * -dvb_service_find3 - (th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi, - const char *netname, uint16_t onid, uint16_t tsid, uint16_t sid, - int enabled, int epgprimary) +dvb_service_find3(dvb_network_t *dn, dvb_mux_t *dm, + const char *netname, uint16_t onid, uint16_t tsid, + uint16_t sid, int enabled, int epgprimary) { service_t *svc; - if (tdmi) { - LIST_FOREACH(svc, &tdmi->tdmi_mux->dm_services, s_group_link) { + if (dm != NULL) { + LIST_FOREACH(svc, &dm->dm_services, s_group_link) { if (enabled && !svc->s_enabled) continue; if (epgprimary && !service_is_primary_epg(svc)) continue; if (sid == svc->s_dvb_service_id) return svc; } - } else if (tda) { - LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) { - if (enabled && !tdmi->tdmi_enabled) continue; - if (onid && onid != tdmi->tdmi_mux->dm_network_id) continue; - if (tsid && tsid != tdmi->tdmi_mux->dm_transport_stream_id) continue; - if (netname && strcmp(netname, tdmi->tdmi_mux->dm_network_name ?: "")) continue; - if ((svc = dvb_service_find3(tda, tdmi, NULL, 0, 0, sid, - enabled, epgprimary))) + } else if (dn) { + LIST_FOREACH(dm, &dn->dn_muxes, dm_network_link) { + if (enabled && !dm->dm_enabled) continue; + if (onid && onid != dm->dm_network_id) continue; + if (tsid && tsid != dm->dm_transport_stream_id) continue; + if (netname && strcmp(netname, dm->dm_network_name ?: "")) continue; + if ((svc = dvb_service_find3(dn, dm, NULL, 0, 0, sid, + enabled, epgprimary))) return svc; } } else { - TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) - if ((svc = dvb_service_find3(tda, NULL, netname, onid, tsid, - sid, enabled, epgprimary))) + LIST_FOREACH(dn, &dvb_networks, dn_global_link) + if ((svc = dvb_service_find3(dn, NULL, netname, onid, tsid, + sid, enabled, epgprimary))) return svc; } return NULL; @@ -377,39 +357,36 @@ dvb_service_find3 * If it cannot be found we create it if 'pmt_pid' is also set */ service_t * -dvb_service_find(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, - const char *identifier) +dvb_service_find(dvb_mux_t *dm, uint16_t sid, int pmt_pid, const char *uuid) { - return dvb_service_find2(tdmi, sid, pmt_pid, identifier, NULL); + return dvb_service_find2(dm, sid, pmt_pid, uuid, NULL); } + +/** + * + */ service_t * -dvb_service_find2(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, - const char *identifier, int *save) +dvb_service_find2(dvb_mux_t *dm, uint16_t sid, int pmt_pid, + const char *uuid, int *save) { service_t *t; - char tmp[200]; char buf[200]; lock_assert(&global_lock); - LIST_FOREACH(t, &tdmi->tdmi_mux->dm_services, s_group_link) { + LIST_FOREACH(t, &dm->dm_services, s_group_link) { if(t->s_dvb_service_id == sid) return t; } - + if(pmt_pid == 0) return NULL; - if(identifier == NULL) { - snprintf(tmp, sizeof(tmp), "%s_%04x", tdmi->tdmi_identifier, sid); - identifier = tmp; - } + dvb_mux_nicename(buf, sizeof(buf), dm); + tvhlog(LOG_DEBUG, "dvb", "Add service \"0x%x\" on \"%s\"", sid, buf); - dvb_mux_nicename(buf, sizeof(buf), tdmi); - tvhlog(LOG_DEBUG, "dvb", "Add service \"%s\" on \"%s\"", identifier, buf); - - t = service_create(identifier, SERVICE_TYPE_DVB, S_MPEG_TS); + t = service_create(uuid, S_MPEG_TS); if (save) *save = 1; t->s_dvb_service_id = sid; @@ -420,17 +397,14 @@ dvb_service_find2(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, t->s_stop_feed = dvb_service_stop; t->s_config_save = dvb_service_save; t->s_setsourceinfo = dvb_service_setsourceinfo; - t->s_quality_index = dvb_service_quality; t->s_grace_period = dvb_grace_period; - t->s_dvb_mux_instance = tdmi; - LIST_INSERT_HEAD(&tdmi->tdmi_mux->dm_services, t, s_group_link); + t->s_dvb_mux = dm; + LIST_INSERT_HEAD(&dm->dm_services, t, s_group_link); pthread_mutex_lock(&t->s_stream_mutex); service_make_nicename(t); pthread_mutex_unlock(&t->s_stream_mutex); - - dvb_adapter_notify(tdmi->tdmi_adapter); return t; } @@ -441,11 +415,11 @@ dvb_service_find2(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, htsmsg_t * dvb_service_build_msg(service_t *t) { - th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance; + dvb_mux_t *dm = t->s_dvb_mux; htsmsg_t *m = htsmsg_create_map(); char buf[100]; - htsmsg_add_str(m, "id", t->s_identifier); + htsmsg_add_str(m, "uuid", t->s_uuid); htsmsg_add_u32(m, "enabled", t->s_enabled); htsmsg_add_u32(m, "channel", t->s_channel_number); @@ -458,9 +432,9 @@ dvb_service_build_msg(service_t *t) htsmsg_add_str(m, "svcname", t->s_svcname ?: ""); htsmsg_add_str(m, "provider", t->s_provider ?: ""); - htsmsg_add_str(m, "network", tdmi->tdmi_mux->dm_network_name ?: ""); + htsmsg_add_str(m, "network", dm->dm_network_name ?: ""); - dvb_mux_nicefreq(buf, sizeof(buf), tdmi->tdmi_mux); + dvb_mux_nicefreq(buf, sizeof(buf), dm); htsmsg_add_str(m, "mux", buf); if(t->s_ch != NULL) @@ -486,16 +460,3 @@ dvb_service_notify_by_adapter(th_dvb_adapter_t *tda) notify_by_msg("dvbService", m); } - -/** - * - */ -void -dvb_service_notify(service_t *t) -{ - th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance; - htsmsg_t *m = htsmsg_create_map(); - - htsmsg_add_str(m, "adapterId", tdmi->tdmi_adapter->tda_identifier); - notify_by_msg("dvbService", m); -} diff --git a/src/dvb/dvb_support.c b/src/dvb/dvb_support.c index 91a9bb2a..c40cc755 100644 --- a/src/dvb/dvb_support.c +++ b/src/dvb/dvb_support.c @@ -485,13 +485,12 @@ dvb_mux_nicefreq(char *buf, size_t size, const dvb_mux_t *dm) * */ void -dvb_mux_nicename(char *buf, size_t size, th_dvb_mux_instance_t *tdmi) +dvb_mux_nicename(char *buf, size_t size, dvb_mux_t *dm) { char freq[50]; - const dvb_mux_t *dm = tdmi->tdmi_mux; const char *n = dm->dm_network_name; - if(tdmi->tdmi_adapter->tda_fe_type == FE_QPSK) { + if(dm->dm_dn->dn_fe_type == FE_QPSK) { nicenum(freq, sizeof(freq), dm->dm_conf.dmc_fe_params.frequency); snprintf(buf, size, "%s%s%s kHz %s", n?:"", n ? ": ":"", freq, diff --git a/src/dvb/dvb_support.h b/src/dvb/dvb_support.h index 3d6aabe7..ab5ece28 100644 --- a/src/dvb/dvb_support.h +++ b/src/dvb/dvb_support.h @@ -79,7 +79,7 @@ const char *dvb_polarisation_to_str(int pol); const char *dvb_polarisation_to_str_long(int pol); th_dvb_adapter_t *dvb_adapter_find_by_identifier(const char *identifier); th_dvb_mux_instance_t *dvb_mux_find_by_identifier(const char *identifier); -void dvb_mux_nicename(char *buf, size_t size, th_dvb_mux_instance_t *tdmi); +void dvb_mux_nicename(char *buf, size_t size, dvb_mux_t *tdmi); int dvb_mux_badness(th_dvb_mux_instance_t *tdmi); const char *dvb_mux_status(th_dvb_mux_instance_t *tdmi); void dvb_mux_nicefreq(char *buf, size_t size, const dvb_mux_t *dm); diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index ff25f37d..6cd5e451 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -64,10 +64,10 @@ dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi) dm->dm_table_initial = 0; dn->dn_initial_num_mux--; - dvb_mux_save(tdmi); + dvb_mux_save(dm); - dvb_mux_nicename(buf, sizeof(buf), tdmi); + dvb_mux_nicename(buf, sizeof(buf), dm); tvhlog(LOG_DEBUG, "dvb", "\"%s\" initial scan completed for \"%s\"", tda->tda_rootpath, buf); dvb_network_mux_scanner(dn); @@ -164,7 +164,8 @@ tdt_add(dvb_mux_t *dm, int tableid, int mask, const char *name, int flags, int pid) { th_dvb_table_t *t; - th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; + th_dvb_mux_instance_t *tdmi = dm->dm_current_tdmi; + assert(tdmi != NULL); // Allow multiple entries per PID, but only one per callback/opaque instance // TODO: this could mean reading the same data multiple times, and not @@ -298,7 +299,7 @@ dvb_bat_callback(dvb_mux_t *dm, uint8_t *buf, int len, save = 1; } if (save) - dvb_mux_save(dm->dm_tdmi); + dvb_mux_save(dm); } i += tdlen; @@ -377,7 +378,7 @@ dvb_sdt_callback(dvb_mux_t *dm, uint8_t *ptr, int len, if(dllen > len) break; - if (!(t = dvb_service_find(dm->dm_tdmi, service_id, 0, NULL))) { + if (!(t = dvb_service_find(dm, service_id, 0, NULL))) { len -= dllen; ptr += dllen; continue; @@ -519,8 +520,8 @@ dvb_pat_callback(dvb_mux_t *dm, uint8_t *ptr, int len, if(service != 0 && pmt != 0) { int save = 0; - dvb_service_find2(dm->dm_tdmi, service, pmt, NULL, &save); - if (save || ! dm->dm_tdmi->tdmi_adapter->tda_disable_pmt_monitor) + dvb_service_find2(dm, service, pmt, NULL, &save); + if (save || ! dm->dm_dn->dn_disable_pmt_monitor) dvb_table_add_pmt(dm, pmt); } ptr += 4; @@ -623,7 +624,7 @@ dvb_table_cable_delivery(dvb_mux_t *dm, uint8_t *ptr, int len, struct dvb_mux_conf dmc; int freq, symrate; - if(!dm->dm_tdmi->tdmi_adapter->tda_autodiscovery) + if(!dm->dm_dn->dn_autodiscovery) return -1; if(len < 11) @@ -655,7 +656,7 @@ dvb_table_cable_delivery(dvb_mux_t *dm, uint8_t *ptr, int len, dmc.dmc_fe_params.u.qam.fec_inner = fec_tab[ptr[10] & 0x07]; - dvb_mux_create(dm->dm_tdmi->tdmi_adapter, &dmc, onid, tsid, NULL, + dvb_mux_create(dm->dm_dn, &dmc, onid, tsid, NULL, "automatic mux discovery", 1, 1, NULL); return 0; } @@ -671,7 +672,7 @@ dvb_table_sat_delivery(dvb_mux_t *dm, uint8_t *ptr, int len, // uint16_t orbital_pos; struct dvb_mux_conf dmc; - if(!dm->dm_tdmi->tdmi_adapter->tda_autodiscovery) + if(!dm->dm_dn->dn_autodiscovery) return -1; if(len < 11) @@ -738,7 +739,7 @@ dvb_table_sat_delivery(dvb_mux_t *dm, uint8_t *ptr, int len, } #endif - dvb_mux_create(dm->dm_tdmi->tdmi_adapter, &dmc, onid, tsid, NULL, + dvb_mux_create(dm->dm_dn, &dmc, onid, tsid, NULL, "automatic mux discovery", 1, 1, NULL); return 0; } @@ -767,7 +768,7 @@ dvb_table_local_channel(dvb_mux_t *dm, uint8_t *ptr, int len, chan = ((ptr[2] & 3) << 8) | ptr[3]; if(chan != 0) { - t = dvb_service_find(dm->dm_tdmi, sid, 0, NULL); + t = dvb_service_find(dm, sid, 0, NULL); if(t != NULL) { if(t->s_channel_number != chan) { @@ -797,11 +798,11 @@ dvb_nit_callback(dvb_mux_t *dm, uint8_t *ptr, int len, uint16_t tsid, onid; uint16_t network_id = (ptr[0] << 8) | ptr[1]; - if(dm->dm_tdmi->tdmi_adapter->tda_nitoid) { + if(dm->dm_dn->dn_nitoid) { if(tableid != 0x41) return -1; - if(network_id != dm->dm_tdmi->tdmi_adapter->tda_nitoid) + if(network_id != dm->dm_dn->dn_nitoid) return -1; } else { @@ -943,7 +944,7 @@ atsc_vct_callback(dvb_mux_t *dm, uint8_t *ptr, int len, continue; service_id = (ptr[24] << 8) | ptr[25]; - if((t = dvb_service_find(dm->dm_tdmi, service_id, 0, NULL)) == NULL) + if((t = dvb_service_find(dm, service_id, 0, NULL)) == NULL) continue; atsc_stype = ptr[27] & 0x3f; @@ -987,18 +988,18 @@ dvb_pmt_callback(dvb_mux_t *dm, uint8_t *ptr, int len, int active = 0; service_t *t; th_dvb_table_t *tdt = opaque; - th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; - LIST_FOREACH(t, &tdmi->tdmi_mux->dm_services, s_group_link) { + LIST_FOREACH(t, &dm->dm_services, s_group_link) { pthread_mutex_lock(&t->s_stream_mutex); psi_parse_pmt(t, ptr, len, 1, 1); if (t->s_pmt_pid == tdt->tdt_pid && t->s_status == SERVICE_RUNNING) active = 1; pthread_mutex_unlock(&t->s_stream_mutex); } - - if (tdmi->tdmi_adapter->tda_disable_pmt_monitor && !active) - dvb_tdt_destroy(tdmi->tdmi_adapter, tdmi, tdt); + + if (dm->dm_dn->dn_disable_pmt_monitor && !active) + dvb_tdt_destroy(dm->dm_current_tdmi->tdmi_adapter, + dm->dm_current_tdmi, tdt); return 0; } @@ -1014,7 +1015,7 @@ dvb_table_add_default_dvb(dvb_mux_t *dm) int table; - if(dm->dm_tdmi->tdmi_adapter->tda_nitoid) { + if(dm->dm_dn->dn_nitoid) { table = 0x41; } else { table = 0x40; @@ -1095,7 +1096,7 @@ dvb_table_add_pmt(dvb_mux_t *dm, int pmt_pid) void dvb_table_rem_pmt(dvb_mux_t *dm, int pmt_pid) { - th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; + th_dvb_mux_instance_t *tdmi = dm->dm_current_tdmi; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; th_dvb_table_t *tdt = NULL; LIST_FOREACH(tdt, &dm->dm_tables, tdt_link) @@ -1112,10 +1113,10 @@ dvb_table_rem_pmt(dvb_mux_t *dm, int pmt_pid) void dvb_table_flush_all(dvb_mux_t *dm) { - th_dvb_adapter_t *tda = dm->dm_tdmi->tdmi_adapter; + th_dvb_mux_instance_t *tdmi = dm->dm_current_tdmi; + th_dvb_adapter_t *tda = tdmi->tdmi_adapter; th_dvb_table_t *tdt; while((tdt = LIST_FIRST(&dm->dm_tables)) != NULL) - dvb_tdt_destroy(tda, dm->dm_tdmi, tdt); - + dvb_tdt_destroy(tda, tdmi, tdt); } diff --git a/src/epggrab/module/eit.c b/src/epggrab/module/eit.c index a2663af6..f19c447a 100644 --- a/src/epggrab/module/eit.c +++ b/src/epggrab/module/eit.c @@ -475,7 +475,7 @@ static int _eit_desc_crid } else { char *defauth = svc->s_default_authority; if (!defauth) - defauth = svc->s_dvb_mux_instance->tdmi_mux->dm_default_authority; + defauth = svc->s_dvb_mux->dm_default_authority; if (defauth) snprintf(crid, clen, "crid://%s%s", defauth, buf); } @@ -544,8 +544,8 @@ static int _eit_process_event /* Override */ if (!ev.default_charset) { ev.default_charset - = dvb_charset_find(svc->s_dvb_mux_instance->tdmi_mux->dm_network_id, - svc->s_dvb_mux_instance->tdmi_mux->dm_transport_stream_id, + = dvb_charset_find(svc->s_dvb_mux->dm_network_id, + svc->s_dvb_mux->dm_transport_stream_id, svc->s_dvb_service_id); } @@ -660,7 +660,6 @@ _eit_callback(dvb_mux_t *dm, uint8_t *ptr, int len, { epggrab_module_t *mod = opaque; epggrab_ota_mux_t *ota; - th_dvb_adapter_t *tda; service_t *svc; eit_status_t *sta; eit_table_status_t *tsta; @@ -713,9 +712,7 @@ _eit_callback(dvb_mux_t *dm, uint8_t *ptr, int len, // Note: tableid=0x4f,0x60-0x6f is other TS // so must find the tdmi if(tableid == 0x4f || tableid >= 0x60) { - tda = dm->dm_tdmi->tdmi_adapter; - th_dvb_mux_instance_t *tdmi = dvb_mux_find(tda, NULL, onid, tsid, 1); - dm = tdmi->tdmi_mux; + dm = dvb_mux_find(dm->dm_dn, NULL, onid, tsid, 1); } else { if (dm->dm_transport_stream_id != tsid || @@ -732,7 +729,7 @@ _eit_callback(dvb_mux_t *dm, uint8_t *ptr, int len, if(!dm) goto done; /* Get service */ - svc = dvb_service_find3(NULL, dm->dm_tdmi, NULL, 0, 0, sid, 1, 1); + svc = dvb_service_find3(NULL, dm, NULL, 0, 0, sid, 1, 1); if (!svc || !svc->s_ch) goto done; /* Register as interesting */ diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index 93e4431d..b02e17fc 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -254,12 +254,11 @@ void epggrab_ota_create_and_register_by_id ( epggrab_module_ota_t *mod, int onid, int tsid, int period, int interval, const char *networkname ) { - th_dvb_adapter_t *tda; - th_dvb_mux_instance_t *tdmi; + dvb_network_t *dn; + dvb_mux_t *dm; epggrab_ota_mux_t *ota; - TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) { - LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) { - dvb_mux_t *dm = tdmi->tdmi_mux; + LIST_FOREACH(dn, &dvb_networks, dn_global_link) { + LIST_FOREACH(dm, &dn->dn_muxes, dm_network_link) { if (dm->dm_transport_stream_id != tsid) continue; if (onid && dm->dm_network_id != onid) continue; if (networkname && (!dm->dm_network_name || diff --git a/src/iptv_input.c b/src/iptv_input.c index 314e5b59..8705e71d 100644 --- a/src/iptv_input.c +++ b/src/iptv_input.c @@ -227,7 +227,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start) fd = tvh_socket(AF_INET6, SOCK_DGRAM, 0); } if(fd == -1) { - tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot open socket", t->s_identifier); + tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot open socket", t->s_uuid); return -1; } @@ -237,7 +237,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start) ifr.ifr_name[IFNAMSIZ - 1] = 0; if(ioctl(fd, SIOCGIFINDEX, &ifr)) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot find interface %s", - t->s_identifier, t->s_iptv_iface); + t->s_uuid, t->s_iptv_iface); close(fd); return -1; } @@ -251,7 +251,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &m, sizeof(struct ip_mreqn)); if(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot bind %s:%d -- %s", - t->s_identifier, inet_ntoa(sin.sin_addr), t->s_iptv_port, + t->s_uuid, inet_ntoa(sin.sin_addr), t->s_iptv_port, strerror(errno)); close(fd); return -1; @@ -265,7 +265,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start) if(setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &m, sizeof(struct ip_mreqn)) == -1) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot join %s -- %s", - t->s_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno)); + t->s_uuid, inet_ntoa(m.imr_multiaddr), strerror(errno)); close(fd); return -1; } @@ -279,7 +279,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start) if(bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) == -1) { inet_ntop(AF_INET6, &sin6.sin6_addr, straddr, sizeof(straddr)); tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot bind %s:%d -- %s", - t->s_identifier, straddr, t->s_iptv_port, + t->s_uuid, straddr, t->s_iptv_port, strerror(errno)); close(fd); return -1; @@ -294,7 +294,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start) inet_ntop(AF_INET6, m6.ipv6mr_multiaddr.s6_addr, straddr, sizeof(straddr)); tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot join %s -- %s", - t->s_identifier, straddr, strerror(errno)); + t->s_uuid, straddr, strerror(errno)); close(fd); return -1; } @@ -312,7 +312,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start) ev.data.fd = fd; if(epoll_ctl(iptv_epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot add to epoll set -- %s", - t->s_identifier, strerror(errno)); + t->s_uuid, strerror(errno)); close(fd); return -1; } @@ -356,7 +356,7 @@ iptv_service_stop(service_t *t) ifr.ifr_name[IFNAMSIZ - 1] = 0; if(ioctl(t->s_iptv_fd, SIOCGIFINDEX, &ifr)) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot find interface %s", - t->s_identifier, t->s_iptv_iface); + t->s_uuid, t->s_iptv_iface); } if(t->s_iptv_group.s_addr != 0) { @@ -371,7 +371,7 @@ iptv_service_stop(service_t *t) if(setsockopt(t->s_iptv_fd, SOL_IP, IP_DROP_MEMBERSHIP, &m, sizeof(struct ip_mreqn)) == -1) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot leave %s -- %s", - t->s_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno)); + t->s_uuid, inet_ntoa(m.imr_multiaddr), strerror(errno)); } } else { char straddr[INET6_ADDRSTRLEN]; @@ -388,7 +388,7 @@ iptv_service_stop(service_t *t) straddr, sizeof(straddr)); tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot leave %s -- %s", - t->s_identifier, straddr, strerror(errno)); + t->s_uuid, straddr, strerror(errno)); } @@ -441,27 +441,12 @@ iptv_service_save(service_t *t) pthread_mutex_unlock(&t->s_stream_mutex); hts_settings_save(m, "iptvservices/%s", - t->s_identifier); + t->s_uuid); htsmsg_destroy(m); } -/** - * - */ -static int -iptv_service_quality(service_t *t) -{ - if(t->s_iptv_iface == NULL || - (t->s_iptv_group.s_addr == 0 && t->s_iptv_group6.s6_addr == 0) || - t->s_iptv_port == 0) - return 0; - - return 100; -} - - /** * Generate a descriptive name for the source */ @@ -499,7 +484,7 @@ iptv_grace_period(service_t *t) static void iptv_service_dtor(service_t *t) { - hts_settings_remove("iptvservices/%s", t->s_identifier); + hts_settings_remove("iptvservices/%s", t->s_uuid); } @@ -519,7 +504,7 @@ iptv_service_find(const char *id, int create) return NULL; LIST_FOREACH(t, &iptv_all_services, s_group_link) - if(!strcmp(t->s_identifier, id)) + if(!strcmp(t->s_uuid, id)) return t; } @@ -534,7 +519,7 @@ iptv_service_find(const char *id, int create) tally = MAX(atoi(id + 5), tally); } - t = service_create(id, SERVICE_TYPE_IPTV, S_MPEG_TS); + t = service_create(id, S_MPEG_TS); t->s_servicetype = ST_SDTV; t->s_start_feed = iptv_service_start; @@ -542,7 +527,6 @@ iptv_service_find(const char *id, int create) t->s_stop_feed = iptv_service_stop; t->s_config_save = iptv_service_save; t->s_setsourceinfo = iptv_service_setsourceinfo; - t->s_quality_index = iptv_service_quality; t->s_grace_period = iptv_grace_period; t->s_dtor = iptv_service_dtor; t->s_iptv_fd = -1; diff --git a/src/rawtsinput.c b/src/rawtsinput.c index bd4a5098..256d476d 100644 --- a/src/rawtsinput.c +++ b/src/rawtsinput.c @@ -83,17 +83,6 @@ rawts_service_save(service_t *t) } - -/** - * - */ -static int -rawts_service_quality(service_t *t) -{ - return 100; -} - - /** * Generate a descriptive name for the source */ @@ -123,7 +112,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, SERVICE_TYPE_DVB, S_MPEG_TS); + t = service_create(tmp, S_MPEG_TS); t->s_flags |= S_DEBUG; t->s_dvb_service_id = sid; @@ -133,7 +122,6 @@ rawts_service_add(rawts_t *rt, uint16_t sid, int pmt_pid) t->s_stop_feed = rawts_service_stop; t->s_config_save = rawts_service_save; t->s_setsourceinfo = rawts_service_setsourceinfo; - t->s_quality_index = rawts_service_quality; t->s_svcname = strdup(tmp); diff --git a/src/service.c b/src/service.c index 6548f104..90b8a4d7 100644 --- a/src/service.c +++ b/src/service.c @@ -231,86 +231,6 @@ service_start(service_t *t, unsigned int weight, int force_start) return 0; } -/** - * - */ -static int -dvb_extra_prio(th_dvb_adapter_t *tda) -{ - return tda->tda_extrapriority + tda->tda_hostconnection * 10; -} - -/** - * Return prio for the given service - */ -static int -service_get_prio(service_t *t) -{ - switch(t->s_type) { - case SERVICE_TYPE_DVB: - return (t->s_scrambled ? 300 : 100) + - dvb_extra_prio(t->s_dvb_mux_instance->tdmi_adapter); - - case SERVICE_TYPE_IPTV: - return 200; - - case SERVICE_TYPE_V4L: - return 400; - - default: - return 500; - } -} - -/** - * Return quality index for given service - * - * We invert the result (providers say that negative numbers are worse) - * - * But for sorting, we want low numbers first - * - * Also, we bias and trim with an offset of two to avoid counting any - * transient errors. - */ - -static int -service_get_quality(service_t *t) -{ - return t->s_quality_index ? -MIN(t->s_quality_index(t) + 2, 0) : 0; -} - - - - -/** - * a - b -> lowest number first - */ -static int -servicecmp(const void *A, const void *B) -{ - service_t *a = *(service_t **)A; - service_t *b = *(service_t **)B; - - /* only check quality if both adapters have the same prio - * - * there needs to be a much more sophisticated algorithm to take priority and quality into account - * additional, it may be problematic, since a higher priority value lowers the ranking - * - */ - int prio_a = service_get_prio(a); - int prio_b = service_get_prio(b); - if (prio_a == prio_b) { - - int q = service_get_quality(a) - service_get_quality(b); - - if(q != 0) - return q; /* Quality precedes priority */ - } - - return prio_a - prio_b; -} - - /** * */ @@ -351,7 +271,7 @@ service_find(channel_t *ch, unsigned int weight, const char *loginfo, /* Sort services, lower priority should come come earlier in the vector (i.e. it will be more favoured when selecting a service */ - qsort(vec, cnt, sizeof(service_t *), servicecmp); + // qsort(vec, cnt, sizeof(service_t *), servicecmp); // Skip up to the service that the caller didn't want // If the sorting above is not stable that might mess up things @@ -371,15 +291,6 @@ service_find(channel_t *ch, unsigned int weight, const char *loginfo, t = vec[i]; if(t->s_status == SERVICE_RUNNING) return t; - if(t->s_quality_index(t) < 10) { - if(loginfo != NULL) { - tvhlog(LOG_NOTICE, "Service", - "%s: Skipping \"%s\" -- Quality below 10%%", - loginfo, service_nicename(t)); - err = SM_CODE_BAD_SIGNAL; - } - continue; - } tvhlog(LOG_DEBUG, "Service", "%s: Probing adapter \"%s\" without stealing for service \"%s\"", loginfo, service_adapter_nicename(t), service_nicename(t)); if((r = service_start(t, 0, 0)) == 0) @@ -487,7 +398,7 @@ service_destroy(service_t *t) t->s_status = SERVICE_ZOMBIE; - free(t->s_identifier); + free(t->s_uuid); free(t->s_svcname); free(t->s_provider); free(t->s_dvb_charset); @@ -516,17 +427,16 @@ service_destroy(service_t *t) * Create and initialize a new service struct */ service_t * -service_create(const char *identifier, int type, int source_type) +service_create(const char *uuid, int source_type) { - unsigned int hash = tvh_strhash(identifier, SERVICE_HASH_WIDTH); + unsigned int hash = tvh_strhash(uuid, SERVICE_HASH_WIDTH); service_t *t = calloc(1, sizeof(service_t)); lock_assert(&global_lock); pthread_mutex_init(&t->s_stream_mutex, NULL); pthread_cond_init(&t->s_tss_cond, NULL); - t->s_identifier = strdup(identifier); - t->s_type = type; + t->s_uuid = strdup(uuid); t->s_source_type = source_type; t->s_refcount = 1; t->s_enabled = 1; @@ -555,7 +465,7 @@ service_find_by_identifier(const char *identifier) lock_assert(&global_lock); LIST_FOREACH(t, &servicehash[hash], s_hash_link) - if(!strcmp(t->s_identifier, identifier)) + if(!strcmp(t->s_uuid, identifier)) break; return t; } @@ -1061,25 +971,7 @@ service_component_nicename(elementary_stream_t *st) const char * service_adapter_nicename(service_t *t) { - switch(t->s_type) { - case SERVICE_TYPE_DVB: - if(t->s_dvb_mux_instance) - return t->s_dvb_mux_instance->tdmi_identifier; - else - return "Unknown adapter"; - - case SERVICE_TYPE_IPTV: - return t->s_iptv_iface; - - case SERVICE_TYPE_V4L: - if(t->s_v4l_adapter) - return t->s_v4l_adapter->va_displayname; - else - return "Unknown adapter"; - - default: - return "Unknown adapter"; - } + return "Adapter"; } const char * @@ -1140,6 +1032,45 @@ service_refresh_channel(service_t *t) } +/** + * + */ +static int +ssc_cmp(const service_start_cand_t *a, + const service_start_cand_t *b) +{ + return a->ssc_prio - b->ssc_prio; +} + +/** + * + */ +service_start_cand_t * +service_find_cand(struct service_start_cand_list *sscl, + struct service *s, int instance, int prio) +{ + service_start_cand_t *ssc; + LIST_FOREACH(ssc, sscl, ssc_link) { + if(ssc->ssc_s == s && ssc->ssc_instance == instance) + break; + } + + if(ssc != NULL) { + ssc = calloc(1, sizeof(service_start_cand_t)); + ssc->ssc_s = s; + service_ref(s); + ssc->ssc_instance = instance; + } else { + if(ssc->ssc_prio == prio) + return ssc; + LIST_REMOVE(ssc, ssc_link); + } + ssc->ssc_prio = prio; + LIST_INSERT_SORTED(sscl, ssc, ssc_link, ssc_cmp); + return ssc; +} + + /** * Get the encryption CAID from a service * only the first CA stream in a service is returned @@ -1174,9 +1105,8 @@ service_is_primary_epg(service_t *svc) service_t *ret = NULL, *t; if (!svc || !svc->s_ch) return 0; LIST_FOREACH(t, &svc->s_ch->ch_services, s_ch_link) { - if (!t->s_dvb_mux_instance) continue; if (!t->s_enabled || !t->s_dvb_eit_enable) continue; - if (!ret || service_get_prio(t) < service_get_prio(ret)) + if (!ret) ret = t; } return !ret ? 0 : (ret->s_dvb_service_id == svc->s_dvb_service_id); diff --git a/src/service.h b/src/service.h index 11e39b5d..e63dfbff 100644 --- a/src/service.h +++ b/src/service.h @@ -167,6 +167,36 @@ typedef struct elementary_stream { } elementary_stream_t; +LIST_HEAD(service_start_cand_list, service_start_cand); + +/** + * + */ +typedef struct service_start_cand { + + LIST_ENTRY(service_start_cand) ssc_link; + + int ssc_prio; + + struct service *ssc_s; // A reference is held + int ssc_instance; // Discriminator when having multiple adapters, etc + + int ssc_error_code; // Set if we deem this cand to be broken + time_t ssc_err_time; // Time we detected it was broken + + int ssc_weight; // Highest weight that holds this cand + +} service_start_cand_t; + + +/** + * + */ +service_start_cand_t *service_find_cand(struct service_start_cand_list *sscl, + struct service *s, + int instance, + int prio); + /** * */ @@ -174,12 +204,6 @@ typedef struct service { LIST_ENTRY(service) s_hash_link; - enum { - SERVICE_TYPE_DVB, - SERVICE_TYPE_IPTV, - SERVICE_TYPE_V4L, - } s_type; - enum { /** * Transport is idle. @@ -262,6 +286,10 @@ typedef struct service { LIST_HEAD(, th_subscription) s_subscriptions; + void (*s_enlist)(struct service *s, + struct service_start_cand_list *sscl); + + int (*s_start_feed)(struct service *t, unsigned int weight, int force_start); @@ -273,8 +301,6 @@ typedef struct service { void (*s_setsourceinfo)(struct service *t, struct source_info *si); - int (*s_quality_index)(struct service *t); - int (*s_grace_period)(struct service *t); void (*s_dtor)(struct service *t); @@ -282,12 +308,12 @@ typedef struct service { /* * Per source type structs */ - struct th_dvb_mux_instance *s_dvb_mux_instance; + struct dvb_mux *s_dvb_mux; /** - * Unique identifer (used for storing on disk, etc) + * Unique identifer */ - char *s_identifier; + char *s_uuid; /** * Name usable for displaying to user @@ -520,8 +546,7 @@ unsigned int service_compute_weight(struct service_list *head); int service_start(service_t *t, unsigned int weight, int force_start); -service_t *service_create(const char *identifier, int type, - int source_type); +service_t *service_create(const char *uuid, int source_type); void service_unref(service_t *t); diff --git a/src/serviceprobe.c b/src/serviceprobe.c index 62dcc211..2bdb5048 100644 --- a/src/serviceprobe.c +++ b/src/serviceprobe.c @@ -108,7 +108,8 @@ serviceprobe_thread(void *aux) was_doing_work = 1; } - checksubscr = !t->s_dvb_mux_instance->tdmi_adapter->tda_skip_checksubscr; + // XXX(dvbreorg) + checksubscr = 1; // !t->s_dvb_mux->tdmi_adapter->tda_skip_checksubscr; if (checksubscr) { tvhlog(LOG_INFO, "serviceprobe", "%20s: checking...", @@ -176,10 +177,10 @@ serviceprobe_thread(void *aux) } else if(t->s_ch == NULL) { int channum = t->s_channel_number; const char *str; - +#if 0 // XXX(dvbreorg) if (!channum && t->s_dvb_mux_instance->tdmi_adapter->tda_sidtochan) channum = t->s_dvb_service_id; - +#endif ch = channel_find_by_name(t->s_svcname, 1, channum); service_map_channel(t, ch, 1); diff --git a/src/settings.c b/src/settings.c index 8f0de39b..8a98cad6 100644 --- a/src/settings.c +++ b/src/settings.c @@ -214,7 +214,7 @@ hts_settings_load_one(const char *filename) * */ static htsmsg_t * -_hts_settings_load(const char *fullpath) +hts_settings_load_path(const char *fullpath, int depth) { char child[256]; struct filebundle_stat st; @@ -237,9 +237,16 @@ _hts_settings_load(const char *fullpath) for(i = 0; i < n; i++) { d = namelist[i]; if(d->name[0] != '.') { - snprintf(child, sizeof(child), "%s/%s", fullpath, d->name); - if ((c = hts_settings_load_one(child))) + + snprintf(child, sizeof(child), "%s/%s", fullpath, d->name); + if(d->type == FB_DIR && depth > 0) { + c = hts_settings_load_path(child, depth - 1); + } else { + c = hts_settings_load_one(child); + } + if(c != NULL) htsmsg_add_msg(r, d->name, c); + } free(d); } @@ -256,32 +263,56 @@ _hts_settings_load(const char *fullpath) /** * */ -htsmsg_t * -hts_settings_load(const char *pathfmt, ...) +static htsmsg_t * +hts_settings_vload(const char *pathfmt, va_list ap, int depth) { htsmsg_t *ret = NULL; char fullpath[256]; - va_list ap; + va_list ap2; + va_copy(ap2, ap); - /* Try normal path */ - va_start(ap, pathfmt); - hts_settings_buildpath(fullpath, sizeof(fullpath), + hts_settings_buildpath(fullpath, sizeof(fullpath), pathfmt, ap, settingspath); - va_end(ap); - ret = _hts_settings_load(fullpath); + ret = hts_settings_load_path(fullpath, depth); /* Try bundle path */ if (!ret && *pathfmt != '/') { - va_start(ap, pathfmt); hts_settings_buildpath(fullpath, sizeof(fullpath), - pathfmt, ap, "data/conf"); - va_end(ap); - ret = _hts_settings_load(fullpath); + pathfmt, ap2, "data/conf"); + ret = hts_settings_load_path(fullpath, depth); } - + return ret; } + +/** + * + */ +htsmsg_t * +hts_settings_load(const char *pathfmt, ...) +{ + va_list ap; + va_start(ap, pathfmt); + htsmsg_t *r = hts_settings_vload(pathfmt, ap, 0); + va_end(ap); + return r; +} + + +/** + * + */ +htsmsg_t * +hts_settings_load_r(int depth, const char *pathfmt, ...) +{ + va_list ap; + va_start(ap, pathfmt); + htsmsg_t *r = hts_settings_vload(pathfmt, ap, depth); + va_end(ap); + return r; +} + /** * */ diff --git a/src/settings.h b/src/settings.h index 7f0bb8d0..2ab52083 100644 --- a/src/settings.h +++ b/src/settings.h @@ -28,6 +28,8 @@ void hts_settings_save(htsmsg_t *record, const char *pathfmt, ...); htsmsg_t *hts_settings_load(const char *pathfmt, ...); +htsmsg_t *hts_settings_load_r(int depth, const char *pathfmt, ...); + void hts_settings_remove(const char *pathfmt, ...); const char *hts_settings_get_root(void); diff --git a/src/subscriptions.c b/src/subscriptions.c index 2f56825b..e7026080 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -385,14 +385,13 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight, tvhlog(LOG_INFO, "subscription", "\"%s\" subscribing on \"%s\", weight: %d, adapter: \"%s\", " "network: \"%s\", mux: \"%s\", provider: \"%s\", " - "service: \"%s\", quality: %d", + "service: \"%s\"", s->ths_title, ch->ch_name, weight, si.si_adapter ?: "", si.si_network ?: "", si.si_mux ?: "", si.si_provider ?: "", - si.si_service ?: "", - s->ths_service->s_quality_index(s->ths_service)); + si.si_service ?: ""); service_source_info_free(&si); } @@ -432,14 +431,13 @@ subscription_create_from_service(service_t *t, const char *name, tvhlog(LOG_INFO, "subscription", "\"%s\" direct subscription to adapter: \"%s\", " "network: \"%s\", mux: \"%s\", provider: \"%s\", " - "service: \"%s\", quality: %d", + "service: \"%s\"", s->ths_title, si.si_adapter ?: "", si.si_network ?: "", si.si_mux ?: "", si.si_provider ?: "", - si.si_service ?: "", - t->s_quality_index(t)); + si.si_service ?: ""); service_source_info_free(&si); subscription_link_service(s, t); diff --git a/src/tvheadend.h b/src/tvheadend.h index e117f6ab..e401d582 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -56,6 +56,7 @@ typedef struct source_info { int si_type; } source_info_t; + static inline void lock_assert0(pthread_mutex_t *l, const char *file, int line) { diff --git a/src/v4l.c b/src/v4l.c index a7b86075..9ad9a5c6 100644 --- a/src/v4l.c +++ b/src/v4l.c @@ -289,7 +289,7 @@ v4l_service_save(service_t *t) pthread_mutex_unlock(&t->s_stream_mutex); hts_settings_save(m, "v4lservices/%s/%s", - va->va_identifier, t->s_identifier); + va->va_identifier, t->s_uuid); htsmsg_destroy(m); } @@ -349,7 +349,7 @@ v4l_service_find(v4l_adapter_t *va, const char *id, int create) return NULL; LIST_FOREACH(t, &va->va_services, s_group_link) - if(!strcmp(t->s_identifier, id)) + if(!strcmp(t->s_uuid, id)) return t; } @@ -364,7 +364,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, SERVICE_TYPE_V4L, 0); + t = service_create(id, 0); t->s_start_feed = v4l_service_start; t->s_refresh_feed = v4l_service_refresh; diff --git a/src/webui/extjs.c b/src/webui/extjs.c index df1ce74e..98d12426 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -1669,7 +1669,7 @@ build_record_iptv(service_t *t) htsmsg_t *r = htsmsg_create_map(); char abuf[INET_ADDRSTRLEN]; char abuf6[INET6_ADDRSTRLEN]; - htsmsg_add_str(r, "id", t->s_identifier); + htsmsg_add_str(r, "id", t->s_uuid); htsmsg_add_str(r, "channelname", t->s_ch ? t->s_ch->ch_name : ""); htsmsg_add_str(r, "interface", t->s_iptv_iface ?: ""); @@ -1828,7 +1828,7 @@ extjs_tvadapter(http_connection_t *hc, const char *remain, void *opaque) array = htsmsg_create_list(); #if ENABLE_LINUXDVB - extjs_list_dvb_adapters(array); + // extjs_list_dvb_adapters(array); #endif #if ENABLE_V4L diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index 211602f1..c6aebc41 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -43,6 +43,10 @@ #include "dvb/dvb_preconf.h" #include "dvr/dvr.h" +#if 0 + + + /** * */ @@ -685,6 +689,7 @@ extjs_list_dvb_adapters(htsmsg_t *array) htsmsg_add_msg(array, NULL, dvb_adapter_build_msg(tda)); } +#endif /** * @@ -741,11 +746,12 @@ 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); +#if 0 http_path_add("/dvb/locations", NULL, extjs_dvblocations, ACCESS_WEB_INTERFACE); - http_path_add("/dvb/networks", - NULL, extjs_dvbnetworks, ACCESS_WEB_INTERFACE); http_path_add("/dvb/adapter", NULL, extjs_dvbadapter, ACCESS_ADMIN); @@ -767,7 +773,6 @@ extjs_start_dvb(void) http_path_add("/dvb/addmux", NULL, extjs_dvb_addmux, ACCESS_ADMIN); -#if 0 // XXX(dvbreorg) http_path_add("/dvb/copymux", NULL, extjs_dvb_copymux, ACCESS_ADMIN); #endif diff --git a/src/webui/statedump.c b/src/webui/statedump.c index ff7e4ef9..96df49a8 100644 --- a/src/webui/statedump.c +++ b/src/webui/statedump.c @@ -76,6 +76,7 @@ dumpchannels(htsbuf_queue_t *hq) } #if ENABLE_LINUXDVB +#if 0 static void dumptransports(htsbuf_queue_t *hq, struct service_list *l, int indent) { @@ -119,6 +120,7 @@ dumptransports(htsbuf_queue_t *hq, struct service_list *l, int indent) } } +#endif @@ -126,23 +128,11 @@ static void dumpdvbadapters(htsbuf_queue_t *hq) { th_dvb_adapter_t *tda; - th_dvb_mux_instance_t *tdmi; outputtitle(hq, 0, "DVB Adapters"); TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) { htsbuf_qprintf(hq, "%s (%s)\n", tda->tda_displayname, tda->tda_identifier); - - outputtitle(hq, 4, "Multiplexes"); - LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) { - char tdminame[64]; - dvb_mux_nicename(tdminame, sizeof(tdminame), tdmi); - htsbuf_qprintf(hq, " %s (%s)\n", - tdminame, tdmi->tdmi_identifier); - - htsbuf_qprintf(hq, "\n"); - dumptransports(hq, &tdmi->tdmi_mux->dm_services, 8); - } } } #endif diff --git a/src/webui/webui.c b/src/webui/webui.c index 6e5ab39c..f72a865d 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -606,7 +606,7 @@ http_stream_tdmi(http_connection_t *hc, th_dvb_mux_instance_t *tdmi) streaming_queue_init(&sq, SMT_PACKET); s = dvb_subscription_create_from_tdmi(tdmi, "HTTP", &sq.sq_st); - name = strdupa(tdmi->tdmi_identifier); + name = strdupa(tdmi->tdmi_mux->dm_uuid); pthread_mutex_unlock(&global_lock); http_stream_run(hc, &sq, name, MC_PASS); pthread_mutex_lock(&global_lock); @@ -723,7 +723,7 @@ http_stream(http_connection_t *hc, const char *remain, void *opaque) } else if(!strcmp(components[0], "service")) { service = service_find_by_identifier(components[1]); } else if(!strcmp(components[0], "mux")) { - tdmi = dvb_mux_find_by_identifier(components[1]); + tdmi = NULL; // dvb_mux_find_by_identifier(components[1]); } if(ch != NULL) {