linuxdvb: starting to get config load/save for device tree

I think eventually I will re-work this to one file per entry similar
to the other trees (like network). But this will do for now.
This commit is contained in:
Adam Sutton 2013-05-25 21:46:37 +01:00
parent 5c420b613a
commit 0fbdb43ac2
8 changed files with 299 additions and 42 deletions

View file

@ -252,28 +252,7 @@ struct mpegts_mux
* Fields
*/
char *mm_dvb_default_authority;
#if 0
dvb_mux_conf_t dm_conf;
char *dm_default_authority;
TAILQ_HEAD(, epggrab_ota_mux) dm_epg_grab;
#endif
#if 0 // TODO: do we need this here? or linuxdvb?
struct th_dvb_mux_instance *dm_current_tdmi;
struct th_dvb_mux_instance_list dm_tdmis;
#endif
#if 0 // TODO: what about these?
// Derived from dm_conf (more or less)
char *dm_local_identifier;
int dm_enabled; // TODO: could be derived?
#endif
int mm_enabled;
};
/* Service */

View file

@ -33,11 +33,19 @@
* DVB Adapter
* **************************************************************************/
static void
linuxdvb_adapter_class_save ( idnode_t *in )
{
linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)in;
linuxdvb_device_save((linuxdvb_device_t*)la->lh_parent);
}
const idclass_t linuxdvb_adapter_class =
{
.ic_super = &linuxdvb_hardware_class,
.ic_class = "linuxdvb_adapter",
.ic_caption = "LinuxDVB Adapter",
.ic_save = linuxdvb_adapter_class_save,
.ic_properties = (const property_t[]){
{ PROPDEF2("rootpath", "Device Path",
PT_STR, linuxdvb_adapter_t, la_rootpath, 1) },
@ -45,6 +53,30 @@ const idclass_t linuxdvb_adapter_class =
}
};
/*
* Save data
*/
void
linuxdvb_adapter_save ( linuxdvb_adapter_t *la, htsmsg_t *m )
{
htsmsg_t *l;
linuxdvb_hardware_t *lh;
linuxdvb_hardware_save((linuxdvb_hardware_t*)la, m);
htsmsg_add_u32(m, "number", la->la_number);
if (la->la_rootpath)
htsmsg_add_str(m, "rootpath", la->la_rootpath);
/* Frontends */
l = htsmsg_create_map();
LIST_FOREACH(lh, &la->lh_children, lh_parent_link) {
htsmsg_t *e = htsmsg_create_map();
linuxdvb_frontend_save((linuxdvb_frontend_t*)lh, e);
htsmsg_add_msg(l, idnode_uuid_as_str(&lh->mi_id), e);
}
htsmsg_add_msg(m, "frontends", l);
}
/*
* Check is free
*/
@ -66,9 +98,14 @@ linuxdvb_adapter_current_weight ( linuxdvb_adapter_t *la )
/*
* Create
*/
static linuxdvb_adapter_t *
linuxdvb_adapter_create0 ( const char *uuid, linuxdvb_device_t *ld, int n )
linuxdvb_adapter_t *
linuxdvb_adapter_create0
( linuxdvb_device_t *ld, const char *uuid, htsmsg_t *conf )
{
uint32_t u32;
const char *str;
htsmsg_t *e;
htsmsg_field_t *f;
linuxdvb_adapter_t *la;
la = calloc(1, sizeof(linuxdvb_adapter_t));
@ -76,11 +113,28 @@ linuxdvb_adapter_create0 ( const char *uuid, linuxdvb_device_t *ld, int n )
free(la);
return NULL;
}
la->la_number = n;
LIST_INSERT_HEAD(&ld->lh_children, (linuxdvb_hardware_t*)la, lh_parent_link);
la->lh_parent = (linuxdvb_hardware_t*)ld;
/* No conf */
if (!conf)
return la;
linuxdvb_hardware_load((linuxdvb_hardware_t*)la, conf);
if (!htsmsg_get_u32(conf, "number", &u32))
la->la_number = u32;
if ((str = htsmsg_get_str(conf, "rootpath")))
la->la_rootpath = strdup(str);
/* Frontends */
if ((conf = htsmsg_get_map(conf, "frontends"))) {
HTSMSG_FOREACH(f, conf) {
if (!(e = htsmsg_get_map_by_field(f))) continue;
(void)linuxdvb_frontend_create0(la, f->hmf_name, e, 0);
}
}
return la;
}
@ -110,11 +164,12 @@ linuxdvb_adapter_find_by_number ( int adapter )
/* Create */
if (!la) {
if (!(la = linuxdvb_adapter_create0(NULL, ld, a)))
if (!(la = linuxdvb_adapter_create0(ld, NULL, NULL)))
return NULL;
}
/* Update */
la->la_number = a;
snprintf(buf, sizeof(buf), "/dev/dvb/adapter%d", adapter);
tvh_str_update(&la->la_rootpath, buf);
if (!la->lh_displayname)
@ -181,7 +236,8 @@ linuxdvb_adapter_added ( int adapter )
linuxdvb_frontend_added(la, i, fe_path, dmx_path, dvr_path, &dfi);
}
if (la)
linuxdvb_device_save((linuxdvb_device_t*)la->lh_parent);
return la;
}

