From a622f4fffa0906c22af9fa114046b360f144984c Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Sun, 27 Oct 2013 21:00:33 +0000 Subject: [PATCH] linuxdvb: WIP - comitting before I lose it! --- src/api/api_mpegts.c | 2 +- src/descrambler/capmt.c | 8 +- src/input/mpegts/linuxdvb/linuxdvb.c | 3 - src/input/mpegts/linuxdvb/linuxdvb_frontend.c | 31 +- src/input/mpegts/linuxdvb/linuxdvb_lnb.c | 6 +- src/input/mpegts/linuxdvb/linuxdvb_private.h | 92 ++- src/input/mpegts/linuxdvb/linuxdvb_rotor.c | 12 +- src/input/mpegts/linuxdvb/linuxdvb_satconf.c | 659 +++++++++++------- src/input/mpegts/linuxdvb/linuxdvb_switch.c | 23 +- src/input/mpegts/tsdemux.c | 22 +- 10 files changed, 532 insertions(+), 326 deletions(-) diff --git a/src/api/api_mpegts.c b/src/api/api_mpegts.c index 8af61049..f67b9a94 100644 --- a/src/api/api_mpegts.c +++ b/src/api/api_mpegts.c @@ -281,7 +281,7 @@ api_linuxdvb_satconf_create return -EINVAL; pthread_mutex_lock(&global_lock); - in = (idnode_t*)linuxdvb_satconf_create0(NULL, conf); + in = NULL;//TODO:(idnode_t*)linuxdvb_satconf_create0(NULL, conf); if (in) { err = 0; in->in_class->ic_save(in); diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index 9f00be80..af962b67 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -584,8 +584,10 @@ capmt_thread(void *aux) idnode_set_t *is = idnode_find_all(&linuxdvb_adapter_class); for (i = 0; i < is->is_count; i++) { la = (linuxdvb_adapter_t*)is->is_array[i]; +#if 0 if (!la || !la->mi_is_enabled) continue; if (!la->mi_is_enabled((mpegts_input_t*)la)) continue; +#endif if (la->la_dvb_number > MAX_CA) { tvhlog(LOG_ERR, "capmt", "adapter number > MAX_CA"); continue; @@ -646,7 +648,7 @@ capmt_table_input(struct th_descrambler *td, struct service *s, capmt_t *capmt = ct->ct_capmt; mpegts_service_t *t = (mpegts_service_t*)s; linuxdvb_frontend_t *lfe; - int adapter_num; + int adapter_num = -1; int total_caids = 0, current_caid = 0; /* Validate */ @@ -656,7 +658,7 @@ capmt_table_input(struct th_descrambler *td, struct service *s, lfe = (linuxdvb_frontend_t*)t->s_dvb_active_input; if (!idnode_is_instance(&lfe->ti_id, &linuxdvb_frontend_class)) return; - adapter_num = ((linuxdvb_adapter_t*)lfe->lh_parent)->la_dvb_number; + //adapter_num = ((linuxdvb_adapter_t*)lfe->lh_parent)->la_dvb_number; caid_t *c; @@ -895,7 +897,7 @@ capmt_service_start(service_t *s) lfe = (linuxdvb_frontend_t*)t->s_dvb_active_input; if (!idnode_is_instance(&lfe->ti_id, &linuxdvb_frontend_class)) return; - tuner = ((linuxdvb_adapter_t*)lfe->lh_parent)->la_dvb_number; + //tuner = ((linuxdvb_adapter_t*)lfe->lh_parent)->la_dvb_number; TAILQ_FOREACH(capmt, &capmts, capmt_link) { /* skip, if we're not active */ diff --git a/src/input/mpegts/linuxdvb/linuxdvb.c b/src/input/mpegts/linuxdvb/linuxdvb.c index fca78181..cf0e76ec 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb.c +++ b/src/input/mpegts/linuxdvb/linuxdvb.c @@ -33,7 +33,4 @@ void linuxdvb_init ( int adapter_mask ) /* Initialsie devices */ linuxdvb_device_init(adapter_mask); - - /* Initialise satconfs */ - linuxdvb_satconf_init(); } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 65458296..ae536cd6 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -182,7 +182,7 @@ 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)) + if (lfe->lfe_satconf && !strcmp(str ?: "", lfe->lfe_satconf->ls_type)) return 0; linuxdvb_satconf_destroy(lfe->lfe_satconf); lfe->lfe_satconf = linuxdvb_satconf_create(lfe, str); @@ -192,14 +192,13 @@ linuxdvb_frontend_dvbs_class_satconf_set ( void *self, const void *str ) static const void * linuxdvb_frontend_dvbs_class_satconf_get ( void *self ) { + static const char *s; 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(); + if (lfe->lfe_satconf) + s = lfe->lfe_satconf->ls_type; + else + s = NULL; + return &s; } const idclass_t linuxdvb_frontend_dvbs_class = @@ -213,9 +212,11 @@ const idclass_t linuxdvb_frontend_dvbs_class = .type = PT_STR, .id = "satconf", .name = "SatConfig", + .opts = PO_NOSAVE, .set = linuxdvb_frontend_dvbs_class_satconf_set, .get = linuxdvb_frontend_dvbs_class_satconf_get, - .list = linuxdvb_frontend_dvbs_class_satconf_list, + .list = linuxdvb_satconf_type_list, + .def.s = "simple" }, {} } @@ -859,6 +860,10 @@ linuxdvb_frontend_create0 /* Start table thread */ tvhthread_create(&tid, NULL, mpegts_input_table_thread, lfe, 1); + /* Create satconf */ + if (type == FE_QPSK && !lfe->lfe_satconf) + lfe->lfe_satconf = linuxdvb_satconf_create(lfe, ""); + /* No conf */ if (!conf) return lfe; @@ -920,6 +925,14 @@ linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *m ) { mpegts_input_save((mpegts_input_t*)lfe, m); htsmsg_add_str(m, "type", dvb_type2str(lfe->lfe_info.type)); +htsmsg_print(m); + if (lfe->lfe_satconf) { + htsmsg_t *s = htsmsg_create_map(); + linuxdvb_satconf_save(lfe->lfe_satconf, s); + htsmsg_add_str(s, "uuid", idnode_uuid_as_str(&lfe->lfe_satconf->ls_id)); + htsmsg_add_msg(m, "satconf", s); + } +htsmsg_print(m); } /****************************************************************************** diff --git a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c index a668ed0b..78acb203 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c @@ -103,7 +103,7 @@ linuxdvb_lnb_standard_pol static int linuxdvb_lnb_standard_tune - ( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, linuxdvb_satconf_t *ls, int fd ) + ( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd ) { int pol = linuxdvb_lnb_standard_pol((linuxdvb_lnb_t*)ld, lm); return linuxdvb_diseqc_set_volt(fd, pol); @@ -148,7 +148,7 @@ linuxdvb_lnb_bandstack_pol static int linuxdvb_lnb_bandstack_tune - ( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, linuxdvb_satconf_t *ls, int fd ) + ( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd ) { int pol = linuxdvb_lnb_bandstack_pol((linuxdvb_lnb_t*)ld, lm); return linuxdvb_diseqc_set_volt(fd, pol); @@ -257,7 +257,7 @@ linuxdvb_lnb_list ( void *o ) linuxdvb_lnb_t * linuxdvb_lnb_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ) + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls ) { int i; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 51749b45..92f7addf 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -22,15 +22,16 @@ #include "input/mpegts.h" -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_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_satconf_ele linuxdvb_satconf_ele_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 LIST_HEAD(,linuxdvb_hardware) linuxdvb_hardware_list_t; @@ -143,16 +144,61 @@ struct linuxdvb_satconf { idnode_t ls_id; const char *ls_type; + + /* + * MPEG-TS hooks + */ + mpegts_input_t *ls_frontend; ///< Frontend we're proxying for + mpegts_mux_instance_t *ls_mmi; ///< Used within delay diseqc handler + + /* + * Diseqc handling + */ + gtimer_t ls_diseqc_timer; + int ls_diseqc_idx; + int ls_diseqc_repeats; + + /* + * Satconf elements + */ + LIST_HEAD(,linuxdvb_satconf_ele) ls_elements; +}; + +/* + * Internal wrapper for a satconf entry + * + * Note: this is a bit cumbersome, it comes from how I first did the satconf + * and was subsequently bullied (by amet) into changing it (probably + * for the better, just don't tell him, no danger he'll read this!) + * + * maybe one day I'll do it again properly + */ +struct linuxdvb_satconf_ele +{ + mpegts_input_t; // This acts as proxy for the frontend + + /* + * Parent + */ + linuxdvb_satconf_t *ls_parent; + LIST_ENTRY(linuxdvb_satconf_ele) ls_link; + + /* + * Diseqc kit + */ + linuxdvb_lnb_t *ls_lnb; + linuxdvb_diseqc_t *ls_switch; + linuxdvb_diseqc_t *ls_rotor; }; struct linuxdvb_diseqc { idnode_t ld_id; const char *ld_type; - linuxdvb_satconf_t *ld_satconf; + linuxdvb_satconf_ele_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); + linuxdvb_satconf_ele_t *ls, int fd); }; struct linuxdvb_lnb @@ -258,11 +304,9 @@ mpegts_service_t *linuxdvb_service_create0 /* * Diseqc gear */ - - linuxdvb_diseqc_t *linuxdvb_diseqc_create0 ( linuxdvb_diseqc_t *ld, const char *uuid, const idclass_t *idc, - htsmsg_t *conf, const char *type, linuxdvb_satconf_t *parent ); + htsmsg_t *conf, const char *type, linuxdvb_satconf_ele_t *parent ); void linuxdvb_diseqc_destroy ( linuxdvb_diseqc_t *ld ); @@ -271,11 +315,11 @@ void linuxdvb_diseqc_destroy ( linuxdvb_diseqc_t *ld ); _u, &_d##_class, _c, _t, _p) linuxdvb_lnb_t *linuxdvb_lnb_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ); + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls ); linuxdvb_diseqc_t *linuxdvb_switch_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ); + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls, int u, int c ); linuxdvb_diseqc_t *linuxdvb_rotor_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ); + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls ); void linuxdvb_lnb_destroy ( linuxdvb_lnb_t *lnb ); void linuxdvb_switch_destroy ( linuxdvb_diseqc_t *ld ); @@ -293,14 +337,22 @@ int linuxdvb_diseqc_set_volt (int fd, int volt); /* * Satconf */ +void linuxdvb_satconf_save ( linuxdvb_satconf_t *ls, htsmsg_t *m ); -void linuxdvb_satconf_init ( void ); +linuxdvb_satconf_ele_t *linuxdvb_satconf_ele_create0 + (const char *uuid, htsmsg_t *conf, linuxdvb_satconf_t *ls); + +void linuxdvb_satconf_ele_destroy ( linuxdvb_satconf_ele_t *ls ); + +htsmsg_t *linuxdvb_satconf_type_list ( void *o ); linuxdvb_satconf_t *linuxdvb_satconf_create0(const char *uuid, htsmsg_t *conf); -void linuxdvb_satconf_delete ( linuxdvb_satconf_t *ls ); +linuxdvb_satconf_t *linuxdvb_satconf_create + ( linuxdvb_frontend_t *lfe, const char *type ); -htsmsg_t *linuxdvb_satconf_types ( void ); +void linuxdvb_satconf_delete ( linuxdvb_satconf_t *ls ); +void linuxdvb_satconf_destroy ( linuxdvb_satconf_t *ls ); linuxdvb_satconf_t *linuxdvb_satconf_create ( linuxdvb_frontend_t *lfe, const char *type ); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index aa3c813f..6d9b19b3 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -131,10 +131,10 @@ const idclass_t linuxdvb_rotor_usals_class = /* GotoX */ static int linuxdvb_rotor_gotox_tune - ( linuxdvb_rotor_t *lr, linuxdvb_mux_t *lm, linuxdvb_satconf_t *ls, int fd ) + ( linuxdvb_rotor_t *lr, linuxdvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd ) { int i; - for (i = 0; i <= ls->ls_diseqc_repeats; i++) { + for (i = 0; i <= ls->ls_parent->ls_diseqc_repeats; i++) { if (linuxdvb_diseqc_send(fd, 0xE0, 0x31, 0x6B, 1, (int)lr->lr_position)) { tvherror("diseqc", "failed to set GOTOX pos %d", lr->lr_position); return -1; @@ -149,7 +149,7 @@ linuxdvb_rotor_gotox_tune /* USALS */ static int linuxdvb_rotor_usals_tune - ( linuxdvb_rotor_t *lr, linuxdvb_mux_t *lm, linuxdvb_satconf_t *ls, int fd ) + ( linuxdvb_rotor_t *lr, linuxdvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd ) { /* * Code originally written in PR #238 by Jason Millard jsm174 @@ -202,7 +202,7 @@ linuxdvb_rotor_usals_tune fabs(pos), (pos > 0.0) ? 'E' : 'W', motor_angle, (motor_angle > 0.0) ? "counter-" : ""); - for (i = 0; i <= ls->ls_diseqc_repeats; i++) { + for (i = 0; i <= ls->ls_parent->ls_diseqc_repeats; i++) { if (linuxdvb_diseqc_send(fd, 0xE0, 0x31, 0x6E, 2, angle_1, angle_2)) { tvherror("diseqc", "failed to send USALS command"); return -1; @@ -218,7 +218,7 @@ linuxdvb_rotor_usals_tune static int linuxdvb_rotor_tune - ( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, linuxdvb_satconf_t *ls, int fd ) + ( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd ) { linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld; @@ -275,7 +275,7 @@ linuxdvb_rotor_list ( void *o ) linuxdvb_diseqc_t * linuxdvb_rotor_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ) + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls ) { int i; linuxdvb_diseqc_t *ld = NULL; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index a92da65e..5e48b0a3 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -29,22 +29,128 @@ #include #include +static const void* +linuxdvb_satconf_ele_class_network_get(void *o); + +static char * +linuxdvb_satconf_ele_class_network_rend ( void *o ); + +static int +linuxdvb_satconf_ele_class_network_set(void *o, const void *v); + +static htsmsg_t * +linuxdvb_satconf_ele_class_network_enum(void *o); + +static struct linuxdvb_satconf_type * +linuxdvb_satconf_type_find ( const char *type ); + +struct linuxdvb_satconf_type { + int ports; + const char *type; + const char *name; + const idclass_t *idc; +}; + /* ************************************************************************** * Types * *************************************************************************/ +static const void * +linuxdvb_satconf_class_network_get + ( linuxdvb_satconf_t *ls, int idx ) +{ + int i = 0; + static const char *s = NULL; + linuxdvb_satconf_ele_t *lse; + LIST_FOREACH(lse, &ls->ls_elements, ls_link) { + if (i == idx) break; + i++; + } + if (lse) + return linuxdvb_satconf_ele_class_network_get(lse); + return &s; +} + +static int +linuxdvb_satconf_class_network_set + ( linuxdvb_satconf_t *ls, int idx, const char *uuid ) +{ + int i = 0; + linuxdvb_satconf_ele_t *lse; + printf("SET NETWORK %p %d = %s\n", ls, idx, uuid); + LIST_FOREACH(lse, &ls->ls_elements, ls_link) { + printf("element\n"); + if (i == idx) break; + i++; + } + printf("lse = %p\n", lse); + if (lse) + return linuxdvb_satconf_ele_class_network_set(lse, uuid); + return 0; +} + +#define linuxdvb_satconf_class_network_getset(x)\ +static int \ +linuxdvb_satconf_class_network_set##x ( void *o, const void *v )\ +{\ + return linuxdvb_satconf_class_network_set(o, x, (void*)v);\ +}\ +static const void * \ +linuxdvb_satconf_class_network_get##x ( void *o )\ +{\ + return linuxdvb_satconf_class_network_get(o, x);\ +} + +linuxdvb_satconf_class_network_getset(0); +linuxdvb_satconf_class_network_getset(1); +linuxdvb_satconf_class_network_getset(2); +linuxdvb_satconf_class_network_getset(3); + +static const char * +linuxdvb_satconf_class_get_title ( idnode_t *p ) +{ + linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)p; + struct linuxdvb_satconf_type *lst = + linuxdvb_satconf_type_find(ls->ls_type); + return lst ? lst->name : ls->ls_type; +} + +static void +linuxdvb_satconf_class_save ( idnode_t *s ) +{ + linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)s; + linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; + linuxdvb_device_save(lfe->lfe_adapter->la_device); +} + /* * Generic satconf */ -const idclass_t linuxdvb_satconf_class +const idclass_t linuxdvb_satconf_class = { + .ic_class = "linuxdvb_satconf", + .ic_caption = "DVB-S Satconf", + .ic_get_title = linuxdvb_satconf_class_get_title, + .ic_save = linuxdvb_satconf_class_save, + .ic_properties = (const property_t[]) { + { + .type = PT_INT, + .id = "diseqc_repeats", + .name = "DiseqC repeats", + .off = offsetof(linuxdvb_satconf_t, ls_diseqc_repeats), + .opts = PO_ADVANCED, + .def.i = 0 + }, + {} + } }; /* * Simple LNB only */ -const idclass_t linuxdvb_satconf_lnbonly_class +const idclass_t linuxdvb_satconf_lnbonly_class = { + .ic_super = &linuxdvb_satconf_class, .ic_class = "linuxdvb_satconf_lnbonly", .ic_caption = "DVB-S Simple", .ic_properties = (const property_t[]) { @@ -52,9 +158,9 @@ const idclass_t linuxdvb_satconf_lnbonly_class .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 + .get = linuxdvb_satconf_class_network_get0, + .set = linuxdvb_satconf_class_network_set0, + .list = linuxdvb_satconf_ele_class_network_enum, }, {} } @@ -63,8 +169,9 @@ const idclass_t linuxdvb_satconf_lnbonly_class /* * 2 port switch */ -const idclass_t linuxdvb_satconf_2port_class +const idclass_t linuxdvb_satconf_2port_class = { + .ic_super = &linuxdvb_satconf_class, .ic_class = "linuxdvb_satconf_2port", .ic_caption = "DVB-S Toneburst", .ic_properties = (const property_t[]) { @@ -72,17 +179,17 @@ const idclass_t linuxdvb_satconf_2port_class .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 + .get = linuxdvb_satconf_class_network_get0, + .set = linuxdvb_satconf_class_network_set0, + .list = linuxdvb_satconf_ele_class_network_enum }, { .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 + .get = linuxdvb_satconf_class_network_get1, + .set = linuxdvb_satconf_class_network_set1, + .list = linuxdvb_satconf_ele_class_network_enum }, {} } @@ -91,8 +198,9 @@ const idclass_t linuxdvb_satconf_2port_class /* * 4 port switch */ -const idclass_t linuxdvb_satconf_4port_class +const idclass_t linuxdvb_satconf_4port_class = { + .ic_super = &linuxdvb_satconf_class, .ic_class = "linuxdvb_satconf_2port", .ic_caption = "DVB-S Toneburst", .ic_properties = (const property_t[]) { @@ -100,33 +208,33 @@ const idclass_t linuxdvb_satconf_4port_class .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 + .get = linuxdvb_satconf_class_network_get0, + .set = linuxdvb_satconf_class_network_set0, + .list = linuxdvb_satconf_ele_class_network_enum }, { .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 + .get = linuxdvb_satconf_class_network_get1, + .set = linuxdvb_satconf_class_network_set1, + .list = linuxdvb_satconf_ele_class_network_enum }, { .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 + .get = linuxdvb_satconf_class_network_get2, + .set = linuxdvb_satconf_class_network_set2, + .list = linuxdvb_satconf_ele_class_network_enum }, { .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 + .get = linuxdvb_satconf_class_network_get3, + .set = linuxdvb_satconf_class_network_set3, + .list = linuxdvb_satconf_ele_class_network_enum }, {} } @@ -135,16 +243,18 @@ const idclass_t linuxdvb_satconf_4port_class /* * Advanced */ -const idclass_t linuxdvb_ - -const idclass_t linuxdvb_satconf_advanced_ele_class +#if 0 +const idclass_t linuxdvb_satconf_advanced_ele_class = { + .ic_super = &linuxdvb_satconf_class, .ic_class = "linuxdvb_satconf_advanced", .ic_caption = "DVB-S Advanced", +#if 0 .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, +#endif .ic_properties = (const property_t[]) { { .type = PT_STR, @@ -155,13 +265,6 @@ const idclass_t linuxdvb_satconf_advanced_ele_class .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", @@ -191,23 +294,125 @@ const idclass_t linuxdvb_satconf_advanced_ele_class }, {} } - }; +#endif /* ************************************************************************** - * Objects + * Types * *************************************************************************/ -typedef struct linuxdvb_satconf_t -{ - idnode_t ls_id; - - /* Sub-elements */ - - - +/* Types/classes */ +static struct linuxdvb_satconf_type linuxdvb_satconf_types[] = { + { + .type = "simple", + .name = "Universal LNB only", + .idc = &linuxdvb_satconf_lnbonly_class, + .ports = 1, + }, + { + .type = "2port", + .name = "2-port Switch (Universal LNB)", + .idc = &linuxdvb_satconf_2port_class, + .ports = 2, + }, + { + .type = "4port", + .name = "4-port Switch (Universal LNB)", + .idc = &linuxdvb_satconf_4port_class, + .ports = 4, + }, +#if 0 + { + .type = "advanced", + .name = "Advanced", + .idc = &linuxdvb_satconf_advanced_class, + .ports = 0, + }, +#endif }; +/* Find type (with default) */ +static struct linuxdvb_satconf_type * +linuxdvb_satconf_type_find ( const char *type ) +{ + int i; + for (i = 0; i < ARRAY_SIZE(linuxdvb_satconf_types); i++) + if (!strcmp(type ?: "", linuxdvb_satconf_types[i].type)) + return linuxdvb_satconf_types+i; + return linuxdvb_satconf_types; +} + +/* List of types */ +htsmsg_t * +linuxdvb_satconf_type_list ( void *p ) +{ + int i; + htsmsg_t *e, *m = htsmsg_create_list(); + for (i = 0; i < ARRAY_SIZE(linuxdvb_satconf_types); i++) { + e = htsmsg_create_map(); + htsmsg_add_str(e, "key", linuxdvb_satconf_types[i].type); + htsmsg_add_str(e, "val", linuxdvb_satconf_types[i].name); + htsmsg_add_msg(m, NULL, e); + } + return m; +} + +/* ************************************************************************** + * Create/Delete satconf + * *************************************************************************/ + +void +linuxdvb_satconf_destroy ( linuxdvb_satconf_t *ls ) +{ + // TODO +} + +linuxdvb_satconf_t * +linuxdvb_satconf_create + ( linuxdvb_frontend_t *lfe, const char *type ) +{ + int i; + linuxdvb_satconf_ele_t *lse; + struct linuxdvb_satconf_type *lst + = linuxdvb_satconf_type_find(type); + const char *uuid = NULL;//"TODO"; + htsmsg_t *conf = NULL; + assert(lst); + + linuxdvb_satconf_t *ls = calloc(1, sizeof(linuxdvb_satconf_t)); + ls->ls_frontend = (mpegts_input_t*)lfe; + ls->ls_type = lst->type; + + /* Create node */ + if (idnode_insert(&ls->ls_id, uuid, lst->idc)) { + free(ls); + return NULL; + } + + /* Create elements */ + for (i = 0; i < lst->ports; i++) { + lse = linuxdvb_satconf_ele_create0(NULL, NULL, ls); + lse->ls_lnb = linuxdvb_lnb_create0(NULL, NULL, lse); + if (lst->ports > 1) + lse->ls_switch = linuxdvb_switch_create0(NULL, NULL, lse, i, -1); + } + + /* Load config */ + if (conf) + idnode_load(&ls->ls_id, conf); + + /* Advanced */ + + return ls; +} + +void +linuxdvb_satconf_save ( linuxdvb_satconf_t *ls, htsmsg_t *m ) +{ + htsmsg_add_str(m, "type", ls->ls_type); + idnode_save(&ls->ls_id, m); +} + /* ************************************************************************** * Class definition * *************************************************************************/ @@ -215,19 +420,19 @@ typedef struct linuxdvb_satconf_t extern const idclass_t mpegts_input_class; static const void* -linuxdvb_satconf_class_network_get(void *o) +linuxdvb_satconf_ele_class_network_get(void *o) { static const char *s; - linuxdvb_satconf_t *ls = o; + linuxdvb_satconf_ele_t *ls = o; s = ls->mi_network ? idnode_uuid_as_str(&ls->mi_network->mn_id) : NULL; return &s; } static char * -linuxdvb_satconf_class_network_rend ( void *o ) +linuxdvb_satconf_ele_class_network_rend ( void *o ) { const char *buf; - linuxdvb_satconf_t *ls = o; + linuxdvb_satconf_ele_t *ls = o; if (ls->mi_network) if ((buf = idnode_get_title(&ls->mi_network->mn_id))) return strdup(buf); @@ -235,12 +440,13 @@ linuxdvb_satconf_class_network_rend ( void *o ) } static int -linuxdvb_satconf_class_network_set(void *o, const void *v) +linuxdvb_satconf_ele_class_network_set(void *o, const void *v) { extern const idclass_t linuxdvb_network_class; mpegts_input_t *mi = o; mpegts_network_t *mn = mi->mi_network; const char *s = v; + printf("SET NETWORK %s\n", (const char*)v); if (mi->mi_network && !strcmp(idnode_uuid_as_str(&mn->mn_id), s ?: "")) return 0; @@ -257,7 +463,7 @@ linuxdvb_satconf_class_network_set(void *o, const void *v) } static htsmsg_t * -linuxdvb_satconf_class_network_enum(void *o) +linuxdvb_satconf_ele_class_network_enum(void *o) { extern const idclass_t linuxdvb_network_dvbs_class; htsmsg_t *m = htsmsg_create_map(); @@ -272,65 +478,7 @@ linuxdvb_satconf_class_network_enum(void *o) return m; } -static const void * -linuxdvb_satconf_class_frontend_get ( void *o ) -{ - static const char *s; - linuxdvb_satconf_t *ls = o; - s = ls->ls_frontend ? idnode_uuid_as_str(&ls->ls_frontend->ti_id) : NULL; - return &s; -} - -static char * -linuxdvb_satconf_class_frontend_rend ( void *o ) -{ - const char *buf; - linuxdvb_satconf_t *ls = o; - if (ls->ls_frontend) - if ((buf = idnode_get_title(&ls->ls_frontend->ti_id))) - return strdup(buf); - return NULL; -} - -static int -linuxdvb_satconf_class_frontend_set ( void *o, const void *v ) -{ - extern const idclass_t linuxdvb_frontend_dvbs_class; - linuxdvb_satconf_t *ls = o; - const char *u = v; - mpegts_input_t *lfe = idnode_find(u, &linuxdvb_frontend_dvbs_class); - if (lfe && ls->ls_frontend != lfe) { - 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; -} - -static htsmsg_t * -linuxdvb_satconf_class_frontend_enum (void *o) -{ - extern const idclass_t linuxdvb_frontend_dvbs_class; - int i; - char buf[512]; - htsmsg_t *m = htsmsg_create_list(); - idnode_set_t *is = idnode_find_all(&linuxdvb_frontend_dvbs_class); - for (i = 0; i < is->is_count; i++) { - mpegts_input_t *mi = (mpegts_input_t*)is->is_array[i]; - htsmsg_t *e = htsmsg_create_map(); - htsmsg_add_str(e, "key", idnode_uuid_as_str(&mi->ti_id)); - *buf = 0; - mi->mi_display_name(mi, buf, sizeof(buf)); - htsmsg_add_str(e, "val", buf); - htsmsg_add_msg(m, NULL, e); - } - idnode_set_free(is); - return m; -} - +#if 0 static void linuxdvb_satconf_class_save ( idnode_t *in ) { @@ -357,12 +505,13 @@ linuxdvb_satconf_class_save ( idnode_t *in ) idnode_uuid_as_str(in)); htsmsg_destroy(m); } +#endif static int -linuxdvb_satconf_class_lnbtype_set ( void *o, const void *p ) +linuxdvb_satconf_ele_class_lnbtype_set ( void *o, const void *p ) { - linuxdvb_satconf_t *ls = o; - const char *str = p; + linuxdvb_satconf_ele_t *ls = o; + const char *str = p; if (ls->ls_lnb && !strcmp(str ?: "", ls->ls_lnb->ld_type)) return 0; if (ls->ls_lnb) linuxdvb_lnb_destroy(ls->ls_lnb); @@ -371,40 +520,40 @@ linuxdvb_satconf_class_lnbtype_set ( void *o, const void *p ) } static const void * -linuxdvb_satconf_class_lnbtype_get ( void *o ) +linuxdvb_satconf_ele_class_lnbtype_get ( void *o ) { static const char *s; - linuxdvb_satconf_t *ls = o; + linuxdvb_satconf_ele_t *ls = o; s = ls->ls_lnb ? ls->ls_lnb->ld_type : NULL; return &s; } static int -linuxdvb_satconf_class_switchtype_set ( void *o, const void *p ) +linuxdvb_satconf_ele_class_switchtype_set ( void *o, const void *p ) { - linuxdvb_satconf_t *ls = o; - const char *str = p; + linuxdvb_satconf_ele_t *ls = o; + const char *str = p; if (ls->ls_switch && !strcmp(str ?: "", ls->ls_switch->ld_type)) return 0; if (ls->ls_switch) linuxdvb_switch_destroy(ls->ls_switch); - ls->ls_switch = linuxdvb_switch_create0(str, NULL, ls); + ls->ls_switch = linuxdvb_switch_create0(str, NULL, ls, 0, 0); return 1; } static const void * -linuxdvb_satconf_class_switchtype_get ( void *o ) +linuxdvb_satconf_ele_class_switchtype_get ( void *o ) { static const char *s; - linuxdvb_satconf_t *ls = o; + linuxdvb_satconf_ele_t *ls = o; s = ls->ls_switch ? ls->ls_switch->ld_type : NULL; return &s; } static int -linuxdvb_satconf_class_rotortype_set ( void *o, const void *p ) +linuxdvb_satconf_ele_class_rotortype_set ( void *o, const void *p ) { - linuxdvb_satconf_t *ls = o; - const char *str = p; + linuxdvb_satconf_ele_t *ls = o; + const char *str = p; if (ls->ls_rotor && !strcmp(str ?: "", ls->ls_rotor->ld_type)) return 0; if (ls->ls_rotor) linuxdvb_rotor_destroy(ls->ls_rotor); @@ -413,19 +562,19 @@ linuxdvb_satconf_class_rotortype_set ( void *o, const void *p ) } static const void * -linuxdvb_satconf_class_rotortype_get ( void *o ) +linuxdvb_satconf_ele_class_rotortype_get ( void *o ) { static const char *s; - linuxdvb_satconf_t *ls = o; + linuxdvb_satconf_ele_t *ls = o; s = ls->ls_rotor ? ls->ls_rotor->ld_type : NULL; return &s; } static const char * -linuxdvb_satconf_class_get_title ( idnode_t *o ) +linuxdvb_satconf_ele_class_get_title ( idnode_t *o ) { static char buf[128]; - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)o; + linuxdvb_satconf_ele_t *ls = (linuxdvb_satconf_ele_t*)o; if (ls->mi_network) ls->mi_network->mn_display_name(ls->mi_network, buf, sizeof(buf)); else @@ -434,9 +583,9 @@ linuxdvb_satconf_class_get_title ( idnode_t *o ) } static idnode_set_t * -linuxdvb_satconf_class_get_childs ( idnode_t *o ) +linuxdvb_satconf_ele_class_get_childs ( idnode_t *o ) { - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)o; + linuxdvb_satconf_ele_t *ls = (linuxdvb_satconf_ele_t*)o; idnode_set_t *is = idnode_set_create(); if (ls->ls_lnb) idnode_set_add(is, &ls->ls_lnb->ld_id, NULL); @@ -448,43 +597,38 @@ linuxdvb_satconf_class_get_childs ( idnode_t *o ) } static void -linuxdvb_satconf_class_delete ( idnode_t *in ) +linuxdvb_satconf_ele_class_delete ( idnode_t *in ) { - linuxdvb_satconf_delete((linuxdvb_satconf_t*)in); + //TODO:linuxdvb_satconf_ele_delete((linuxdvb_satconf_ele_t*)in); } -const idclass_t linuxdvb_satconf_class = +const idclass_t linuxdvb_satconf_ele_class = { .ic_super = &mpegts_input_class, - .ic_class = "linuxdvb_satconf", - .ic_caption = "Linux DVB Satconf", - .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_class = "linuxdvb_satconf_ele", + .ic_caption = "Satconf", + .ic_get_title = linuxdvb_satconf_ele_class_get_title, + .ic_get_childs = linuxdvb_satconf_ele_class_get_childs, +#if 0 + .ic_save = linuxdvb_satconf_ele_class_save, +#endif + .ic_delete = linuxdvb_satconf_ele_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 + .get = linuxdvb_satconf_ele_class_network_get, + .set = linuxdvb_satconf_ele_class_network_set, + .list = linuxdvb_satconf_ele_class_network_enum, + .rend = linuxdvb_satconf_ele_class_network_rend, }, { .type = PT_STR, .id = "lnb_type", .name = "LNB Type", - .set = linuxdvb_satconf_class_lnbtype_set, - .get = linuxdvb_satconf_class_lnbtype_get, + .set = linuxdvb_satconf_ele_class_lnbtype_set, + .get = linuxdvb_satconf_ele_class_lnbtype_get, .list = linuxdvb_lnb_list, .def.s = "Universal", }, @@ -492,8 +636,8 @@ const idclass_t linuxdvb_satconf_class = .type = PT_STR, .id = "switch_type", .name = "Switch Type", - .set = linuxdvb_satconf_class_switchtype_set, - .get = linuxdvb_satconf_class_switchtype_get, + .set = linuxdvb_satconf_ele_class_switchtype_set, + .get = linuxdvb_satconf_ele_class_switchtype_get, .list = linuxdvb_switch_list, .def.s = "None", }, @@ -501,8 +645,8 @@ const idclass_t linuxdvb_satconf_class = .type = PT_STR, .id = "rotor_type", .name = "Rotor Type", - .set = linuxdvb_satconf_class_rotortype_set, - .get = linuxdvb_satconf_class_rotortype_get, + .set = linuxdvb_satconf_ele_class_rotortype_set, + .get = linuxdvb_satconf_ele_class_rotortype_get, .list = linuxdvb_rotor_list, .def.s = "None", }, @@ -511,83 +655,69 @@ const idclass_t linuxdvb_satconf_class = }; /* ************************************************************************** - * Class methods + * MPEG-TS Class methods * *************************************************************************/ static void -linuxdvb_satconf_display_name ( mpegts_input_t* mi, char *buf, size_t len ) +linuxdvb_satconf_ele_display_name ( mpegts_input_t* mi, char *buf, size_t len ) { - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; + linuxdvb_satconf_t *ls = ((linuxdvb_satconf_ele_t*)mi)->ls_parent; if (ls->ls_frontend) ls->ls_frontend->mi_display_name(ls->ls_frontend, buf, len); else strncpy(buf, "Unknown", len); } -static int -linuxdvb_satconf_is_enabled ( mpegts_input_t *mi ) -{ - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; - if (!ls->ls_frontend) - return 0; - return ls->ls_frontend->mi_is_enabled(ls->ls_frontend); +#define linuxdvb_satconf_ele_proxy(type, func)\ +static type \ +linuxdvb_satconf_ele_##func ( mpegts_input_t *mi )\ +{\ + linuxdvb_satconf_t *ls = ((linuxdvb_satconf_ele_t*)mi)->ls_parent;\ + return ls->ls_frontend->mi_##func(ls->ls_frontend);\ } -static int -linuxdvb_satconf_is_free ( mpegts_input_t *mi ) -{ - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; - if (!ls->ls_frontend) - return 0; - return ls->ls_frontend->mi_is_free(ls->ls_frontend); -} +linuxdvb_satconf_ele_proxy(int, is_enabled); +linuxdvb_satconf_ele_proxy(int, is_free); +linuxdvb_satconf_ele_proxy(int, get_weight); static int -linuxdvb_satconf_get_weight ( mpegts_input_t *mi ) -{ - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; - if (!ls->ls_frontend) - return 0; - return ls->ls_frontend->mi_get_weight(ls->ls_frontend); -} - -static int -linuxdvb_satconf_get_priority ( mpegts_input_t *mi ) +linuxdvb_satconf_ele_get_priority ( mpegts_input_t *mi ) { int prio = 0; - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; + linuxdvb_satconf_t *ls = ((linuxdvb_satconf_ele_t*)mi)->ls_parent; if (!ls->ls_frontend) prio = ls->ls_frontend->mi_get_priority(ls->ls_frontend); return prio + mpegts_input_get_priority(mi); } static void -linuxdvb_satconf_stop_mux +linuxdvb_satconf_ele_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; + linuxdvb_satconf_t *ls = ((linuxdvb_satconf_ele_t*)mi)->ls_parent; if (ls->ls_frontend) ls->ls_frontend->mi_stop_mux(ls->ls_frontend, mmi); gtimer_disarm(&ls->ls_diseqc_timer); } -static void linuxdvb_satconf_tune_cb ( void *o ); +static void linuxdvb_satconf_ele_tune_cb ( void *o ); static int -linuxdvb_satconf_tune ( linuxdvb_satconf_t *ls ) +linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) { int r, i, b; uint32_t f; + linuxdvb_satconf_t *ls = lse->ls_parent; /* Get beans in a row */ mpegts_mux_instance_t *mmi = ls->ls_mmi; linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mmi->mmi_mux; linuxdvb_diseqc_t *lds[] = { - ls->ls_rotor ? (linuxdvb_diseqc_t*)ls->ls_switch : NULL, - (linuxdvb_diseqc_t*)ls->ls_rotor, - (linuxdvb_diseqc_t*)ls->ls_switch, - (linuxdvb_diseqc_t*)ls->ls_lnb + lse->ls_rotor ? (linuxdvb_diseqc_t*)lse->ls_switch : NULL, + (linuxdvb_diseqc_t*)lse->ls_rotor, + (linuxdvb_diseqc_t*)lse->ls_switch, + (linuxdvb_diseqc_t*)lse->ls_lnb }; // TODO: really need to understand whether or not we need to pre configure // and/or re-affirm the switch @@ -602,21 +732,21 @@ linuxdvb_satconf_tune ( linuxdvb_satconf_t *ls ) i = ls->ls_diseqc_idx; for (i = ls->ls_diseqc_idx; i < ARRAY_SIZE(lds); i++) { if (!lds[i]) continue; - r = lds[i]->ld_tune(lds[i], lm, ls, lfe->lfe_fe_fd); + r = lds[i]->ld_tune(lds[i], lm, lse, lfe->lfe_fe_fd); /* Error */ if (r < 0) return r; /* Pending */ if (r != 0) { - gtimer_arm_ms(&ls->ls_diseqc_timer, linuxdvb_satconf_tune_cb, ls, r); + gtimer_arm_ms(&ls->ls_diseqc_timer, linuxdvb_satconf_ele_tune_cb, lse, r); ls->ls_diseqc_idx = i + 1; return 0; } } /* Set the tone */ - b = ls->ls_lnb->lnb_band(ls->ls_lnb, lm); + b = lse->ls_lnb->lnb_band(lse->ls_lnb, lm); tvhtrace("disqec", "set diseqc tone %s", b ? "on" : "off"); if (ioctl(lfe->lfe_fe_fd, FE_SET_TONE, b ? SEC_TONE_ON : SEC_TONE_OFF)) { tvherror("diseqc", "failed to set diseqc tone (e=%s)", strerror(errno)); @@ -624,36 +754,35 @@ linuxdvb_satconf_tune ( linuxdvb_satconf_t *ls ) } /* Frontend */ - f = ls->ls_lnb->lnb_freq(ls->ls_lnb, lm); + f = lse->ls_lnb->lnb_freq(lse->ls_lnb, lm); return linuxdvb_frontend_tune1(lfe, mmi, f); } static void -linuxdvb_satconf_tune_cb ( void *o ) +linuxdvb_satconf_ele_tune_cb ( void *o ) { - linuxdvb_satconf_t *ls = o; - if (linuxdvb_satconf_tune(ls) < 0) { - // TODO: how do we signal this? - } + (void)linuxdvb_satconf_ele_tune(o); + // TODO: how to signal error } static int -linuxdvb_satconf_start_mux +linuxdvb_satconf_ele_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { int r; uint32_t f; - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; - linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mmi->mmi_mux; + linuxdvb_satconf_ele_t *lse = (linuxdvb_satconf_ele_t*)mi; + linuxdvb_satconf_t *ls = lse->ls_parent; + linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; + linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mmi->mmi_mux; /* Test run */ // Note: basically this ensures the tuning params are acceptable // for the FE, so that if they're not we don't have to wait // for things like rotors and switches - if (!ls->ls_lnb) + if (!lse->ls_lnb) return SM_CODE_TUNING_FAILED; - f = ls->ls_lnb->lnb_freq(ls->ls_lnb, lm); + f = lse->ls_lnb->lnb_freq(lse->ls_lnb, lm); if (f == (uint32_t)-1) return SM_CODE_TUNING_FAILED; r = linuxdvb_frontend_tune0(lfe, mmi, f); @@ -662,11 +791,11 @@ linuxdvb_satconf_start_mux /* Diseqc */ ls->ls_mmi = mmi; ls->ls_diseqc_idx = 0; - return linuxdvb_satconf_tune(ls); + return linuxdvb_satconf_ele_tune(lse); } static void -linuxdvb_satconf_open_service +linuxdvb_satconf_ele_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int init ) { linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; @@ -674,7 +803,7 @@ linuxdvb_satconf_open_service } static void -linuxdvb_satconf_close_service +linuxdvb_satconf_ele_close_service ( mpegts_input_t *mi, mpegts_service_t *s ) { linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; @@ -682,7 +811,7 @@ linuxdvb_satconf_close_service } static void -linuxdvb_satconf_started_mux +linuxdvb_satconf_ele_started_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; @@ -690,7 +819,7 @@ linuxdvb_satconf_started_mux } static void -linuxdvb_satconf_stopped_mux +linuxdvb_satconf_ele_stopped_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; @@ -698,7 +827,7 @@ linuxdvb_satconf_stopped_mux } static int -linuxdvb_satconf_has_subscription +linuxdvb_satconf_ele_has_subscription ( mpegts_input_t *mi, mpegts_mux_t *mm ) { linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; @@ -706,15 +835,16 @@ linuxdvb_satconf_has_subscription } static int -linuxdvb_satconf_get_grace +linuxdvb_satconf_ele_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm ) { int i, r; - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; - linuxdvb_diseqc_t *lds[] = { - (linuxdvb_diseqc_t*)ls->ls_switch, - (linuxdvb_diseqc_t*)ls->ls_rotor, - (linuxdvb_diseqc_t*)ls->ls_lnb + linuxdvb_satconf_ele_t *lse = (linuxdvb_satconf_ele_t*)mi; + linuxdvb_satconf_t *ls = lse->ls_parent; + linuxdvb_diseqc_t *lds[] = { + (linuxdvb_diseqc_t*)lse->ls_switch, + (linuxdvb_diseqc_t*)lse->ls_rotor, + (linuxdvb_diseqc_t*)lse->ls_lnb }; /* Get underlying value */ @@ -733,7 +863,7 @@ linuxdvb_satconf_get_grace } static mpegts_pid_t * -linuxdvb_satconf_open_pid +linuxdvb_satconf_ele_open_pid ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, void *owner ) { linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; @@ -744,56 +874,66 @@ linuxdvb_satconf_open_pid * Creation/Config * *************************************************************************/ -linuxdvb_satconf_t * -linuxdvb_satconf_create0 - ( const char *uuid, htsmsg_t *conf ) +void +linuxdvb_satconf_ele_destroy ( linuxdvb_satconf_ele_t *ls ) +{ + // TODO +} + +linuxdvb_satconf_ele_t * +linuxdvb_satconf_ele_create0 + ( const char *uuid, htsmsg_t *conf, linuxdvb_satconf_t *ls ) { htsmsg_t *e; - linuxdvb_satconf_t *ls = mpegts_input_create(linuxdvb_satconf, uuid, conf); + linuxdvb_satconf_ele_t *lse + = mpegts_input_create(linuxdvb_satconf_ele, uuid, conf); + lse->ls_parent = ls; + LIST_INSERT_HEAD(&ls->ls_elements, lse, ls_link); /* Input callbacks */ - ls->mi_is_enabled = linuxdvb_satconf_is_enabled; - ls->mi_is_free = linuxdvb_satconf_is_free; - ls->mi_get_weight = linuxdvb_satconf_get_weight; - ls->mi_get_priority = linuxdvb_satconf_get_priority; - ls->mi_get_grace = linuxdvb_satconf_get_grace; - ls->mi_display_name = linuxdvb_satconf_display_name; - ls->mi_start_mux = linuxdvb_satconf_start_mux; - ls->mi_stop_mux = linuxdvb_satconf_stop_mux; - ls->mi_open_service = linuxdvb_satconf_open_service; - ls->mi_close_service = linuxdvb_satconf_close_service; - ls->mi_started_mux = linuxdvb_satconf_started_mux; - ls->mi_stopped_mux = linuxdvb_satconf_stopped_mux; - ls->mi_has_subscription = linuxdvb_satconf_has_subscription; - ls->mi_open_pid = linuxdvb_satconf_open_pid; + lse->mi_is_enabled = linuxdvb_satconf_ele_is_enabled; + lse->mi_is_free = linuxdvb_satconf_ele_is_free; + lse->mi_get_weight = linuxdvb_satconf_ele_get_weight; + lse->mi_get_priority = linuxdvb_satconf_ele_get_priority; + lse->mi_get_grace = linuxdvb_satconf_ele_get_grace; + lse->mi_display_name = linuxdvb_satconf_ele_display_name; + lse->mi_start_mux = linuxdvb_satconf_ele_start_mux; + lse->mi_stop_mux = linuxdvb_satconf_ele_stop_mux; + lse->mi_open_service = linuxdvb_satconf_ele_open_service; + lse->mi_close_service = linuxdvb_satconf_ele_close_service; + lse->mi_started_mux = linuxdvb_satconf_ele_started_mux; + lse->mi_stopped_mux = linuxdvb_satconf_ele_stopped_mux; + lse->mi_has_subscription = linuxdvb_satconf_ele_has_subscription; + lse->mi_open_pid = linuxdvb_satconf_ele_open_pid; /* Config */ if (conf) { /* LNB */ - if (ls->ls_lnb && (e = htsmsg_get_map(conf, "lnb_conf"))) - idnode_load(&ls->ls_lnb->ld_id, e); + if (lse->ls_lnb && (e = htsmsg_get_map(conf, "lnb_conf"))) + idnode_load(&lse->ls_lnb->ld_id, e); /* Switch */ - if (ls->ls_switch && (e = htsmsg_get_map(conf, "switch_conf"))) - idnode_load(&ls->ls_switch->ld_id, e); + if (lse->ls_switch && (e = htsmsg_get_map(conf, "switch_conf"))) + idnode_load(&lse->ls_switch->ld_id, e); /* Rotor */ - if (ls->ls_rotor && (e = htsmsg_get_map(conf, "rotor_conf"))) - idnode_load(&ls->ls_rotor->ld_id, e); + if (lse->ls_rotor && (e = htsmsg_get_map(conf, "rotor_conf"))) + idnode_load(&lse->ls_rotor->ld_id, e); } /* Create default LNB */ - if (!ls->ls_lnb) - ls->ls_lnb = linuxdvb_lnb_create0(NULL, NULL, ls); + if (!lse->ls_lnb) + lse->ls_lnb = linuxdvb_lnb_create0(NULL, NULL, lse); - return ls; + return lse; } void linuxdvb_satconf_delete ( linuxdvb_satconf_t *ls ) { - const char *uuid = idnode_uuid_as_str(&ls->ti_id); +#if TODO + const char *uuid = idnode_uuid_as_str(&ls->ls_id); hts_settings_remove("input/linuxdvb/satconfs/%s", uuid); if (ls->ls_lnb) linuxdvb_lnb_destroy(ls->ls_lnb); @@ -802,21 +942,12 @@ linuxdvb_satconf_delete ( linuxdvb_satconf_t *ls ) if (ls->ls_rotor) linuxdvb_rotor_destroy(ls->ls_rotor); mpegts_input_delete((mpegts_input_t*)ls); +#endif } -void -linuxdvb_satconf_init ( void ) -{ - htsmsg_t *s, *e; - htsmsg_field_t *f; - if ((s = hts_settings_load_r(1, "input/linuxdvb/satconfs"))) { - HTSMSG_FOREACH(f, s) { - if (!(e = htsmsg_get_map_by_field(f))) continue; - (void)linuxdvb_satconf_create0(f->hmf_name, e); - } - htsmsg_destroy(s); - } -} +/****************************************************************************** + * DiseqC + *****************************************************************************/ static const char * linuxdvb_diseqc_class_get_title ( idnode_t *o ) @@ -828,9 +959,11 @@ linuxdvb_diseqc_class_get_title ( idnode_t *o ) static void linuxdvb_diseqc_class_save ( idnode_t *o ) { +#if TODO linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; if (ld->ld_satconf) linuxdvb_satconf_class_save(&ld->ld_satconf->ti_id); +#endif } const idclass_t linuxdvb_diseqc_class = @@ -844,7 +977,7 @@ const idclass_t linuxdvb_diseqc_class = linuxdvb_diseqc_t * linuxdvb_diseqc_create0 ( linuxdvb_diseqc_t *ld, const char *uuid, const idclass_t *idc, - htsmsg_t *conf, const char *type, linuxdvb_satconf_t *parent ) + htsmsg_t *conf, const char *type, linuxdvb_satconf_ele_t *parent ) { /* Insert */ if (idnode_insert(&ld->ld_id, uuid, idc)) { diff --git a/src/input/mpegts/linuxdvb/linuxdvb_switch.c b/src/input/mpegts/linuxdvb/linuxdvb_switch.c index 16cad4fa..445ffbf4 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_switch.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_switch.c @@ -112,7 +112,7 @@ const idclass_t linuxdvb_switch_class = static int linuxdvb_switch_tune - ( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, linuxdvb_satconf_t *sc, int fd ) + ( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, linuxdvb_satconf_ele_t *sc, int fd ) { int i, com, r1 = 0, r2 = 0; int pol, band; @@ -130,7 +130,7 @@ linuxdvb_switch_tune com = 0xF0 | (ls->ls_committed << 2) | (pol << 1) | band; /* Single committed (before repeats) */ - if (sc->ls_diseqc_repeats > 0) { + if (sc->ls_parent->ls_diseqc_repeats > 0) { r2 = 1; if (linuxdvb_diseqc_send(fd, 0xE0, 0x10, 0x38, 1, com)) return -1; @@ -138,7 +138,7 @@ linuxdvb_switch_tune } /* Repeats */ - for (i = 0; i <= sc->ls_diseqc_repeats; i++) { + for (i = 0; i <= sc->ls_parent->ls_diseqc_repeats; i++) { /* Uncommitted */ if (linuxdvb_diseqc_send(fd, 0xE0 | r1, 0x10, 0x39, 1, @@ -181,17 +181,26 @@ linuxdvb_switch_list ( void *o ) linuxdvb_diseqc_t * linuxdvb_switch_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ) + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls, int u, int c ) { - linuxdvb_diseqc_t *ld = NULL; + linuxdvb_switch_t *ld = NULL; if (!strcmp(name ?: "", "Generic")) { - ld = linuxdvb_diseqc_create(linuxdvb_switch, NULL, conf, "Generic", ls); + ld = (linuxdvb_switch_t*)linuxdvb_diseqc_create(linuxdvb_switch, NULL, conf, "Generic", ls); if (ld) { ld->ld_tune = linuxdvb_switch_tune; + if (!conf) { + if (u >= 0) { + ld->ls_committed = u; + ld->ls_toneburst = u % 2; + } + if (c >= 0) { + ld->ls_committed = c; + } + } } } - return ld; + return (linuxdvb_diseqc_t*)ld; } void diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index 0b8e1248..ed0468f6 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -83,13 +83,13 @@ ts_recv_packet0 if(st->es_cc_valid && cc != st->es_cc) { /* Incorrect CC */ limitedlog(&st->es_loglimit_cc, "TS", service_component_nicename(st), - "Continuity counter error"); + "Continuity counter error"); avgstat_add(&t->s_cc_errors, 1, dispatch_clock); avgstat_add(&st->es_cc_errors, 1, dispatch_clock); // Mark as error if this is not the first packet of a payload if(!pusi) - error |= 0x2; + error |= 0x2; } st->es_cc_valid = 1; st->es_cc = (cc + 1) & 0xf; @@ -143,8 +143,8 @@ ts_process_pcr(mpegts_service_t *t, elementary_stream_t *st, int64_t pcr) if(d < -90000LL || d > 90000LL) { st->es_pcr_recovery_fails++; if(st->es_pcr_recovery_fails > 10) { - st->es_pcr_recovery_fails = 0; - st->es_pcr_real_last = PTS_UNSET; + st->es_pcr_recovery_fails = 0; + st->es_pcr_real_last = PTS_UNSET; } return; } @@ -153,7 +153,7 @@ ts_process_pcr(mpegts_service_t *t, elementary_stream_t *st, int64_t pcr) if(t->s_pcr_pid == st->es_pid) { /* This is the registered PCR PID, adjust service PCR drift - via an IIR filter */ + via an IIR filter */ t->s_pcr_drift = (t->s_pcr_drift * 255 + st->es_pcr_drift) / 256; } @@ -207,7 +207,7 @@ ts_recv_packet1(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp) if(error) { /* Transport Error Indicator */ limitedlog(&t->s_loglimit_tei, "TS", service_nicename((service_t*)t), - "Transport error indicator"); + "Transport error indicator"); } pid = (tsb[1] & 0x1f) << 8 | tsb[2]; @@ -245,19 +245,19 @@ ts_recv_packet1(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp) r = td->td_descramble(td, (service_t*)t, st, tsb); if(r == 0) { - pthread_mutex_unlock(&t->s_stream_mutex); - return 1; + pthread_mutex_unlock(&t->s_stream_mutex); + return 1; } if(r == 1) - m++; + m++; } if(!error && t->s_scrambled != 0) { if(n == 0) { - service_set_streaming_status_flags((service_t*)t, TSS_NO_DESCRAMBLER); + service_set_streaming_status_flags((service_t*)t, TSS_NO_DESCRAMBLER); } else if(m == n) { - service_set_streaming_status_flags((service_t*)t, TSS_NO_ACCESS); + service_set_streaming_status_flags((service_t*)t, TSS_NO_ACCESS); } }