diff --git a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c index cd83a284..5b20fd14 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c @@ -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; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_device.c b/src/input/mpegts/linuxdvb/linuxdvb_device.c index 442e8e25..488eb793 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_device.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_device.c @@ -31,7 +31,7 @@ #include /* *************************************************************************** - * 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; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 972b5911..65458296 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -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", diff --git a/src/input/mpegts/linuxdvb/linuxdvb_hardware.c b/src/input/mpegts/linuxdvb/linuxdvb_hardware.c deleted file mode 100644 index 6150f279..00000000 --- a/src/input/mpegts/linuxdvb/linuxdvb_hardware.c +++ /dev/null @@ -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 . - */ - -#include "tvheadend.h" -#include "input.h" -#include "linuxdvb_private.h" -#include "queue.h" - -#include -#include -#include -#include -#include -#include - -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[]){ - {} - } -}; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 3fd165bf..51749b45 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -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__ */ diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index e0dd04f7..a92da65e 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -29,6 +29,185 @@ #include #include +/* ************************************************************************** + * 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",