mpegts linuxdvb: starting to get more complete config load/save

This commit is contained in:
Adam Sutton 2013-05-30 20:55:11 +01:00
parent 578c3fc545
commit 7465423cb6
12 changed files with 238 additions and 120 deletions

View file

@ -342,9 +342,27 @@ idnode_notify_title_changed(void *obj)
notify_by_msg("idnodeNameChanged", m);
}
int
idnode_load_one
( idnode_t *self, htsmsg_t *m )
/*
* Save
*/
void
idnode_save ( idnode_t *self, htsmsg_t *c )
{
return 0;
const idclass_t *idc = self->in_class;
while (idc) {
prop_read_values(self, idc->ic_properties, c);
idc = idc->ic_super;
}
}
/*
* Load
*/
void idnode_load ( idnode_t *self, htsmsg_t *c )
{
const idclass_t *idc = self->in_class;
while (idc) {
prop_write_values(self, idc->ic_properties, c);
idc = idc->ic_super;
}
}

View file

@ -50,16 +50,5 @@ void idnode_update_all_props(idnode_t *in,
void idnode_notify_title_changed(void *obj);
void idnode_save ( idnode_t *self, const char *path );
idnode_t *idnode_load ( htsmsg_field_t *cfg, void*(*create)(const char*) );
void idnode_load_all ( const char *path, void *(*create)(const char*) );
idnode_t *idnode_create0
( size_t alloc, const idclass_t *class, const char *uuid );
#define idnode_create(c, uuid)\
(struct c*)idnode_create0(sizeof(struct c), &c##_class, uuid)
int idnode_load_one(idnode_t *self, htsmsg_t *cfg);
void idnode_save ( idnode_t *self, htsmsg_t *m );
void idnode_load ( idnode_t *self, htsmsg_t *m );

View file

@ -146,7 +146,6 @@ struct mpegts_network
/*
* Identification
*/
char *mn_network_name;
/*
@ -170,30 +169,18 @@ struct mpegts_network
/*
* Functions
*/
void (*mn_display_name) (mpegts_network_t*, char *buf, size_t len);
void (*mn_config_save) (mpegts_network_t*);
mpegts_mux_t* (*mn_create_mux)
(mpegts_mux_t*, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *conf);
mpegts_service_t* (*mn_create_service)
(mpegts_mux_t*, uint16_t sid, uint16_t pmt_pid);
void (*mn_display_name) (mpegts_network_t*, char *buf, size_t len);
void (*mn_config_save) (mpegts_network_t*);
// Note: the above are slightly odd in that they take mux instead of
// network as initial param. This is intentional as we need to
// know the mux and can easily get to network from there
#if 0 // TODO: FIXME
int dn_fe_type; // Frontend types for this network (FE_QPSK, etc)
#endif
uint32_t mn_nid; // limit scope of scanning
#if 0 // TODO: FIXME CONFIG
uint32_t dn_disable_pmt_monitor;
uint32_t dn_autodiscovery;
uint32_t dn_nitoid;
uint32_t dn_skip_checksubscr;
#endif
/*
* Configuration
*/
uint32_t mn_nid;
uint32_t mn_autodiscovery;
};
/* Multiplex */
@ -249,17 +236,18 @@ struct mpegts_mux
*/
void (*mm_config_save) (mpegts_mux_t *mm);
void (*mm_display_name) (mpegts_mux_t*, char *buf, size_t len);
int (*mm_is_enabled) (mpegts_mux_t *mm);
int (*mm_start) (mpegts_mux_t *mm, const char *r, int w);
void (*mm_stop) (mpegts_mux_t *mm);
void (*mm_open_table) (mpegts_mux_t*,mpegts_table_t*);
void (*mm_close_table) (mpegts_mux_t*,mpegts_table_t*);
void (*mm_create_instances) (mpegts_mux_t*);
void (*mm_display_name) (mpegts_mux_t*, char *buf, size_t len);
/*
* Fields
* Configuration
*/
char *mm_dvb_default_authority;
char *mm_crid_authority;
int mm_enabled;
};
@ -473,9 +461,9 @@ mpegts_mux_instance_t *mpegts_mux_instance_create0
&type##_class, uuid,\
mi, mm);
int mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force );
int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid, int force );
int mpegts_mux_set_default_authority ( mpegts_mux_t *mm, const char *defauth );
int mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid );
int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid );
int mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth );
size_t mpegts_input_recv_packets
(mpegts_input_t *mi, mpegts_mux_instance_t *mmi, uint8_t *tsb, size_t len,

View file

@ -200,8 +200,8 @@ typedef struct dvb_mux_conf
const char *dvb_mux_conf_load
( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m );
int dvb_mux_conf_save
( dvb_mux_conf_t *dmc, htsmsg_t *m );
void dvb_mux_conf_save
( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m );
/* conversion routines */
const char *dvb_rolloff2str ( int rolloff );

View file

@ -438,7 +438,7 @@ dvb_pat_callback
{
int sect, last, ver;
uint16_t sid, pid, tsid;
uint16_t nit_pid = DVB_NIT_PID;
uint16_t nit_pid = 0;
mpegts_mux_t *mm = mt->mt_mux;
/* Begin */
@ -449,9 +449,7 @@ dvb_pat_callback
/* Multiplex */
tsid = (ptr[0] << 8) | ptr[1];
tvhtrace("pat", "tsid %04X (%d)", tsid, tsid);
mpegts_mux_set_tsid(mm, tsid, 0);
if (mm->mm_tsid != tsid)
return -1;
mpegts_mux_set_tsid(mm, tsid);
/* Process each programme */
ptr += 5;
@ -463,8 +461,8 @@ dvb_pat_callback
/* NIT PID */
if (sid == 0) {
if (pid) {
tvhtrace("pat", " nit on pid %04X (%d)", pid, pid);
nit_pid = pid;
tvhtrace("pat", " nit on pid %04X (%d)", pid, pid);
}
/* Service */
@ -481,11 +479,13 @@ dvb_pat_callback
ptr += 4;
len -= 4;
}
/* Install NIT handler */
if (nit_pid)
mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback,
NULL, "nit", MT_QUICKREQ | MT_CRC, nit_pid);
/* Install NIT monitor */
mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback,
NULL, "nit", MT_CRC | MT_QUICKREQ, nit_pid);
/* End */
dvb_table_end(mt, tableid, sect, last, ver);
return mt->mt_state[0].complete ? 0 : -1;
}
@ -631,7 +631,7 @@ dvb_nit_callback
return -1;
tvhtrace(mt->mt_name, " default auth [%s]", dauth);
if (mux && *dauth)
mpegts_mux_set_default_authority(mux, dauth);
mpegts_mux_set_crid_authority(mux, dauth);
break;
case DVB_DESC_LOCAL_CHAN:
if (dvb_desc_local_channel(mt->mt_name, dptr, dlen, mux))
@ -675,10 +675,8 @@ dvb_sdt_callback
/* Find Transport Stream */
if (tableid == 0x42) {
mpegts_mux_set_onid(mm, onid, 0);
mpegts_mux_set_tsid(mm, tsid, 0);
if (mm->mm_onid != onid || mm->mm_tsid != tsid)
return -1;
mpegts_mux_set_onid(mm, onid);
mpegts_mux_set_tsid(mm, tsid);
} else {
mpegts_network_t *mn = mm->mm_network;
LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link)

