linuxdvb: started updating to the new hardware API

I actually had this basically working, but then barrelled on with changing
satconf further, without committing anything (got back into old SVN bad habits)
so what's here is a bit of a half finsihed mess
This commit is contained in:
Adam Sutton 2013-10-17 21:39:44 +01:00
parent a1592da5e1
commit 61a96da207
6 changed files with 417 additions and 283 deletions

View file

@ -41,15 +41,34 @@ 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);
linuxdvb_device_save(la->la_device);
}
static idnode_set_t *
linuxdvb_adapter_class_get_childs ( idnode_t *in )
{
linuxdvb_frontend_t *lfe;
linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)in;
idnode_set_t *is = idnode_set_create();
LIST_FOREACH(lfe, &la->la_frontends, lfe_link)
idnode_set_add(is, &lfe->ti_id, NULL);
return is;
}
static const char *
linuxdvb_adapter_class_get_title ( idnode_t *in )
{
linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)in;
return la->la_name ?: la->la_rootpath;
}
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_get_childs = linuxdvb_adapter_class_get_childs,
.ic_get_title = linuxdvb_adapter_class_get_title,
.ic_properties = (const property_t[]){
{
.type = PT_STR,
@ -69,57 +88,21 @@ void
linuxdvb_adapter_save ( linuxdvb_adapter_t *la, htsmsg_t *m )
{
htsmsg_t *l;
linuxdvb_hardware_t *lh;
linuxdvb_frontend_t *lfe;
idnode_save(&la->ti_id, m);
idnode_save(&la->la_id, m);
htsmsg_add_u32(m, "number", la->la_number);
/* Frontends */
l = htsmsg_create_map();
LIST_FOREACH(lh, &la->lh_children, lh_parent_link) {
LIST_FOREACH(lfe, &la->la_frontends, lfe_link) {
htsmsg_t *e = htsmsg_create_map();
linuxdvb_frontend_save((linuxdvb_frontend_t*)lh, e);
htsmsg_add_msg(l, idnode_uuid_as_str(&lh->ti_id), e);
linuxdvb_frontend_save(lfe, e);
htsmsg_add_msg(l, idnode_uuid_as_str(&lfe->ti_id), e);
}
htsmsg_add_msg(m, "frontends", l);
}
/*
* Check is free
*/
int
linuxdvb_adapter_is_free ( linuxdvb_adapter_t *la )
{
return 0;
}
/*
* Get current weight
*/
int
linuxdvb_adapter_current_weight ( linuxdvb_adapter_t *la )
{
return 0;
}
/*
* Enabled
*/
static int
linuxdvb_adapter_is_enabled ( mpegts_input_t *mi )
{
linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)mi;
linuxdvb_hardware_t *lh;
if (la->la_dvb_number == -1)
return 0;
LIST_FOREACH(lh, &la->lh_children, lh_parent_link)
if (lh->mi_is_enabled && lh->mi_is_enabled((mpegts_input_t*)lh))
return 1;
return 0;
}
/*
* Create
*/
@ -133,22 +116,20 @@ linuxdvb_adapter_create0
linuxdvb_adapter_t *la;
la = calloc(1, sizeof(linuxdvb_adapter_t));
if (idnode_insert(&la->ti_id, uuid, &linuxdvb_adapter_class)) {
if (idnode_insert(&la->la_id, uuid, &linuxdvb_adapter_class)) {
free(la);
return NULL;
}
LIST_INSERT_HEAD(&ld->lh_children, (linuxdvb_hardware_t*)la, lh_parent_link);
la->lh_parent = (linuxdvb_hardware_t*)ld;
la->mi_is_enabled = linuxdvb_adapter_is_enabled;
la->mi_enabled = 1;
LIST_INSERT_HEAD(&ld->ld_adapters, la, la_link);
la->la_device = ld;
la->la_dvb_number = -1;
/* No conf */
if (!conf)
return la;
idnode_load(&la->ti_id, conf);
idnode_load(&la->la_id, conf);
if (!htsmsg_get_u32(conf, "number", &u32))
la->la_number = u32;
@ -171,7 +152,6 @@ linuxdvb_adapter_find_by_number ( int adapter )
{
int a;
char buf[1024];
linuxdvb_hardware_t *lh;
linuxdvb_device_t *ld;
linuxdvb_adapter_t *la;
@ -181,11 +161,10 @@ linuxdvb_adapter_find_by_number ( int adapter )
/* Find existing adapter */
a = adapter - ld->ld_devid.di_min_adapter;
LIST_FOREACH(lh, &ld->lh_children, lh_parent_link) {
if (((linuxdvb_adapter_t*)lh)->la_number == a)
LIST_FOREACH(la, &ld->ld_adapters, la_link) {
if (la->la_number == a)
break;
}
la = (linuxdvb_adapter_t*)lh;
/* Create */
if (!la) {
@ -252,10 +231,10 @@ linuxdvb_adapter_added ( int adapter )
return NULL;
}
la->la_dvb_number = adapter;
if (!la->mi_displayname) {
char buf[256];
if (!la->la_name) {
char buf[512];
snprintf(buf, sizeof(buf), "%s #%d", dfi.name, la->la_number);
la->mi_displayname = strdup(buf);
la->la_name = strdup(buf);
}
}
@ -266,7 +245,7 @@ linuxdvb_adapter_added ( int adapter )
}
if (la)
linuxdvb_device_save((linuxdvb_device_t*)la->lh_parent);
linuxdvb_device_save(la->la_device);
return la;
}

View file

@ -31,7 +31,7 @@
#include <fcntl.h>
/* ***************************************************************************
* DVB Device
* Device/BUS Info
* **************************************************************************/
/*
@ -167,42 +167,40 @@ get_min_dvb_adapter ( device_info_t *di )
di->di_min_adapter = mina;
}
/* ***************************************************************************
* Class
* **************************************************************************/
static void
linuxdvb_device_class_save ( idnode_t *in )
{
linuxdvb_device_save((linuxdvb_device_t*)in);
}
void linuxdvb_device_save ( linuxdvb_device_t *ld )
static const char *
linuxdvb_device_class_get_title ( idnode_t *in )
{
htsmsg_t *m, *e, *l;
linuxdvb_hardware_t *lh;
return ((linuxdvb_device_t*)in)->ld_devid.di_id;
}
m = htsmsg_create_map();
idnode_save(&ld->ti_id, m);
/* 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->ti_id), e);
}
htsmsg_add_msg(m, "adapters", l);
/* Save */
hts_settings_save(m, "input/linuxdvb/devices/%s",
idnode_uuid_as_str(&ld->ti_id));
htsmsg_destroy(m);
static idnode_set_t *
linuxdvb_device_class_get_childs ( idnode_t *in )
{
linuxdvb_adapter_t *la;
linuxdvb_device_t *ld = (linuxdvb_device_t*)in;
idnode_set_t *is = idnode_set_create();
LIST_FOREACH(la, &ld->ld_adapters, la_link)
idnode_set_add(is, &la->la_id, NULL);
return is;
}
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_get_childs = linuxdvb_device_class_get_childs,
.ic_get_title = linuxdvb_device_class_get_title,
.ic_properties = (const property_t[]){
{
.type = PT_STR,
@ -215,14 +213,31 @@ const idclass_t linuxdvb_device_class =
}
};
static linuxdvb_hardware_list_t linuxdvb_device_all;
idnode_set_t *
linuxdvb_root ( void )
void linuxdvb_device_save ( linuxdvb_device_t *ld )
{
return linuxdvb_hardware_enumerate(&linuxdvb_device_all);
htsmsg_t *m, *e, *l;
linuxdvb_adapter_t *la;
m = htsmsg_create_map();
idnode_save(&ld->th_id, m);
/* Adapters */
l = htsmsg_create_map();
LIST_FOREACH(la, &ld->ld_adapters, la_link) {
e = htsmsg_create_map();
linuxdvb_adapter_save(la, e);
htsmsg_add_msg(l, idnode_uuid_as_str(&la->la_id), e);
}
htsmsg_add_msg(m, "adapters", l);
/* Save */
hts_settings_save(m, "input/linuxdvb/devices/%s",
idnode_uuid_as_str(&ld->th_id));
htsmsg_destroy(m);
}
linuxdvb_device_t *
linuxdvb_device_create0 ( const char *uuid, htsmsg_t *conf )
{
@ -232,21 +247,18 @@ linuxdvb_device_create0 ( const char *uuid, htsmsg_t *conf )
/* Create */
ld = calloc(1, sizeof(linuxdvb_device_t));
if (idnode_insert(&ld->ti_id, uuid, &linuxdvb_device_class)) {
if (idnode_insert(&ld->th_id, uuid, &linuxdvb_device_class)) {
free(ld);
return NULL;
}
LIST_INSERT_HEAD(&linuxdvb_device_all, (linuxdvb_hardware_t*)ld, lh_parent_link);
/* Defaults */
ld->mi_enabled = 1;
LIST_INSERT_HEAD(&tvh_hardware, (tvh_hardware_t*)ld, th_link);
/* No config */
if (!conf)
return ld;
/* Load config */
idnode_load(&ld->ti_id, conf);
idnode_load(&ld->th_id, conf);
get_min_dvb_adapter(&ld->ld_devid);
/* Adapters */
@ -263,11 +275,11 @@ linuxdvb_device_create0 ( const char *uuid, htsmsg_t *conf )
static linuxdvb_device_t *
linuxdvb_device_find_by_hwid ( const char *hwid )
{
linuxdvb_hardware_t *lh;
LIST_FOREACH(lh, &linuxdvb_device_all, lh_parent_link) {
if (!strcmp(hwid, ((linuxdvb_device_t*)lh)->ld_devid.di_id ?: ""))
return (linuxdvb_device_t*)lh;
tvh_hardware_t *lh;
LIST_FOREACH(lh, &tvh_hardware, th_link) {
if (idnode_is_instance(&lh->th_id, &linuxdvb_device_class))
if (!strcmp(hwid, ((linuxdvb_device_t*)lh)->ld_devid.di_id ?: ""))
return (linuxdvb_device_t*)lh;
}
return NULL;
}
@ -302,7 +314,6 @@ linuxdvb_device_find_by_adapter ( int a )
/* Copy device info */
memcpy(&ld->ld_devid, &dev, sizeof(dev));
ld->mi_displayname = strdup(dev.di_id);
ld->ld_devid.di_id = dev.di_id;
return ld;
}

View file

@ -40,14 +40,12 @@ linuxdvb_frontend_input_thread ( void *aux );
* Class definition
* *************************************************************************/
extern const idclass_t linuxdvb_hardware_class;
static void
linuxdvb_frontend_class_save ( idnode_t *in )
{
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)in;
if (lfe->lh_parent && lfe->lh_parent->lh_parent)
linuxdvb_device_save((linuxdvb_device_t*)lfe->lh_parent->lh_parent);
if (lfe->lfe_adapter && lfe->lfe_adapter->la_device)
linuxdvb_device_save(lfe->lfe_adapter->la_device);
}
static const void*
@ -104,7 +102,7 @@ linuxdvb_frontend_class_network_enum(void *o)
const idclass_t linuxdvb_frontend_class =
{
.ic_super = &linuxdvb_hardware_class,
.ic_super = &mpegts_input_class,
.ic_class = "linuxdvb_frontend",
.ic_caption = "Linux DVB Frontend",
.ic_save = linuxdvb_frontend_class_save,
@ -171,12 +169,54 @@ const idclass_t linuxdvb_frontend_dvbt_class =
}
};
static idnode_set_t *
linuxdvb_frontend_dvbs_class_get_childs ( idnode_t *self )
{
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)self;
idnode_set_t *is = idnode_set_create();
idnode_set_add(is, &lfe->lfe_satconf->ls_id, NULL);
return is;
}
static int
linuxdvb_frontend_dvbs_class_satconf_set ( void *self, const void *str )
{
linuxdvb_frontend_t *lfe = self;
if (!strcmp(str ?: "", lfe->lfe_satconf->ls_type))
return 0;
linuxdvb_satconf_destroy(lfe->lfe_satconf);
lfe->lfe_satconf = linuxdvb_satconf_create(lfe, str);
return 1;
}
static const void *
linuxdvb_frontend_dvbs_class_satconf_get ( void *self )
{
linuxdvb_frontend_t *lfe = self;
return &lfe->lfe_satconf->ls_type;
}
static htsmsg_t *
linuxdvb_frontend_dvbs_class_satconf_list ( void *self )
{
return linuxdvb_satconf_types();
}
const idclass_t linuxdvb_frontend_dvbs_class =
{
.ic_super = &linuxdvb_frontend_class,
.ic_class = "linuxdvb_frontend_dvbs",
.ic_caption = "Linux DVB-S Frontend",
.ic_get_childs = linuxdvb_frontend_dvbs_class_get_childs,
.ic_properties = (const property_t[]){
{
.type = PT_STR,
.id = "satconf",
.name = "SatConfig",
.set = linuxdvb_frontend_dvbs_class_satconf_set,
.get = linuxdvb_frontend_dvbs_class_satconf_get,
.list = linuxdvb_frontend_dvbs_class_satconf_list,
},
{}
}
};
@ -231,30 +271,6 @@ linuxdvb_frontend_is_enabled ( mpegts_input_t *mi )
return 1;
}
#if 0
static int
linuxdvb_frontend_is_free ( mpegts_input_t *mi )
{
#if 0
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
linuxdvb_adapter_t *la = lfe->lfe_adapter;
return linuxdvb_adapter_is_free(la);
#endif
return 0;
}
static int
linuxdvb_frontend_current_weight ( mpegts_input_t *mi )
{
#if 0
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
linuxdvb_adapter_t *la = lfe->lfe_adapter;
return linuxdvb_adapter_current_weight(la);
#endif
return 0;
}
#endif
static void
linuxdvb_frontend_stop_mux
( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
@ -833,8 +849,8 @@ linuxdvb_frontend_create0
lfe->mi_open_pid = linuxdvb_frontend_open_pid;
/* Adapter link */
lfe->lh_parent = (linuxdvb_hardware_t*)la;
LIST_INSERT_HEAD(&la->lh_children, (linuxdvb_hardware_t*)lfe, lh_parent_link);
lfe->lfe_adapter = la;
LIST_INSERT_HEAD(&la->la_frontends, lfe, lfe_link);
/* DVR lock/cond */
pthread_mutex_init(&lfe->lfe_dvr_lock, NULL);
@ -858,12 +874,10 @@ linuxdvb_frontend_added
const char *dvr_path,
const struct dvb_frontend_info *fe_info )
{
linuxdvb_hardware_t *lh;
linuxdvb_frontend_t *lfe = NULL;
/* Find existing */
LIST_FOREACH(lh, &la->lh_children, lh_parent_link) {
lfe = (linuxdvb_frontend_t*)lh;
LIST_FOREACH(lfe, &la->la_frontends, lfe_link) {
if (lfe->lfe_number == fe_num) {
if (lfe->lfe_info.type != fe_info->type) {
tvhlog(LOG_ERR, "linuxdvb", "detected incorrect fe_type %s != %s",

View file

@ -1,58 +0,0 @@
/*
* Tvheadend - Linux DVB hardware class
*
* Copyright (C) 2013 Adam Sutton
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tvheadend.h"
#include "input.h"
#include "linuxdvb_private.h"
#include "queue.h"
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
idnode_set_t *
linuxdvb_hardware_enumerate ( linuxdvb_hardware_list_t *list )
{
linuxdvb_hardware_t *lh;
idnode_set_t *set = idnode_set_create();
LIST_FOREACH(lh, list, lh_parent_link)
idnode_set_add(set, &lh->ti_id, NULL);
return set;
}
static idnode_set_t *
linuxdvb_hardware_class_get_childs ( idnode_t *in )
{
return linuxdvb_hardware_enumerate(&((linuxdvb_hardware_t*)in)->lh_children);
}
extern const idclass_t mpegts_input_class;
const idclass_t linuxdvb_hardware_class =
{
.ic_super = &mpegts_input_class,
.ic_class = "linuxdvb_hardware",
.ic_caption = "LinuxDVB Hardware",
.ic_get_childs = linuxdvb_hardware_class_get_childs,
.ic_properties = (const property_t[]){
{}
}
};

View file

@ -26,12 +26,18 @@ typedef struct linuxdvb_hardware linuxdvb_hardware_t;
typedef struct linuxdvb_device linuxdvb_device_t;
typedef struct linuxdvb_adapter linuxdvb_adapter_t;
typedef struct linuxdvb_frontend linuxdvb_frontend_t;
typedef struct linuxdvb_satconf linuxdvb_satconf_t;
typedef struct linuxdvb_diseqc linuxdvb_diseqc_t;
typedef struct linuxdvb_lnb linuxdvb_lnb_t;
typedef struct linuxdvb_network linuxdvb_network_t;
typedef struct linuxdvb_mux linuxdvb_mux_t;
typedef struct linuxdvb_satconf linuxdvb_satconf_t;
typedef LIST_HEAD(,linuxdvb_hardware) linuxdvb_hardware_list_t;
/*
* Hardware tree objects
*/
typedef struct device_info
{
char *di_id;
@ -47,74 +53,54 @@ typedef struct device_info
int di_min_adapter;
} device_info_t;
struct linuxdvb_hardware
{
mpegts_input_t; // Note: this is redundant in many of the instances
// but we can't do multiple-inheritance and this
// keeps some of the code clean
/*
* Parent/Child links
*/
linuxdvb_hardware_t *lh_parent;
LIST_ENTRY(linuxdvb_hardware) lh_parent_link;
linuxdvb_hardware_list_t lh_children;
};
extern const idclass_t linuxdvb_hardware_class;
idnode_set_t *linuxdvb_hardware_enumerate
( linuxdvb_hardware_list_t *list );
struct linuxdvb_device
{
linuxdvb_hardware_t;
tvh_hardware_t;
/*
* Device info
*/
device_info_t ld_devid;
device_info_t ld_devid;
/*
* Adapters
*/
LIST_HEAD(,linuxdvb_adapter) ld_adapters;
};
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);
linuxdvb_device_t * linuxdvb_device_find_by_adapter ( int a );
struct linuxdvb_adapter
{
linuxdvb_hardware_t;
idnode_t la_id;
/*
* Link to device
*/
linuxdvb_device_t *la_device;
LIST_ENTRY(linuxdvb_adapter) la_link;
/*
* Adapter info
*/
char *la_name;
char *la_rootpath;
uint32_t la_number;
int la_dvb_number;
/*
* Frontends
*/
LIST_HEAD(,linuxdvb_frontend) la_frontends;
};
#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 );
int linuxdvb_adapter_current_weight ( linuxdvb_adapter_t *la );
linuxdvb_adapter_t *linuxdvb_adapter_find_by_hwid ( const char *hwid );
linuxdvb_adapter_t *linuxdvb_adapter_find_by_path ( const char *path );
struct linuxdvb_frontend
{
linuxdvb_hardware_t;
mpegts_input_t;
/*
* Adapter
*/
linuxdvb_adapter_t *lfe_adapter;
LIST_ENTRY(linuxdvb_frontend) lfe_link;
/*
* Frontend info
@ -146,8 +132,65 @@ struct linuxdvb_frontend
*/
int lfe_fullmux;
int lfe_noclosefe;
/*
* Satconf (DVB-S only)
*/
linuxdvb_satconf_t *lfe_satconf;
};
struct linuxdvb_satconf
{
idnode_t ls_id;
const char *ls_type;
};
struct linuxdvb_diseqc
{
idnode_t ld_id;
const char *ld_type;
linuxdvb_satconf_t *ld_satconf;
int (*ld_grace) (linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm);
int (*ld_tune) (linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm,
linuxdvb_satconf_t *ls, int fd);
};
struct linuxdvb_lnb
{
linuxdvb_diseqc_t;
uint32_t (*lnb_freq)(linuxdvb_lnb_t*, linuxdvb_mux_t*);
int (*lnb_band)(linuxdvb_lnb_t*, linuxdvb_mux_t*);
int (*lnb_pol) (linuxdvb_lnb_t*, linuxdvb_mux_t*);
};
/*
* Methods
*/
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);
linuxdvb_device_t * linuxdvb_device_find_by_adapter ( int a );
#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 );
int linuxdvb_adapter_current_weight ( linuxdvb_adapter_t *la );
linuxdvb_adapter_t *linuxdvb_adapter_find_by_hwid ( const char *hwid );
linuxdvb_adapter_t *linuxdvb_adapter_find_by_path ( const char *path );
linuxdvb_frontend_t *
linuxdvb_frontend_create0
( linuxdvb_adapter_t *la, const char *uuid, htsmsg_t *conf, fe_type_t type );
@ -215,26 +258,7 @@ mpegts_service_t *linuxdvb_service_create0
/*
* Diseqc gear
*/
typedef struct linuxdvb_diseqc linuxdvb_diseqc_t;
typedef struct linuxdvb_lnb linuxdvb_lnb_t;
struct linuxdvb_diseqc
{
idnode_t ld_id;
const char *ld_type;
linuxdvb_satconf_t *ld_satconf;
int (*ld_grace) (linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm);
int (*ld_tune) (linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm,
linuxdvb_satconf_t *ls, int fd);
};
struct linuxdvb_lnb
{
linuxdvb_diseqc_t;
uint32_t (*lnb_freq)(linuxdvb_lnb_t*, linuxdvb_mux_t*);
int (*lnb_band)(linuxdvb_lnb_t*, linuxdvb_mux_t*);
int (*lnb_pol) (linuxdvb_lnb_t*, linuxdvb_mux_t*);
};
linuxdvb_diseqc_t *linuxdvb_diseqc_create0
( linuxdvb_diseqc_t *ld, const char *uuid, const idclass_t *idc,
@ -269,22 +293,6 @@ int linuxdvb_diseqc_set_volt (int fd, int volt);
/*
* Satconf
*/
struct linuxdvb_satconf
{
linuxdvb_frontend_t;
mpegts_input_t *ls_frontend;
mpegts_mux_instance_t *ls_mmi;
/* Diseqc gear */
linuxdvb_lnb_t *ls_lnb;
linuxdvb_diseqc_t *ls_switch;
linuxdvb_diseqc_t *ls_rotor;
gtimer_t ls_diseqc_timer;
int ls_diseqc_idx;
int ls_diseqc_repeats;
};
void linuxdvb_satconf_init ( void );
@ -292,4 +300,11 @@ linuxdvb_satconf_t *linuxdvb_satconf_create0(const char *uuid, htsmsg_t *conf);
void linuxdvb_satconf_delete ( linuxdvb_satconf_t *ls );
htsmsg_t *linuxdvb_satconf_types ( void );
linuxdvb_satconf_t *linuxdvb_satconf_create
( linuxdvb_frontend_t *lfe, const char *type );
void linuxdvb_satconf_destroy ( linuxdvb_satconf_t *ls );
#endif /* __TVH_LINUXDVB_PRIVATE_H__ */

View file

@ -29,6 +29,185 @@
#include <assert.h>
#include <linux/dvb/dmx.h>
/* **************************************************************************
* Types
* *************************************************************************/
/*
* Generic satconf
*/
const idclass_t linuxdvb_satconf_class
{
};
/*
* Simple LNB only
*/
const idclass_t linuxdvb_satconf_lnbonly_class
{
.ic_class = "linuxdvb_satconf_lnbonly",
.ic_caption = "DVB-S Simple",
.ic_properties = (const property_t[]) {
{
.type = PT_STR,
.id = "network",
.name = "Network",
.get = linuxdvb_satconf_class_network_get,
.set = linuxdvb_satconf_class_network_set,
.list = linuxdvb_satconf_class_network_list
},
{}
}
};
/*
* 2 port switch
*/
const idclass_t linuxdvb_satconf_2port_class
{
.ic_class = "linuxdvb_satconf_2port",
.ic_caption = "DVB-S Toneburst",
.ic_properties = (const property_t[]) {
{
.type = PT_STR,
.id = "network_a",
.name = "A",
.get = linuxdvb_satconf_class_network_a_get,
.set = linuxdvb_satconf_class_network_a_set,
.list = linuxdvb_satconf_class_network_list
},
{
.type = PT_STR,
.id = "network_b",
.name = "B",
.get = linuxdvb_satconf_class_network_b_get,
.set = linuxdvb_satconf_class_network_b_set,
.list = linuxdvb_satconf_class_network_list
},
{}
}
};
/*
* 4 port switch
*/
const idclass_t linuxdvb_satconf_4port_class
{
.ic_class = "linuxdvb_satconf_2port",
.ic_caption = "DVB-S Toneburst",
.ic_properties = (const property_t[]) {
{
.type = PT_STR,
.id = "network_aa",
.name = "AA",
.get = linuxdvb_satconf_class_network_aa_get,
.set = linuxdvb_satconf_class_network_aa_set,
.list = linuxdvb_satconf_class_network_list
},
{
.type = PT_STR,
.id = "network_ab",
.name = "AB",
.get = linuxdvb_satconf_class_network_ab_get,
.set = linuxdvb_satconf_class_network_ab_set,
.list = linuxdvb_satconf_class_network_list
},
{
.type = PT_STR,
.id = "network_ba",
.name = "BA",
.get = linuxdvb_satconf_class_network_ba_get,
.set = linuxdvb_satconf_class_network_ba_set,
.list = linuxdvb_satconf_class_network_list
},
{
.type = PT_STR,
.id = "network_bb`",
.name = "BB",
.get = linuxdvb_satconf_class_network_bb_get,
.set = linuxdvb_satconf_class_network_bb_set,
.list = linuxdvb_satconf_class_network_list
},
{}
}
};
/*
* Advanced
*/
const idclass_t linuxdvb_
const idclass_t linuxdvb_satconf_advanced_ele_class
{
.ic_class = "linuxdvb_satconf_advanced",
.ic_caption = "DVB-S Advanced",
.ic_get_title = linuxdvb_satconf_class_get_title,
.ic_get_childs = linuxdvb_satconf_class_get_childs,
.ic_save = linuxdvb_satconf_class_save,
.ic_delete = linuxdvb_satconf_class_delete,
.ic_properties = (const property_t[]) {
{
.type = PT_STR,
.id = "network",
.name = "Network",
.get = linuxdvb_satconf_class_network_get,
.set = linuxdvb_satconf_class_network_set,
.list = linuxdvb_satconf_class_network_enum,
.rend = linuxdvb_satconf_class_network_rend,
},
{
.type = PT_INT,
.id = "diseqc_repeats",
.name = "DiseqC repeats",
.off = offsetof(linuxdvb_satconf_t, ls_diseqc_repeats),
.def.i = 0
},
{
.type = PT_STR,
.id = "lnb_type",
.name = "LNB Type",
.set = linuxdvb_satconf_class_lnbtype_set,
.get = linuxdvb_satconf_class_lnbtype_get,
.list = linuxdvb_lnb_list,
.def.s = "Universal",
},
{
.type = PT_STR,
.id = "switch_type",
.name = "Switch Type",
.set = linuxdvb_satconf_class_switchtype_set,
.get = linuxdvb_satconf_class_switchtype_get,
.list = linuxdvb_switch_list,
.def.s = "None",
},
{
.type = PT_STR,
.id = "rotor_type",
.name = "Rotor Type",
.set = linuxdvb_satconf_class_rotortype_set,
.get = linuxdvb_satconf_class_rotortype_get,
.list = linuxdvb_rotor_list,
.def.s = "None",
},
{}
}
};
/* **************************************************************************
* Objects
* *************************************************************************/
typedef struct linuxdvb_satconf_t
{
idnode_t ls_id;
/* Sub-elements */
};
/* **************************************************************************
* Class definition
* *************************************************************************/
@ -121,8 +300,11 @@ linuxdvb_satconf_class_frontend_set ( void *o, const void *v )
const char *u = v;
mpegts_input_t *lfe = idnode_find(u, &linuxdvb_frontend_dvbs_class);
if (lfe && ls->ls_frontend != lfe) {
// TODO: I probably need to clean up the existing linkages
if (ls->ls_frontend)
LIST_REMOVE(ls, ls_link);
ls->ls_frontend = lfe;
if (lfe)
LIST_INSERT_HEAD(&((linuxdvb_frontend_t*)lfe)->lfe_satconfs, ls, ls_link);
return 1;
}
return 0;
@ -244,8 +426,8 @@ linuxdvb_satconf_class_get_title ( idnode_t *o )
{
static char buf[128];
linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)o;
if (ls->mi_display_name)
ls->mi_display_name((mpegts_input_t*)ls, buf, sizeof(buf));
if (ls->mi_network)
ls->mi_network->mn_display_name(ls->mi_network, buf, sizeof(buf));
else
*buf = 0;
return buf;
@ -281,15 +463,6 @@ const idclass_t linuxdvb_satconf_class =
.ic_save = linuxdvb_satconf_class_save,
.ic_delete = linuxdvb_satconf_class_delete,
.ic_properties = (const property_t[]) {
{
.type = PT_STR,
.id = "frontend",
.name = "Frontend",
.get = linuxdvb_satconf_class_frontend_get,
.set = linuxdvb_satconf_class_frontend_set,
.list = linuxdvb_satconf_class_frontend_enum,
.rend = linuxdvb_satconf_class_frontend_rend,
},
{
.type = PT_STR,
.id = "network",