* 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 */
* 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) },
}
};
+/*
+ * 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
*/
/*
* 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));
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;
}
/* 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)
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;
}
-
-
{
return val2str(p, bustab);
}
+static int
+devinfo_str2bus ( const char *str )
+{
+ return str2val(str, bustab);
+}
/*
* Get bus information
}
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) },
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));
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;
}
}
}
}
-
+
/* Scan for hardware */
if ((dp = opendir("/dev/dvb"))) {
struct dirent *de;
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) },
* 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 )
{
{
}
-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;
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;
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;
}
/* 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 */
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 )
{
{
}
+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;
/* 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;
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;
}
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
};
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);
#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 );
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
{
/*
* Tuning information
*/
- dvb_mux_conf_t lm_tune_conf;
+ dvb_mux_conf_t lm_tuning;
};
linuxdvb_mux_t *linuxdvb_mux_create0
int i32;
const char *s;
+ if (p->rdonly) return 0;
+
void *val = obj + p->off;
switch(p->type) {