View file

@ -676,4 +676,66 @@ dvb_mux_conf_load ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m )
return "Invalid FE type";
}
static void
dvb_mux_conf_save_dvbt ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
struct dvb_ofdm_parameters *ofdm = &dmc->dmc_fe_params.u.ofdm;
htsmsg_add_str(m, "bandwidth",
dvb_bw2str(ofdm->bandwidth));
htsmsg_add_str(m, "constellation",
dvb_qam2str(ofdm->constellation));
htsmsg_add_str(m, "transmission_mode",
dvb_mode2str(ofdm->transmission_mode));
htsmsg_add_str(m, "guard_interval",
dvb_guard2str(ofdm->guard_interval));
htsmsg_add_str(m, "hierarchy",
dvb_hier2str(ofdm->hierarchy_information));
htsmsg_add_str(m, "fec_hi",
dvb_fec2str(ofdm->code_rate_HP));
htsmsg_add_str(m, "fec_lo",
dvb_fec2str(ofdm->code_rate_LP));
}
static void
dvb_mux_conf_save_dvbc ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
struct dvb_qam_parameters *qam = &dmc->dmc_fe_params.u.qam;
htsmsg_add_u32(m, "symbol_rate", qam->symbol_rate);
htsmsg_add_str(m, "constellation", dvb_qam2str(qam->modulation));
htsmsg_add_str(m, "fec", dvb_fec2str(qam->fec_inner));
}
static void
dvb_mux_conf_save_dvbs ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
struct dvb_qpsk_parameters *qpsk = &dmc->dmc_fe_params.u.qpsk;
htsmsg_add_u32(m, "symbol_rate", qpsk->symbol_rate);
htsmsg_add_str(m, "fec", dvb_fec2str(qpsk->fec_inner));
htsmsg_add_str(m, "polarisation", dvb_pol2str(dmc->dmc_fe_polarisation));
#if DVB_API_VERSION >= 5
htsmsg_add_str(m, "modulation", dvb_qam2str(dmc->dmc_fe_modulation));
htsmsg_add_str(m, "rolloff", dvb_rolloff2str(dmc->dmc_fe_rolloff));
#endif
}
static void
dvb_mux_conf_save_atsc ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
htsmsg_add_str(m, "constellation",
dvb_qam2str(dmc->dmc_fe_params.u.vsb.modulation));
}
void
dvb_mux_conf_save ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m )
{
htsmsg_add_u32(m, "frequency", dmc->dmc_fe_params.frequency);
#if DVB_API_VERSION >= 5
htsmsg_add_str(m, "delsys", dvb_delsys2str(dmc->dmc_fe_delsys));
#endif
if (type == FE_OFDM) dvb_mux_conf_save_dvbt(dmc, m);
else if (type == FE_QAM) dvb_mux_conf_save_dvbc(dmc, m);
else if (type == FE_QPSK) dvb_mux_conf_save_dvbs(dmc, m);
else if (type == FE_ATSC) dvb_mux_conf_save_atsc(dmc, m);
}
#endif /* ENABLE_DVBAPI */