View file

@ -48,6 +48,11 @@ devinfo_bus2str ( int p )
{
return val2str(p, bustab);
}
static int
devinfo_str2bus ( const char *str )
{
return str2val(str, bustab);
}
/*
* Get bus information
@ -143,12 +148,70 @@ get_device_info ( device_info_t *di, int a )
}
di->di_id = strdup(buf);
}
static void
get_min_dvb_adapter ( device_info_t *di )
{
int mina = -1;
char path[512];
DIR *dp;
struct dirent *de;
snprintf(path, sizeof(path), "/sys/bus/%s/devices/%s/dvb",
di->di_bus == BUS_PCI ? "pci" : "usb", di->di_path);
/* Find minimum adapter number */
if ((dp = opendir(path))) {
while ((de = readdir(dp))) {
int t;
if ((sscanf(de->d_name, "dvb%d.frontend0", &t)))
if (mina == -1 || t < mina) mina = t;
}
}
di->di_min_adapter = mina;
}
static void
linuxdvb_device_class_save ( idnode_t *in )
{
linuxdvb_device_save((linuxdvb_device_t*)in);
}
void linuxdvb_device_save ( linuxdvb_device_t *ld )
{
htsmsg_t *m, *e, *l;
linuxdvb_hardware_t *lh;
m = htsmsg_create_map();
linuxdvb_hardware_save((linuxdvb_hardware_t*)ld, m);
if (ld->ld_devid.di_id) {
htsmsg_add_str(m, "devid", ld->ld_devid.di_id);
htsmsg_add_str(m, "devbus", devinfo_bus2str(ld->ld_devid.di_bus));
htsmsg_add_str(m, "devpath", ld->ld_devid.di_path);
} else {
printf("OH NO, no device ID\n");
}
/* Adapters */
l = htsmsg_create_map();
LIST_FOREACH(lh, &ld->lh_children, lh_parent_link) {
e = htsmsg_create_map();
linuxdvb_adapter_save((linuxdvb_adapter_t*)lh, e);
htsmsg_add_msg(l, idnode_uuid_as_str(&lh->mi_id), e);
}
htsmsg_add_msg(m, "adapters", l);
/* Save */
hts_settings_save(m, "input/linuxdvb/devices/%s",
idnode_uuid_as_str(&ld->mi_id));
}
const idclass_t linuxdvb_device_class =
{
.ic_super = &linuxdvb_hardware_class,
.ic_class = "linuxdvb_device",
.ic_caption = "LinuxDVB Device",
.ic_save = linuxdvb_device_class_save,
.ic_properties = (const property_t[]){
{ PROPDEF2("devid", "Device ID",
PT_STR, linuxdvb_device_t, ld_devid.di_id, 1) },
@ -170,6 +233,8 @@ linuxdvb_device_create0 ( const char *uuid, htsmsg_t *conf )
uint32_t u32;
const char *str;
linuxdvb_device_t *ld;
htsmsg_t *e;
htsmsg_field_t *f;
/* Create */
ld = calloc(1, sizeof(linuxdvb_device_t));
@ -184,15 +249,26 @@ linuxdvb_device_create0 ( const char *uuid, htsmsg_t *conf )
return ld;
/* Load config */
linuxdvb_hardware_load((linuxdvb_hardware_t*)ld, conf);
if (!htsmsg_get_u32(conf, "enabled", &u32) && u32)
ld->lh_enabled = 1;
if ((str = htsmsg_get_str(conf, "displayname")))
ld->lh_displayname = strdup(str);
if ((str = htsmsg_get_str(conf, "devid")))
strncpy(ld->ld_devid.di_id, str, sizeof(ld->ld_devid.di_id));
ld->ld_devid.di_id = strdup(str);
if ((str = htsmsg_get_str(conf, "devbus")))
ld->ld_devid.di_bus = devinfo_str2bus(str);
if ((str = htsmsg_get_str(conf, "devpath")))
strncpy(ld->ld_devid.di_path, str, sizeof(ld->ld_devid.di_path));
get_min_dvb_adapter(&ld->ld_devid);
// TODO: adapters
// TODO: frontends
/* Adapters */
if ((conf = htsmsg_get_map(conf, "adapters"))) {
HTSMSG_FOREACH(f, conf) {
if (!(e = htsmsg_get_map_by_field(f))) continue;
(void)linuxdvb_adapter_create0(ld, f->hmf_name, e);
}
}
return ld;
}
@ -247,7 +323,7 @@ void linuxdvb_device_init ( int adapter_mask )
}
}
}
/* Scan for hardware */
if ((dp = opendir("/dev/dvb"))) {
struct dirent *de;

View file

@ -39,12 +39,20 @@ linuxdvb_frontend_class_get_title ( idnode_t *in )
return "unknown";
}
static void
linuxdvb_frontend_class_save ( idnode_t *in )
{
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)in;
linuxdvb_device_save((linuxdvb_device_t*)lfe->lh_parent->lh_parent);
}
const idclass_t linuxdvb_frontend_class =
{
.ic_super = &linuxdvb_hardware_class,
.ic_class = "linuxdvb_frontend",
.ic_caption = "Linux DVB Frontend",
.ic_get_title = linuxdvb_frontend_class_get_title,
.ic_save = linuxdvb_frontend_class_save,
.ic_properties = (const property_t[]) {
{ PROPDEF2("fe_path", "Frontend Path",
PT_STR, linuxdvb_frontend_t, lfe_fe_path, 1) },
@ -100,6 +108,19 @@ const idclass_t linuxdvb_frontend_atsc_class =
* Frontend
* *************************************************************************/
void
linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *m )
{
htsmsg_add_u32(m, "number", lfe->lfe_number);
htsmsg_add_str(m, "type", dvb_type2str(lfe->lfe_info.type));
if (lfe->lfe_fe_path)
htsmsg_add_str(m, "fe_path", lfe->lfe_fe_path);
if (lfe->lfe_dmx_path)
htsmsg_add_str(m, "dmx_path", lfe->lfe_dmx_path);
if (lfe->lfe_dvr_path)
htsmsg_add_str(m, "dvr_path", lfe->lfe_dvr_path);
}
static int
linuxdvb_frontend_is_free ( mpegts_input_t *mi )
{
@ -250,12 +271,21 @@ linuxdvb_frontend_close_service
{
}
static linuxdvb_frontend_t *
linuxdvb_frontend_t *
linuxdvb_frontend_create0
( const char *uuid, linuxdvb_adapter_t *la, int num, fe_type_t type )
( linuxdvb_adapter_t *la, const char *uuid, htsmsg_t *conf, fe_type_t type )
{
uint32_t u32;
const char *str;
const idclass_t *idc;
/* Get type */
if (conf) {
if (!(str = htsmsg_get_str(conf, "type")))
return NULL;
type = dvb_str2type(str);
}
/* Class */
if (type == FE_QPSK)
idc = &linuxdvb_frontend_dvbs_class;
@ -273,6 +303,7 @@ linuxdvb_frontend_create0
linuxdvb_frontend_t *lfe
= (linuxdvb_frontend_t*)
mpegts_input_create0(calloc(1, sizeof(linuxdvb_frontend_t)), idc, uuid);
lfe->lfe_info.type = type;
/* Input callbacks */
lfe->mi_start_mux = linuxdvb_frontend_start_mux;
@ -286,6 +317,14 @@ linuxdvb_frontend_create0
lfe->lh_parent = (linuxdvb_hardware_t*)la;
LIST_INSERT_HEAD(&la->lh_children, (linuxdvb_hardware_t*)lfe, lh_parent_link);
/* No conf */
if (!conf)
return lfe;
if (!htsmsg_get_u32(conf, "number", &u32))
lfe->lfe_number = u32;
// TODO: network
return lfe;
}
@ -315,13 +354,14 @@ linuxdvb_frontend_added
/* Create new */
if (!lfe) {
if (!(lfe = linuxdvb_frontend_create0(NULL, la, fe_num, fe_info->type))) {
if (!(lfe = linuxdvb_frontend_create0(la, NULL, NULL, fe_info->type))) {
tvhlog(LOG_ERR, "linuxdvb", "failed to create frontend");
return NULL;
}
}
/* Copy info */
lfe->lfe_number = fe_num;
memcpy(&lfe->lfe_info, fe_info, sizeof(struct dvb_frontend_info));
/* Set paths */

View file

@ -45,6 +45,23 @@ linuxdvb_hardware_enumerate ( linuxdvb_hardware_list_t *list )
return v;
}
void linuxdvb_hardware_save ( linuxdvb_hardware_t *lh, htsmsg_t *m )
{
htsmsg_add_u32(m, "enabled", lh->lh_enabled);
if (lh->lh_displayname)
htsmsg_add_str(m, "displayname", lh->lh_displayname);
}
void linuxdvb_hardware_load ( linuxdvb_hardware_t *lh, htsmsg_t *conf )
{
uint32_t u32;
const char *str;
if (!htsmsg_get_u32(conf, "enabled", &u32) && u32)
lh->lh_enabled = 1;
if ((str = htsmsg_get_str(conf, "displayname")))
lh->lh_displayname = strdup(str);
}
static const char *
linuxdvb_hardware_class_get_title ( idnode_t *in )
{

View file

@ -116,13 +116,64 @@ linuxdvb_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
{
}
static const char *
dvb_mux_conf_load ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m )
{
//const char *s;
dmc->dmc_fe_params.inversion = INVERSION_AUTO;
htsmsg_get_u32(m, "frequency", &dmc->dmc_fe_params.frequency);
#if 0
switch(tda->tda_type) {
case FE_OFDM:
s = htsmsg_get_str(m, "bandwidth");
if(s == NULL || (r = str2val(s, bwtab)) < 0)
return "Invalid bandwidth";
dmc->dmc_fe_params.u.ofdm.bandwidth = r;
s = htsmsg_get_str(m, "constellation");
if(s == NULL || (r = str2val(s, qamtab)) < 0)
return "Invalid QAM constellation";
dmc->dmc_fe_params.u.ofdm.constellation = r;
s = htsmsg_get_str(m, "transmission_mode");
if(s == NULL || (r = str2val(s, modetab)) < 0)
return "Invalid transmission mode";
dmc->dmc_fe_params.u.ofdm.transmission_mode = r;
s = htsmsg_get_str(m, "guard_interval");
if(s == NULL || (r = str2val(s, guardtab)) < 0)
return "Invalid guard interval";
dmc->dmc_fe_params.u.ofdm.guard_interval = r;
s = htsmsg_get_str(m, "hierarchy");
if(s == NULL || (r = str2val(s, hiertab)) < 0)
return "Invalid heirarchy information";
dmc->dmc_fe_params.u.ofdm.hierarchy_information = r;
s = htsmsg_get_str(m, "fec_hi");
if(s == NULL || (r = str2val(s, fectab)) < 0)
return "Invalid hi-FEC";
dmc->dmc_fe_params.u.ofdm.code_rate_HP = r;
s = htsmsg_get_str(m, "fec_lo");
if(s == NULL || (r = str2val(s, fectab)) < 0)
return "Invalid lo-FEC";
dmc->dmc_fe_params.u.ofdm.code_rate_LP = r;
break;
}
#endif
return "Not yet supported";
}
linuxdvb_mux_t *
linuxdvb_mux_create0
( linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf )
{
//uint32_t u32;
//const char *str;
uint32_t u32;
const char *str;
htsmsg_t *c, *e;
htsmsg_field_t *f;
mpegts_mux_t *mm;
linuxdvb_mux_t *lm;
const idclass_t *idc;
@ -151,10 +202,6 @@ linuxdvb_mux_create0
/* Callbacks */
lm->mm_config_save = linuxdvb_mux_config_save;
#if 0
lm->mm_start = linuxdvb_mux_start;
lm->mm_stop = linuxdvb_mux_stop;
#endif
lm->mm_open_table = linuxdvb_mux_open_table;
lm->mm_close_table = linuxdvb_mux_close_table;
@ -163,6 +210,30 @@ linuxdvb_mux_create0
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);
/* Tuning info */
if ((e = htsmsg_get_map(conf, "tuning")))
(void)dvb_mux_conf_load(ln->ln_type, &lm->lm_tuning, e);
/* Services */
if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes/%s/services",
"TODO", uuid))) {
HTSMSG_FOREACH(f, c) {
if (!(e = htsmsg_get_map_by_field(f))) continue;
if (!(e = htsmsg_get_map(e, "config"))) continue;
//(void)linuxdvb_service_create0(lm, f->hmf_name, e);
}
htsmsg_destroy(c);
}
return lm;
}

