diff --git a/Makefile b/Makefile
index f5d064bb..5cda57d1 100644
--- a/Makefile
+++ b/Makefile
@@ -175,6 +175,7 @@ SRCS-${CONFIG_LINUXDVB} += \
src/input/mpegts/linuxdvb/linuxdvb_network.c \
src/input/mpegts/linuxdvb/linuxdvb_mux.c \
src/input/mpegts/linuxdvb/linuxdvb_service.c \
+ src/input/mpegts/linuxdvb/linuxdvb_satconf.c \
# IPTV
SRCS-${CONFIG_IPTV} += \
diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c
index 5f4658ae..ce0f8b67 100644
--- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c
+++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c
@@ -62,6 +62,62 @@ linuxdvb_frontend_class_save ( idnode_t *in )
linuxdvb_device_save((linuxdvb_device_t*)lfe->lh_parent->lh_parent);
}
+static const char*
+linuxdvb_frontend_class_network_get(void *o)
+{
+ linuxdvb_frontend_t *lfe = o;
+ if (lfe->mi_network)
+ return idnode_uuid_as_str(&lfe->mi_network->mn_id);
+ return NULL;
+}
+
+static int
+linuxdvb_frontend_class_network_set(void *o, const char *s)
+{
+ mpegts_input_t *mi = o;
+ mpegts_network_t *mn = mi->mi_network;
+ linuxdvb_network_t *ln = (linuxdvb_network_t*)mn;
+ linuxdvb_frontend_t *lfe = o;
+
+ if (lfe->lfe_info.type == FE_QPSK) {
+ tvherror("linuxdvb", "cannot set network on DVB-S FE");
+ return 0;
+ }
+
+ if (mi->mi_network && !strcmp(idnode_uuid_as_str(&mn->mn_id), s ?: ""))
+ return 0;
+
+ if (ln && ln->ln_type != lfe->lfe_info.type) {
+ tvherror("linuxdvb", "attempt to set network of wrong type");
+ return 0;
+ }
+
+ mpegts_input_set_network(mi, s ? mpegts_network_find(s) : NULL);
+ return 1;
+}
+
+static htsmsg_t *
+linuxdvb_frontend_class_network_enum(void *o)
+{
+ extern const idclass_t linuxdvb_network_class;
+ int i;
+ linuxdvb_frontend_t *lfe = o;
+ linuxdvb_network_t *ln;
+ htsmsg_t *m = htsmsg_create_list();
+ idnode_set_t *is = idnode_find_all(&linuxdvb_network_class);
+ for (i = 0; i < is->is_count; i++) {
+ ln = (linuxdvb_network_t*)is->is_array[i];
+ if (ln->ln_type == lfe->lfe_info.type) {
+ htsmsg_t *e = htsmsg_create_map();
+ htsmsg_add_str(e, "key", idnode_uuid_as_str(&ln->mn_id));
+ htsmsg_add_str(e, "val", ln->mn_network_name);
+ htsmsg_add_msg(m, NULL, e);
+ }
+ }
+ idnode_set_free(is);
+ return m;
+}
+
const idclass_t linuxdvb_frontend_class =
{
.ic_super = &linuxdvb_hardware_class,
@@ -108,50 +164,6 @@ const idclass_t linuxdvb_frontend_class =
}
};
-static const char*
-linuxdvb_frontend_class_network_get(void *o)
-{
- linuxdvb_frontend_t *lfe = o;
- if (lfe->mi_network)
- return idnode_uuid_as_str(&lfe->mi_network->mn_id);
- return NULL;
-}
-
-static int
-linuxdvb_frontend_class_network_set(void *o, const char *s)
-{
- mpegts_input_t *mi = o;
- mpegts_network_t *mn = mi->mi_network;
-
- if (mi->mi_network && !strcmp(idnode_uuid_as_str(&mn->mn_id), s ?: ""))
- return 0;
-
- mpegts_input_set_network(mi, s ? mpegts_network_find(s) : NULL);
- return 1;
-}
-
-static htsmsg_t *
-linuxdvb_frontend_class_network_enum(void *o)
-{
- extern const idclass_t linuxdvb_network_class;
- int i;
- linuxdvb_frontend_t *lfe = o;
- linuxdvb_network_t *ln;
- htsmsg_t *m = htsmsg_create_list();
- idnode_set_t *is = idnode_find_all(&linuxdvb_network_class);
- for (i = 0; i < is->is_count; i++) {
- ln = (linuxdvb_network_t*)is->is_array[i];
- if (ln->ln_type == lfe->lfe_info.type) {
- htsmsg_t *e = htsmsg_create_map();
- htsmsg_add_str(e, "key", idnode_uuid_as_str(&ln->mn_id));
- htsmsg_add_str(e, "val", ln->mn_network_name);
- htsmsg_add_msg(m, NULL, e);
- }
- }
- idnode_set_free(is);
- return m;
-}
-
const idclass_t linuxdvb_frontend_dvbt_class =
{
.ic_super = &linuxdvb_frontend_class,
@@ -186,6 +198,14 @@ const idclass_t linuxdvb_frontend_dvbc_class =
.ic_class = "linuxdvb_frontend_dvbc",
.ic_caption = "Linux DVB-C Frontend",
.ic_properties = (const property_t[]){
+ {
+ .type = PT_STR,
+ .id = "network",
+ .name = "Network",
+ .str_get = linuxdvb_frontend_class_network_get,
+ .str_set = linuxdvb_frontend_class_network_set,
+ .str_enum = linuxdvb_frontend_class_network_enum
+ },
{}
}
};
@@ -196,6 +216,14 @@ const idclass_t linuxdvb_frontend_atsc_class =
.ic_class = "linuxdvb_frontend_atsc",
.ic_caption = "Linux ATSC Frontend",
.ic_properties = (const property_t[]){
+ {
+ .type = PT_STR,
+ .id = "network",
+ .name = "Network",
+ .str_get = linuxdvb_frontend_class_network_get,
+ .str_set = linuxdvb_frontend_class_network_set,
+ .str_enum = linuxdvb_frontend_class_network_enum
+ },
{}
}
};
diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h
index 3d8627c3..d905d940 100644
--- a/src/input/mpegts/linuxdvb/linuxdvb_private.h
+++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h
@@ -28,6 +28,7 @@ typedef struct linuxdvb_adapter linuxdvb_adapter_t;
typedef struct linuxdvb_frontend linuxdvb_frontend_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;
@@ -143,12 +144,16 @@ struct linuxdvb_frontend
int lfe_locked;
time_t lfe_monitor;
gtimer_t lfe_monitor_timer;
- int (*lfe_open_pid) (linuxdvb_frontend_t *lfe, int pid, const char *name);
/*
* Configuration
*/
int lfe_fullmux;
+
+ /*
+ * Callbacks
+ */
+ int (*lfe_open_pid) (linuxdvb_frontend_t *lfe, int pid, const char *name);
};
linuxdvb_frontend_t *
@@ -206,4 +211,17 @@ mpegts_service_t *linuxdvb_service_create0
(linuxdvb_mux_t *lm, uint16_t sid, uint16_t pmt_pid,
const char *uuid, htsmsg_t *conf);
+/*
+ * Satconf
+ */
+struct linuxdvb_satconf
+{
+ mpegts_input_t;
+
+ /* Links */
+ mpegts_input_t *ls_frontend;
+};
+
+linuxdvb_satconf_t *linuxdvb_satconf_create0(const char *uuid, htsmsg_t *conf);
+
#endif /* __TVH_LINUXDVB_PRIVATE_H__ */
diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c
new file mode 100644
index 00000000..ee541422
--- /dev/null
+++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c
@@ -0,0 +1,286 @@
+/*
+ * Tvheadend - Linux DVB satconf
+ *
+ * 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 "linuxdvb_private.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* **************************************************************************
+ * Class definition
+ * *************************************************************************/
+
+extern const idclass_t linuxdvb_hardware_class;
+
+static const char*
+linuxdvb_satconf_class_network_get(void *o)
+{
+ linuxdvb_satconf_t *ls = o;
+ if (ls->mi_network)
+ return idnode_uuid_as_str(&ls->mi_network->mn_id);
+ return NULL;
+}
+
+static int
+linuxdvb_satconf_class_network_set(void *o, const char *s)
+{
+ mpegts_input_t *mi = o;
+ mpegts_network_t *mn = mi->mi_network;
+ linuxdvb_network_t *ln = (linuxdvb_network_t*)mn;
+
+ if (mi->mi_network && !strcmp(idnode_uuid_as_str(&mn->mn_id), s ?: ""))
+ return 0;
+
+ if (ln->ln_type != FE_QPSK) {
+ tvherror("linuxdvb", "attempt to set network of wrong type");
+ return 0;
+ }
+
+ mpegts_input_set_network(mi, s ? mpegts_network_find(s) : NULL);
+ return 1;
+}
+
+static htsmsg_t *
+linuxdvb_satconf_class_network_enum(void *o)
+{
+ extern const idclass_t linuxdvb_network_class;
+ int i;
+ linuxdvb_network_t *ln;
+ htsmsg_t *m = htsmsg_create_list();
+ idnode_set_t *is = idnode_find_all(&linuxdvb_network_class);
+ for (i = 0; i < is->is_count; i++) {
+ ln = (linuxdvb_network_t*)is->is_array[i];
+ if (ln->ln_type == FE_QPSK) {
+ htsmsg_t *e = htsmsg_create_map();
+ htsmsg_add_str(e, "key", idnode_uuid_as_str(&ln->mn_id));
+ htsmsg_add_str(e, "val", ln->mn_network_name);
+ htsmsg_add_msg(m, NULL, e);
+ }
+ }
+ idnode_set_free(is);
+ return m;
+}
+
+static const char *
+linuxdvb_satconf_class_frontend_get ( void *o )
+{
+ linuxdvb_satconf_t *ls = o;
+ if (ls->ls_frontend)
+ return idnode_uuid_as_str(&ls->ls_frontend->mi_id);
+ return NULL;
+}
+
+static int
+linuxdvb_satconf_class_frontend_set ( void *o, const char *u )
+{
+ extern const idclass_t linuxdvb_frontend_dvbs_class;
+ linuxdvb_satconf_t *ls = o;
+ 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
+ ls->ls_frontend = lfe;
+ 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->mi_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;
+}
+
+const idclass_t linuxdvb_satconf_class =
+{
+ .ic_super = &linuxdvb_hardware_class,
+ .ic_class = "linuxdvb_satconf",
+ .ic_caption = "Linux DVB Satconf",
+ //.ic_get_title = linuxdvb_satconf_class_get_title,
+ //.ic_save = linuxdvb_satconf_class_save,
+ .ic_properties = (const property_t[]) {
+ {
+ .type = PT_STR,
+ .id = "frontend",
+ .name = "Frontend",
+ .str_get = linuxdvb_satconf_class_frontend_get,
+ .str_set = linuxdvb_satconf_class_frontend_set,
+ .str_enum = linuxdvb_satconf_class_frontend_enum
+ },
+ {
+ .type = PT_STR,
+ .id = "network",
+ .name = "Network",
+ .str_get = linuxdvb_satconf_class_network_get,
+ .str_set = linuxdvb_satconf_class_network_set,
+ .str_enum = linuxdvb_satconf_class_network_enum
+ },
+ {}
+ }
+};
+
+/* **************************************************************************
+ * Class methods
+ * *************************************************************************/
+
+static void
+linuxdvb_satconf_display_name ( mpegts_input_t* mi, char *buf, size_t len )
+{
+ linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi;
+ ls->mi_display_name(ls->ls_frontend, buf, len);
+}
+
+static const idclass_t *
+linuxdvb_satconf_network_class ( mpegts_input_t *mi )
+{
+ extern const idclass_t linuxdvb_network_class;
+ return &linuxdvb_network_class;
+}
+
+static mpegts_network_t *
+linuxdvb_satconf_network_create ( mpegts_input_t *mi, htsmsg_t *conf )
+{
+ return (mpegts_network_t*)
+ linuxdvb_network_create0(NULL, FE_QPSK, conf);
+}
+
+static int
+linuxdvb_satconf_is_enabled ( mpegts_input_t *mi )
+{
+ linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi;
+ return ls->ls_frontend->mi_is_enabled(ls->ls_frontend);
+}
+
+static int
+linuxdvb_satconf_is_free ( mpegts_input_t *mi )
+{
+ linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi;
+ return ls->ls_frontend->mi_is_free(ls->ls_frontend);
+}
+
+static int
+linuxdvb_satconf_current_weight ( mpegts_input_t *mi )
+{
+ linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi;
+ return ls->ls_frontend->mi_current_weight(ls->ls_frontend);
+}
+
+static void
+linuxdvb_satconf_stop_mux
+ ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
+{
+ linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi;
+ ls->ls_frontend->mi_stop_mux(ls->ls_frontend, mmi);
+}
+
+static int
+linuxdvb_satconf_start_mux
+ ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
+{
+ linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi;
+ mi = ls->ls_frontend;
+ // TODO: need more here!
+ return mi->mi_start_mux(mi, mmi);
+}
+
+static void
+linuxdvb_satconf_open_service
+ ( mpegts_input_t *mi, mpegts_service_t *s )
+{
+ linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi;
+ ls->ls_frontend->mi_open_service(ls->ls_frontend, s);
+}
+
+static void
+linuxdvb_satconf_close_service
+ ( mpegts_input_t *mi, mpegts_service_t *s )
+{
+ linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi;
+ ls->ls_frontend->mi_close_service(ls->ls_frontend, s);
+}
+
+static void
+linuxdvb_satconf_create_mux_instance
+ ( mpegts_input_t *mi, mpegts_mux_t *mm )
+{
+ linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi;
+ ls->ls_frontend->mi_create_mux_instance(ls->ls_frontend, mm);
+}
+
+/* **************************************************************************
+ * Creation/Config
+ * *************************************************************************/
+
+linuxdvb_satconf_t *
+linuxdvb_satconf_create0
+ ( const char *uuid, htsmsg_t *conf )
+{
+ linuxdvb_satconf_t *ls = mpegts_input_create(linuxdvb_satconf, uuid, conf);
+
+ /* Input callbacks */
+ ls->mi_is_enabled = linuxdvb_satconf_is_enabled;
+ ls->mi_is_free = linuxdvb_satconf_is_free;
+ ls->mi_current_weight = linuxdvb_satconf_current_weight;
+ 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_network_class = linuxdvb_satconf_network_class;
+ ls->mi_network_create = linuxdvb_satconf_network_create;
+ ls->mi_create_mux_instance = linuxdvb_satconf_create_mux_instance;
+
+ return ls;
+}
+
+#if 0
+void
+linuxdvb_satconf_save ( linuxdvb_satconf_t *lfe, htsmsg_t *m )
+{
+ //mpegts_input_save((mpegts_input_t*)lfe, m);
+ // htsmsg_add_str(m, "type", dvb_type2str(lfe->lfe_info.type));
+}
+#endif
+
+/******************************************************************************
+ * Editor Configuration
+ *
+ * vim:sts=2:ts=2:sw=2:et
+ *****************************************************************************/