View file

@ -284,6 +284,8 @@ linuxdvb_frontend_monitor ( void *aux )
NULL, "pat", MT_QUICKREQ | MT_CRC, DVB_PAT_PID);
mpegts_table_add(mm, DVB_SDT_BASE, DVB_SDT_MASK, dvb_sdt_callback,
NULL, "sdt", MT_QUICKREQ | MT_CRC, DVB_SDT_PID);
mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback,
NULL, "nit", MT_QUICKREQ | MT_CRC, DVB_NIT_PID);
mpegts_table_add(mm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback,
NULL, "bat", MT_CRC, DVB_BAT_PID);
} else {

View file

@ -91,17 +91,29 @@ const idclass_t linuxdvb_mux_atsc_class =
static void
linuxdvb_mux_config_save ( mpegts_mux_t *mm )
{
linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network;
htsmsg_t *c = htsmsg_create_map();
idnode_save(&mm->mm_id, c);
dvb_mux_conf_save(ln->ln_type, &lm->lm_tuning, c);
hts_settings_save(c, "input/linuxdvb/networks/%s/muxes/%s/config",
idnode_uuid_as_str(&mm->mm_network->mn_id),
idnode_uuid_as_str(&mm->mm_id));
htsmsg_destroy(c);
}
static void
linuxdvb_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len )
{
size_t c = 0;
const char *unit = "Hz";
linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
c = snprintf(buf+c, len-c, "%d %s [%04X:%04X]",
lm->lm_tuning.dmc_fe_params.frequency,
unit, mm->mm_onid, mm->mm_tsid);
linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network;
snprintf(buf, len, "%d %s%s [onid:%04X, tsid:%04X]",
lm->lm_tuning.dmc_fe_params.frequency,
(ln->ln_type == FE_QPSK) ? "MHz " : "Hz",
(ln->ln_type == FE_QPSK)
? dvb_pol2str(lm->lm_tuning.dmc_fe_polarisation)
: "",
mm->mm_onid, mm->mm_tsid);
}
static void
@ -110,15 +122,11 @@ linuxdvb_mux_create_instances ( mpegts_mux_t *mm )
extern const idclass_t mpegts_mux_instance_class;
mpegts_input_t *mi;
mpegts_mux_instance_t *mmi;
tvhtrace("linuxdvb", "mm %p create instances", mm);
LIST_FOREACH(mi, &mm->mm_network->mn_inputs, mi_network_link) {
tvhtrace("linuxdvb", " checking mi %p", mi);
LIST_FOREACH(mmi, &mi->mi_mux_instances, mmi_input_link)
if (mmi->mmi_mux == mm) break;
if (!mmi) {
if (!mmi)
mmi = mpegts_mux_instance_create(mpegts_mux_instance, NULL, mi, mm);
tvhtrace("linuxdvb", " created mmi %p", mmi);
}
// TODO: we might eventually want to keep history!
}
}
@ -180,7 +188,6 @@ linuxdvb_mux_t *
linuxdvb_mux_create1
( linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf )
{
uint32_t u32;
const char *str;
htsmsg_t *c, *e;
htsmsg_field_t *f;
@ -198,7 +205,6 @@ linuxdvb_mux_create1
lm = linuxdvb_mux_create0(ln, MPEGTS_ONID_NONE,
MPEGTS_TSID_NONE, &dmc, uuid);
if (!lm) printf("OH DEAR\n");
if (!lm) return NULL;
/* No config */
@ -206,15 +212,7 @@ linuxdvb_mux_create1
return lm;
/* Config */
// TODO: this could go in mpegts_mux
if (!htsmsg_get_u32(conf, "enabled", &u32) && u32)
lm->mm_enabled = 1;
if (!htsmsg_get_u32(conf, "onid", &u32))
lm->mm_onid = u32;
if (!htsmsg_get_u32(conf, "tsid", &u32))
lm->mm_tsid = u32;
if ((str = htsmsg_get_str(conf, "default_authority")))
lm->mm_dvb_default_authority = strdup(str);
idnode_load(&lm->mm_id, conf);
memcpy(&lm->lm_tuning, &dmc, sizeof(dmc));
/* Services */
@ -228,5 +226,7 @@ linuxdvb_mux_create1
htsmsg_destroy(c);
}
lm->mm_config_save((mpegts_mux_t*)lm);
return lm;
}