View file

@ -70,6 +70,8 @@ extern const idclass_t linuxdvb_hardware_class;
idnode_t **
linuxdvb_hardware_enumerate ( linuxdvb_hardware_list_t *list );
void linuxdvb_hardware_save ( linuxdvb_hardware_t *lh, htsmsg_t *m );
void linuxdvb_hardware_load ( linuxdvb_hardware_t *lh, htsmsg_t *m );
struct linuxdvb_device
@ -83,6 +85,7 @@ struct linuxdvb_device
};
void linuxdvb_device_init ( int adapter_mask );
void linuxdvb_device_save ( linuxdvb_device_t *ld );
linuxdvb_device_t *linuxdvb_device_create0
(const char *uuid, htsmsg_t *conf);
@ -103,6 +106,11 @@ struct linuxdvb_adapter
#define LINUXDVB_SUBSYS_FE 0x01
#define LINUXDVB_SUBSYS_DVR 0x02
void linuxdvb_adapter_save ( linuxdvb_adapter_t *la, htsmsg_t *m );
linuxdvb_adapter_t *linuxdvb_adapter_create0
( linuxdvb_device_t *ld, const char *uuid, htsmsg_t *conf );
linuxdvb_adapter_t *linuxdvb_adapter_added (int a);
int linuxdvb_adapter_is_free ( linuxdvb_adapter_t *la );
@ -131,11 +139,19 @@ struct linuxdvb_frontend
gtimer_t lfe_monitor_timer;
};
linuxdvb_frontend_t *
linuxdvb_frontend_create0
( linuxdvb_adapter_t *la, const char *uuid, htsmsg_t *conf, fe_type_t type );
void linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *m );
linuxdvb_frontend_t *
linuxdvb_frontend_added
( linuxdvb_adapter_t *la, int fe_num,
const char *fe_path, const char *dmx_path, const char *dvr_path,
const struct dvb_frontend_info *fe_info );
void linuxdvb_frontend_add_network
( linuxdvb_frontend_t *lfe, linuxdvb_network_t *net );
struct linuxdvb_network
{
@ -157,7 +173,7 @@ struct linuxdvb_mux
/*
* Tuning information
*/
dvb_mux_conf_t lm_tune_conf;
dvb_mux_conf_t lm_tuning;
};
linuxdvb_mux_t *linuxdvb_mux_create0

View file

@ -169,6 +169,8 @@ prop_seti(void *obj, const property_t *p, const char *value)
int i32;
const char *s;
if (p->rdonly) return 0;
void *val = obj + p->off;
switch(p->type) {