void
dvbcam_service_stop(service_t *t)
{
- dvbcam_active_service_t *as, *as_tmp;
+ dvbcam_active_service_t *as, *as_tmp;
linuxdvb_ca_t *ca = NULL;
dvbcam_active_cam_t *ac2;
- uint8_t slot;
+ uint8_t slot = -1;
tvhtrace("dvbcam", "stop service %p", t);
return rfreq;
}
+static int
+linuxdvb_en50494_match
+ ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm1, dvb_mux_t *lm2 )
+{
+ return lm1 == lm2;
+}
+
static int
linuxdvb_en50494_tune
( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
le->le_frequency = 0;
le->le_pin = LINUXDVB_EN50494_NOPIN;
le->ld_freq = linuxdvb_en50494_freq;
+ le->ld_match = linuxdvb_en50494_match;
ld = linuxdvb_diseqc_create0((linuxdvb_diseqc_t *)le,
NULL, &linuxdvb_en50494_class, conf,
return &s;
}
+static htsmsg_t *
+linuxdvb_frontend_dvbs_class_master_enum( void * self, const char *lang )
+{
+ linuxdvb_frontend_t *lfe = self, *lfe2;
+ linuxdvb_adapter_t *la;
+ tvh_hardware_t *th;
+ htsmsg_t *m = htsmsg_create_list();
+ htsmsg_t *e = htsmsg_create_map();
+ htsmsg_add_str(e, "key", "");
+ htsmsg_add_str(e, "val", N_("This Tuner"));
+ htsmsg_add_msg(m, NULL, e);
+ LIST_FOREACH(th, &tvh_hardware, th_link) {
+ if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) continue;
+ la = (linuxdvb_adapter_t*)th;
+ LIST_FOREACH(lfe2, &la->la_frontends, lfe_link) {
+ if (lfe2 != lfe && lfe2->lfe_type == lfe->lfe_type) {
+ e = htsmsg_create_map();
+ htsmsg_add_str(e, "key", idnode_uuid_as_sstr(&lfe2->ti_id));
+ htsmsg_add_str(e, "val", lfe2->mi_name);
+ htsmsg_add_msg(m, NULL, e);
+ }
+ }
+ }
+ return m;
+}
+
const idclass_t linuxdvb_frontend_dvbs_class =
{
.ic_super = &linuxdvb_frontend_class,
.list = linuxdvb_satconf_type_list,
.def.s = "simple"
},
+ {
+ .type = PT_STR,
+ .id = "fe_master",
+ .name = N_("Master Tuner"),
+ .list = linuxdvb_frontend_dvbs_class_master_enum,
+ .off = offsetof(linuxdvb_frontend_t, lfe_master),
+ },
+ {
+ .id = "networks",
+ .type = PT_NONE,
+ },
+ {}
+ }
+};
+
+const idclass_t linuxdvb_frontend_dvbs_slave_class =
+{
+ .ic_super = &linuxdvb_frontend_class,
+ .ic_class = "linuxdvb_frontend_dvbs",
+ .ic_caption = N_("Linux DVB-S Slave Frontend"),
+ .ic_properties = (const property_t[]){
+ {
+ .type = PT_STR,
+ .id = "fe_master",
+ .name = N_("Master Tuner"),
+ .list = linuxdvb_frontend_dvbs_class_master_enum,
+ .off = offsetof(linuxdvb_frontend_t, lfe_master),
+ },
{
.id = "networks",
.type = PT_NONE,
static int
linuxdvb_frontend_is_enabled ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags )
{
- linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
+ linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2;
+ linuxdvb_adapter_t *la;
+ tvh_hardware_t *th;
+
if (lfe->lfe_fe_path == NULL) return 0;
if (!mpegts_input_is_enabled(mi, mm, flags)) return 0;
if (access(lfe->lfe_fe_path, R_OK | W_OK)) return 0;
if (lfe->lfe_in_setup) return 0;
+ if (lfe->lfe_type != DVB_TYPE_S) return 0;
+
+ /* check if any "blocking" tuner is running */
+ LIST_FOREACH(th, &tvh_hardware, th_link) {
+ if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) continue;
+ la = (linuxdvb_adapter_t*)th;
+ LIST_FOREACH(lfe2, &la->la_frontends, lfe_link) {
+ if (lfe2 == lfe) continue;
+ if (lfe2->lfe_type != DVB_TYPE_S) continue;
+ if (lfe->lfe_master && !strcmp(lfe->lfe_master, idnode_uuid_as_sstr(&lfe2->ti_id))) {
+ if (lfe2->lfe_satconf == NULL)
+ return 0; /* invalid master */
+ return linuxdvb_satconf_match_mux(lfe2->lfe_satconf, mm);
+ }
+ if (lfe2->lfe_master &&
+ !strcmp(lfe2->lfe_master, idnode_uuid_as_sstr(&lfe->ti_id)) &&
+ lfe2->lfe_refcount > 0) {
+ if (lfe->lfe_satconf == NULL)
+ return 0;
+ return linuxdvb_satconf_match_mux(lfe->lfe_satconf, mm);
+ }
+ }
+ }
return 1;
}
( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
{
char buf1[256], buf2[256];
-
- linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
+ linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2;
+
+ if (lfe->lfe_master)
+ assert(lfe->lfe_type == DVB_TYPE_S);
+
mi->mi_display_name(mi, buf1, sizeof(buf1));
mpegts_mux_nice_name(mmi->mmi_mux, buf2, sizeof(buf2));
tvhdebug("linuxdvb", "%s - stopping %s", buf1, buf2);
/* Ensure it won't happen immediately */
gtimer_arm(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 2);
- if (lfe->lfe_satconf)
+ if (lfe->lfe_satconf && lfe->lfe_refcount == 1)
linuxdvb_satconf_post_stop_mux(lfe->lfe_satconf);
+ if (lfe->lfe_master) {
+ lfe2 = (linuxdvb_frontend_t *)idnode_find(lfe->lfe_master, &linuxdvb_frontend_class, NULL);
+ if (lfe2->lfe_type != lfe->lfe_type)
+ lfe2 = NULL;
+ if (lfe2) { /* master tuner shutdown procedure */
+ assert(lfe2->lfe_refcount >= 0);
+ if (--lfe2->lfe_refcount == 0) {
+ lfe2->lfe_ready = 0;
+ lfe2->lfe_locked = 0;
+ lfe2->lfe_status = 0;
+ lfe2->lfe_status2 = 0;
+ /* Ensure it won't happen immediately */
+ gtimer_arm(&lfe2->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 2);
+ if (lfe2->lfe_satconf)
+ linuxdvb_satconf_post_stop_mux(lfe2->lfe_satconf);
+ lfe2->lfe_in_setup = 0;
+ lfe2->lfe_freq = 0;
+ }
+ }
+ }
+
+ lfe->lfe_refcount--;
lfe->lfe_in_setup = 0;
lfe->lfe_freq = 0;
mpegts_pid_done(&lfe->lfe_pids);
linuxdvb_frontend_start_mux
( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
{
- linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
- int res;
+ linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2;
+ int res, f;
+
+ assert(lfe->lfe_in_setup == 0);
+ lfe->lfe_refcount++;
lfe->lfe_in_setup = 1;
lfe->lfe_ioctls = 0;
+
+ if (lfe->lfe_master) {
+ assert(lfe->lfe_type == DVB_TYPE_S);
+ lfe2 = (linuxdvb_frontend_t *)idnode_find(lfe->lfe_master, &linuxdvb_frontend_class, NULL);
+ if (lfe2->lfe_type != lfe->lfe_type)
+ lfe2 = NULL;
+ res = SM_CODE_TUNING_FAILED;
+ if (lfe2) {
+ f = linuxdvb_satconf_lnb_freq(lfe2->lfe_satconf, mmi);
+ if (f <= 0)
+ goto end;
+ if (lfe2->lfe_refcount++ == 0) {
+ lfe2->lfe_in_setup = 1;
+ lfe2->lfe_ioctls = 0;
+ res = linuxdvb_satconf_start_mux(lfe2->lfe_satconf, mmi, 0);
+ if (res)
+ goto end;
+ }
+ res = linuxdvb_frontend_tune1((linuxdvb_frontend_t*)mi, mmi, f);
+ }
+ goto end;
+ }
+
if (lfe->lfe_satconf)
- res = linuxdvb_satconf_start_mux(lfe->lfe_satconf, mmi);
+ res = linuxdvb_satconf_start_mux(lfe->lfe_satconf, mmi, lfe->lfe_refcount > 1);
else
res = linuxdvb_frontend_tune1((linuxdvb_frontend_t*)mi, mmi, -1);
- if (res)
+
+end:
+ if (res) {
lfe->lfe_in_setup = 0;
+ lfe->lfe_refcount--;
+ }
return res;
}
mmi->mmi_mux->mm_stop(mmi->mmi_mux, 1, SM_CODE_ABORTED);
/* Close FE */
- if (lfe->lfe_fe_fd > 0 && !mmi && lfe->lfe_powersave) {
+ if (lfe->lfe_fe_fd > 0 && !lfe->lfe_refcount && lfe->lfe_powersave) {
tvhtrace("linuxdvb", "%s - closing frontend", buf);
close(lfe->lfe_fe_fd);
lfe->lfe_fe_fd = -1;
/* Open FE */
lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1));
+ tvhtrace("linuxdvb", "%s - frontend clear", buf1);
if (lfe->lfe_fe_fd <= 0) {
lfe->lfe_fe_fd = tvh_open(lfe->lfe_fe_path, O_RDWR | O_NONBLOCK, 0);
dvb_fe_type_t type, const char *name )
{
const idclass_t *idc;
- const char *str, *uuid = NULL, *scuuid = NULL, *sctype = NULL;
- char id[12], lname[256];
+ const char *str, *uuid = NULL, *muuid = NULL, *scuuid = NULL, *sctype = NULL;
+ char id[16], lname[256];
linuxdvb_frontend_t *lfe;
htsmsg_t *scconf = NULL;
+ /* Tuner slave */
+ snprintf(id, sizeof(id), "master for #%d", number);
+ if (conf && type == DVB_TYPE_S) {
+ muuid = htsmsg_get_str(conf, id);
+ if (muuid && uuid && !strcmp(muuid, uuid))
+ muuid = NULL;
+ }
+
/* Internal config ID */
snprintf(id, sizeof(id), "%s #%d", dvb_type2str(type), number);
if (conf)
/* Class */
if (type == DVB_TYPE_S)
- idc = &linuxdvb_frontend_dvbs_class;
+ idc = muuid ? &linuxdvb_frontend_dvbs_slave_class :
+ &linuxdvb_frontend_dvbs_class;
else if (type == DVB_TYPE_C)
idc = &linuxdvb_frontend_dvbc_class;
else if (type == DVB_TYPE_T)
// in mpegts_input_create()). So we must set early.
lfe = calloc(1, sizeof(linuxdvb_frontend_t));
lfe->lfe_number = number;
- lfe->lfe_type = type;
+ lfe->lfe_type = type;
+ lfe->lfe_master = muuid ? strdup(muuid) : NULL;
strncpy(lfe->lfe_name, name, sizeof(lfe->lfe_name));
lfe->lfe_name[sizeof(lfe->lfe_name)-1] = '\0';
lfe->lfe_ibuf_size = 18800;
mpegts_pid_init(&lfe->lfe_pids);
/* Satconf */
- if (conf) {
+ if (conf && !muuid) {
if ((scconf = htsmsg_get_map(conf, "satconf"))) {
sctype = htsmsg_get_str(scconf, "type");
scuuid = htsmsg_get_str(scconf, "uuid");
}
/* Create satconf */
- if (lfe->lfe_type == DVB_TYPE_S && !lfe->lfe_satconf)
+ if (lfe->lfe_type == DVB_TYPE_S && !lfe->lfe_satconf && !muuid)
lfe->lfe_satconf = linuxdvb_satconf_create(lfe, sctype, scuuid, scconf);
/* Double check enabled */
void
linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *fe )
{
- char id[12];
+ char id[16];
htsmsg_t *m = htsmsg_create_map();
/* Save frontend */
mpegts_input_save((mpegts_input_t*)lfe, m);
htsmsg_add_str(m, "type", dvb_type2str(lfe->lfe_type));
htsmsg_add_str(m, "uuid", idnode_uuid_as_sstr(&lfe->ti_id));
- if (lfe->lfe_satconf) {
+ if (lfe->lfe_satconf && !lfe->lfe_master) {
htsmsg_t *s = htsmsg_create_map();
linuxdvb_satconf_save(lfe->lfe_satconf, s);
htsmsg_add_str(s, "uuid", idnode_uuid_as_sstr(&lfe->lfe_satconf->ls_id));
htsmsg_add_msg(m, "satconf", s);
}
+ htsmsg_delete_field(m, "fe_master");
/* Add to list */
snprintf(id, sizeof(id), "%s #%d", dvb_type2str(lfe->lfe_type), lfe->lfe_number);
htsmsg_add_msg(fe, id, m);
+
+ if (lfe->lfe_master) {
+ snprintf(id, sizeof(id), "master for #%d", lfe->lfe_number);
+ htsmsg_add_str(fe, id, lfe->lfe_master);
+ }
}
void
free(lfe->lfe_fe_path);
free(lfe->lfe_dmx_path);
free(lfe->lfe_dvr_path);
+ free(lfe->lfe_master);
/* Delete satconf */
if (lfe->lfe_satconf)
return (uint32_t)abs(f);
}
+static int
+linuxdvb_lnb_standard_match
+ ( linuxdvb_lnb_t *l, dvb_mux_t *lm1, dvb_mux_t *lm2 )
+{
+ linuxdvb_lnb_conf_t *lnb = (linuxdvb_lnb_conf_t*)l;
+ dvb_mux_conf_t *dmc1 = &lm1->lm_tuning;
+ dvb_mux_conf_t *dmc2 = &lm2->lm_tuning;
+
+ if (lnb->lnb_switch) {
+ uint32_t hi1 = dmc1->dmc_fe_freq > lnb->lnb_switch;
+ uint32_t hi2 = dmc2->dmc_fe_freq > lnb->lnb_switch;
+ if (hi1 != hi2)
+ return 0;
+ }
+ if (dmc1->u.dmc_fe_qpsk.polarisation != dmc2->u.dmc_fe_qpsk.polarisation)
+ return 0;
+ return 1;
+}
+
static int
linuxdvb_lnb_standard_band
( linuxdvb_lnb_t *l, dvb_mux_t *lm )
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_standard_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_standard_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_standard_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_standard_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_standard_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_standard_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_inverted_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_standard_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_standard_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_standard_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_standard_band,
.lnb_pol = linuxdvb_lnb_standard_pol,
},
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_bandstack_freq,
+ .lnb_match = linuxdvb_lnb_standard_match,
.lnb_band = linuxdvb_lnb_bandstack_band,
.lnb_pol = linuxdvb_lnb_bandstack_pol,
},
typedef TAILQ_HEAD(linuxdvb_ca_capmt_queue,linuxdvb_ca_capmt) linuxdvb_ca_capmt_queue_t;
#endif
+extern const idclass_t linuxdvb_adapter_class;
+
struct linuxdvb_adapter
{
tvh_hardware_t;
/*
* Tuning
*/
+ int lfe_refcount;
int lfe_ready;
int lfe_in_setup;
int lfe_locked;
/*
* Configuration
*/
+ char *lfe_master;
int lfe_powersave;
int lfe_tune_repeats;
uint32_t lfe_skip_bytes;
linuxdvb_satconf_ele_t *ld_satconf;
int (*ld_grace) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm);
int (*ld_freq) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, int freq);
+ int (*ld_match) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm1, dvb_mux_t *lm2);
int (*ld_tune) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls,
int vol, int pol, int band, int freq);
struct linuxdvb_lnb
{
linuxdvb_diseqc_t;
- uint32_t (*lnb_freq)(linuxdvb_lnb_t*, dvb_mux_t*);
- int (*lnb_band)(linuxdvb_lnb_t*, dvb_mux_t*);
- int (*lnb_pol) (linuxdvb_lnb_t*, dvb_mux_t*);
+ uint32_t (*lnb_freq) (linuxdvb_lnb_t*, dvb_mux_t*);
+ int (*lnb_match)(linuxdvb_lnb_t*, dvb_mux_t*, dvb_mux_t*);
+ int (*lnb_band) (linuxdvb_lnb_t*, dvb_mux_t*);
+ int (*lnb_pol) (linuxdvb_lnb_t*, dvb_mux_t*);
};
struct linuxdvb_en50494
int linuxdvb_satconf_get_grace
( linuxdvb_satconf_t *ls, mpegts_mux_t *mm );
-
+
+int linuxdvb_satconf_lnb_freq
+ ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi );
+
void linuxdvb_satconf_post_stop_mux( linuxdvb_satconf_t *ls );
int linuxdvb_satconf_start_mux
- ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi );
+ ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi, int skip_diseqc );
+
+int linuxdvb_satconf_match_mux
+ ( linuxdvb_satconf_t *ls, mpegts_mux_t *mm );
int linuxdvb_satconf_start ( linuxdvb_satconf_t *ls, int delay, int vol );
linuxdvb_satconf_post_stop_mux
( linuxdvb_satconf_t *ls )
{
+ ls->ls_mmi = NULL;
gtimer_disarm(&ls->ls_diseqc_timer);
if (ls->ls_frontend && ls->ls_lnb_poweroff) {
linuxdvb_diseqc_set_volt(ls, -1);
}
int
-linuxdvb_satconf_start_mux
+linuxdvb_satconf_lnb_freq
( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi )
+{
+ int f;
+ linuxdvb_satconf_ele_t *lse = linuxdvb_satconf_find_ele(ls, mmi->mmi_mux);
+ dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux;
+
+ if (!lse->lse_lnb)
+ return -1;
+
+ f = lse->lse_lnb->lnb_freq(lse->lse_lnb, lm);
+ if (f == (uint32_t)-1)
+ return -1;
+
+ /* calculate tuning frequency for en50494 */
+ if (lse->lse_en50494) {
+ f = lse->lse_en50494->ld_freq(lse->lse_en50494, lm, f);
+ if (f < 0) {
+ tvherror("en50494", "invalid tuning freq");
+ return -1;
+ }
+ }
+ return f;
+}
+
+int
+linuxdvb_satconf_start_mux
+ ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi, int skip_diseqc )
{
int r;
uint32_t f;
linuxdvb_satconf_ele_t *lse = linuxdvb_satconf_find_ele(ls, mmi->mmi_mux);
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend;
- dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux;
/* Not fully configured */
if (!lse) return SM_CODE_TUNING_FAILED;
if (!lse->lse_lnb)
return SM_CODE_TUNING_FAILED;
+ if (skip_diseqc) {
+ f = linuxdvb_satconf_lnb_freq(ls, mmi);
+ if (f < 0)
+ return SM_CODE_TUNING_FAILED;
+ return linuxdvb_frontend_tune1(lfe, mmi, f);
+ }
if (ls->ls_early_tune) {
-
- f = lse->lse_lnb->lnb_freq(lse->lse_lnb, lm);
- if (f == (uint32_t)-1)
+ f = linuxdvb_satconf_lnb_freq(ls, mmi);
+ if (f < 0)
return SM_CODE_TUNING_FAILED;
-
- /* calculate tuning frequency for en50494 */
- if (lse->lse_en50494) {
- r = lse->lse_en50494->ld_freq(lse->lse_en50494, lm, f);
- if (r < 0) {
- tvherror("en50494", "invalid tuning freq");
- return -1;
- }
- /* tune frequency for the frontend */
- f = r;
- }
-
r = linuxdvb_frontend_tune0(lfe, mmi, f);
if (r) return r;
} else {
ls->ls_last_tone_off = 0;
}
+/*
+ * return 0 if passed mux cannot be used simultanously with given
+ * diseqc config
+ */
+int
+linuxdvb_satconf_match_mux
+ ( linuxdvb_satconf_t *ls, mpegts_mux_t *mm )
+{
+ mpegts_mux_instance_t *mmi = ls->ls_mmi;
+
+ if (mmi == NULL || mmi->mmi_mux == NULL)
+ return 1;
+
+ linuxdvb_satconf_ele_t *lse1 = linuxdvb_satconf_find_ele(ls, mm);
+ linuxdvb_satconf_ele_t *lse2 = linuxdvb_satconf_find_ele(ls, mmi->mmi_mux);
+ dvb_mux_t *lm1 = (dvb_mux_t*)mmi->mmi_mux;
+ dvb_mux_t *lm2 = (dvb_mux_t*)mm;
+
+#if ENABLE_TRACE
+ char buf1[256], buf2[256];
+ dvb_mux_conf_str(&lm1->lm_tuning, buf1, sizeof(buf1));
+ dvb_mux_conf_str(&lm2->lm_tuning, buf2, sizeof(buf2));
+ tvhtrace("diseqc", "match mux 1 - %s", buf1);
+ tvhtrace("diseqc", "match mux 2 - %s", buf2);
+#endif
+
+ if (lse1 != lse2) {
+ tvhtrace("diseqc", "match position failed");
+ return 0;
+ }
+ if (!lse1->lse_lnb->lnb_match(lse1->lse_lnb, lm1, lm2)) {
+ tvhtrace("diseqc", "match LNB failed");
+ return 0;
+ }
+ if (lse1->lse_en50494 && !lse1->lse_en50494->ld_match(lse1->lse_en50494, lm1, lm2)) {
+ tvhtrace("diseqc", "match en50494 failed");
+ return 0;
+ }
+ return 1;
+}
+
/* **************************************************************************
* Create/Delete satconf
* *************************************************************************/