View file

@ -31,29 +31,53 @@
#include <fcntl.h>
extern const idclass_t mpegts_network_class;
static const char *
ln_type_getstr ( void *ptr )
{
return dvb_type2str(((linuxdvb_network_t*)ptr)->ln_type);
}
static void
ln_type_setstr ( void *ptr, const char *str )
{
((linuxdvb_network_t*)ptr)->ln_type = dvb_str2type(str);
}
const idclass_t linuxdvb_network_class =
{
.ic_super = &mpegts_network_class,
.ic_class = "linuxdvb_network",
.ic_caption = "LinuxDVB Network",
.ic_properties = (const property_t[]){
#if 0
{ PROPDEF2("type", "Network Type",
PT_STR, linuxdvb_network_t, ln_type, 1),
.get_str },
#endif
.str_get = ln_type_getstr,
.str_set = ln_type_setstr },
{}
}
};
static void
linuxdvb_network_config_save ( mpegts_network_t *mn )
{
htsmsg_t *c = htsmsg_create_map();
idnode_save(&mn->mn_id, c);
hts_settings_save(c, "input/linuxdvb/networks/%s/config",
idnode_uuid_as_str(&mn->mn_id));
htsmsg_destroy(c);
}
static mpegts_mux_t *
linuxdvb_network_find_mux
( linuxdvb_network_t *ln, dvb_mux_conf_t *dmc )
{
#define LINUXDVB_FREQ_TOL 2000 // TODO: fix this!
mpegts_mux_t *mm;
LIST_FOREACH(mm, &ln->mn_muxes, mm_network_link) {
linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
if (abs(lm->lm_tuning.dmc_fe_params.frequency - dmc->dmc_fe_params.frequency) > 2000) continue;
if (abs(lm->lm_tuning.dmc_fe_params.frequency
- dmc->dmc_fe_params.frequency) > LINUXDVB_FREQ_TOL) continue;
if (lm->lm_tuning.dmc_fe_polarisation != dmc->dmc_fe_polarisation) continue;
break;
}
@ -62,12 +86,15 @@ linuxdvb_network_find_mux
static mpegts_mux_t *
linuxdvb_network_create_mux
( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *conf )
( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *dmc )
{
linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network;
mm = linuxdvb_network_find_mux(ln, conf);
if (!mm)
mm = (mpegts_mux_t*)linuxdvb_mux_create0(ln, onid, tsid, conf, NULL);
mm = linuxdvb_network_find_mux(ln, dmc);
if (!mm) {
mm = (mpegts_mux_t*)linuxdvb_mux_create0(ln, onid, tsid, dmc, NULL);
if (mm)
mm->mm_config_save(mm);
}
return mm;
}
@ -78,17 +105,10 @@ linuxdvb_network_create_service
return NULL;
}
static void
linuxdvb_network_config_save ( mpegts_network_t *mn )
{
}
static linuxdvb_network_t *
linuxdvb_network_create0
( const char *uuid, htsmsg_t *conf )
{
uint32_t u32;
const char *str;
linuxdvb_network_t *ln;
htsmsg_t *c, *e;
htsmsg_field_t *f;
@ -107,12 +127,7 @@ linuxdvb_network_create0
return ln;
/* Load configuration */
if ((str = htsmsg_get_str(conf, "type")))
ln->ln_type = dvb_str2type(str);
if ((str = htsmsg_get_str(conf, "name")))
ln->mn_network_name = strdup(str);
if (!htsmsg_get_u32(conf, "nid", &u32))
ln->mn_nid = u32;
idnode_load(&ln->mn_id, conf);
/* Load muxes */
if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes", uuid))) {
@ -123,6 +138,8 @@ linuxdvb_network_create0
}
}
linuxdvb_network_config_save((mpegts_network_t*)ln);
return ln;
}
@ -147,4 +164,5 @@ void linuxdvb_network_init ( void )
(void)linuxdvb_network_create0(f->hmf_name, e);
}
htsmsg_destroy(c);
exit(1);
}

View file

@ -52,42 +52,60 @@ const idclass_t mpegts_mux_class =
.ic_class = "mpegts_mux",
.ic_caption = "MPEGTS Multiplex",
.ic_properties = (const property_t[]){
{ PROPDEF1("enabled", "Enabled",
PT_BOOL, mpegts_mux_t, mm_enabled) },
{ PROPDEF1("onid", "Original Network ID",
PT_INT, mpegts_mux_t, mm_onid) },
PT_INT, mpegts_mux_t, mm_onid) },
{ PROPDEF1("tsid", "Transport Stream ID",
PT_INT, mpegts_mux_t, mm_tsid) },
PT_INT, mpegts_mux_t, mm_tsid) },
{ PROPDEF2("crid_authority", "CRID Authority",
PT_STR, mpegts_mux_t, mm_crid_authority, 1) },
{}
}
};
static void
mpegts_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len )
{
snprintf(buf, len, "Multiplex [onid:%04X tsid:%04X]",
mm->mm_onid, mm->mm_tsid);
}
static void
mpegts_mux_config_save ( mpegts_mux_t *mm )
{
}
static int
mpegts_mux_is_enabled ( mpegts_mux_t *mm )
{
return mm->mm_enabled;
}
int
mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid, int force )
mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid )
{
if (onid == mm->mm_onid)
return 0;
if (!force && mm->mm_onid != MPEGTS_ONID_NONE)
return 0;
mm->mm_onid = onid;
return 1;
}
int
mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force )
mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid )
{
if (tsid == mm->mm_tsid)
return 0;
if (!force && mm->mm_tsid != MPEGTS_TSID_NONE)
return 0;
mm->mm_tsid = tsid;
return 1;
}
int
mpegts_mux_set_default_authority ( mpegts_mux_t *mm, const char *defauth )
mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth )
{
if (defauth && !strcmp(defauth, mm->mm_dvb_default_authority ?: ""))
if (defauth && !strcmp(defauth, mm->mm_crid_authority ?: ""))
return 0;
tvh_str_update(&mm->mm_dvb_default_authority, defauth);
tvh_str_update(&mm->mm_crid_authority, defauth);
return 1;
}
@ -336,6 +354,11 @@ mpegts_mux_create0
mm->mm_network = mn;
mpegts_mux_initial_scan_link(mm);
/* Debug/Config */
mm->mm_display_name = mpegts_mux_display_name;
mm->mm_config_save = mpegts_mux_config_save;
mm->mm_is_enabled = mpegts_mux_is_enabled;
/* Start/stop */
mm->mm_start = mpegts_mux_start;
mm->mm_stop = mpegts_mux_stop;

View file

@ -25,13 +25,28 @@ const idclass_t mpegts_network_class =
.ic_class = "mpegts_network",
.ic_caption = "MPEGTS Network",
.ic_properties = (const property_t[]){
{ PROPDEF1("networkname", "Network Name",
PT_STR, mpegts_network_t, mn_network_name) },
{ PROPDEF1("nid", "Network ID (limit scanning)",
PT_INT, mpegts_network_t, mn_nid) },
{ PROPDEF1("autodiscovery", "Network Discovery",
PT_BOOL, mpegts_network_t, mn_autodiscovery) },
{}
}
};
static void
mpegts_network_display_name
( mpegts_network_t *mn, char *buf, size_t len )
{
strncpy(buf, mn->mn_network_name ?: "unknown", len);
}
static void
mpegts_network_config_save
( mpegts_network_t *mn )
{
// Nothing - leave to child classes
}
static mpegts_mux_t *
@ -41,6 +56,13 @@ mpegts_network_create_mux
return NULL;
}
static mpegts_service_t *
mpegts_network_create_service
( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid )
{
return NULL;
}
static void
mpegts_network_initial_scan(void *aux)
{
@ -76,8 +98,10 @@ mpegts_network_create0
const char *netname )
{
idnode_insert(&mn->mn_id, uuid, idc);
mn->mn_create_mux = mpegts_network_create_mux;
mn->mn_config_save = mpegts_network_config_save;
mn->mn_display_name = mpegts_network_display_name;
mn->mn_config_save = mpegts_network_config_save;
mn->mn_create_mux = mpegts_network_create_mux;
mn->mn_create_service = mpegts_network_create_service;
if (netname) mn->mn_network_name = strdup(netname);
TAILQ_INIT(&mn->mn_initial_scan_pending_queue);
TAILQ_INIT(&mn->mn_initial_scan_current_queue);

View file

@ -53,11 +53,7 @@ prop_write_values(void *obj, const property_t *pl, htsmsg_t *m)
continue;
const property_t *p = prop_find(pl, f->hmf_name);
if(p == NULL) {
fprintf(stderr, "Property %s unmappable\n", f->hmf_name);
continue;
}
if (p->rdonly) {
tvhlog(LOG_WARNING, "prop", "field %s is read-only", p->id);
//fprintf(stderr, "Property %s unmappable\n", f->hmf_name);
continue;
}