diff --git a/src/epggrab.h b/src/epggrab.h
index 8c28b7d7..56bec684 100644
--- a/src/epggrab.h
+++ b/src/epggrab.h
@@ -172,8 +172,6 @@ struct epggrab_module_ext
*/
struct epggrab_ota_mux
{
- idnode_t om_id;
-
char *om_mux_uuid; ///< Soft-link to mux
LIST_HEAD(,epggrab_ota_map) om_modules; ///< List of linked mods
diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c
index 1c4709b5..16cdfb3a 100644
--- a/src/epggrab/otamux.c
+++ b/src/epggrab/otamux.c
@@ -16,16 +16,20 @@
* along with this program. If not, see .
*/
-#include
-
#include "tvheadend.h"
#include "queue.h"
+#include "settings.h"
#include "epg.h"
#include "epggrab.h"
#include "epggrab/private.h"
#include "input/mpegts.h"
#include "subscriptions.h"
+#include
+#include
+#include
+#include
+
RB_HEAD(,epggrab_ota_mux) epggrab_ota_all;
LIST_HEAD(,epggrab_ota_mux) epggrab_ota_pending;
LIST_HEAD(,epggrab_ota_mux) epggrab_ota_active;
@@ -36,6 +40,8 @@ gtimer_t epggrab_ota_active_timer;
static void epggrab_ota_active_timer_cb ( void *p );
static void epggrab_ota_pending_timer_cb ( void *p );
+static void epggrab_ota_save ( epggrab_ota_mux_t *ota );
+
/* **************************************************************************
* Utilities
* *************************************************************************/
@@ -152,16 +158,6 @@ epggrab_mux_stop ( mpegts_mux_t *mm, void *p )
epggrab_ota_done(ota, 0);
}
-void
-epggrab_ota_init ( void )
-{
- static mpegts_listener_t ml = {
- .ml_mux_start = epggrab_mux_start,
- .ml_mux_stop = epggrab_mux_stop,
- };
- mpegts_add_listener(&ml);
-}
-
/* **************************************************************************
* Completion handling
* *************************************************************************/
@@ -175,6 +171,7 @@ epggrab_ota_register
( epggrab_module_ota_t *mod, mpegts_mux_t *mm,
int interval, int timeout )
{
+ int save = 0;
static epggrab_ota_mux_t *skel = NULL;
epggrab_ota_map_t *map;
epggrab_ota_mux_t *ota;
@@ -198,22 +195,25 @@ epggrab_ota_register
LIST_INSERT_SORTED(&epggrab_ota_active, ota, om_q_link, om_time_cmp);
if (LIST_FIRST(&epggrab_ota_active) == ota)
epggrab_ota_active_timer_cb(NULL);
-
- // TODO: configuration
+ save = 1;
}
/* Find module entry */
LIST_FOREACH(map, &ota->om_modules, om_link)
if (map->om_module == mod)
break;
- if (!mod) {
+ if (!map) {
map = calloc(1, sizeof(epggrab_ota_map_t));
map->om_module = mod;
map->om_timeout = timeout;
map->om_interval = interval;
LIST_INSERT_HEAD(&ota->om_modules, map, om_link);
+ save = 1;
}
+ /* Save config */
+ if (save) epggrab_ota_save(ota);
+
return ota;
}
@@ -329,3 +329,105 @@ done:
/* **************************************************************************
* Config
* *************************************************************************/
+
+static void
+epggrab_ota_save ( epggrab_ota_mux_t *ota )
+{
+ epggrab_ota_map_t *map;
+ htsmsg_t *e, *l, *c = htsmsg_create_map();
+
+ htsmsg_add_u32(c, "timeout", ota->om_timeout);
+ htsmsg_add_u32(c, "interval", ota->om_interval);
+ l = htsmsg_create_list();
+ LIST_FOREACH(map, &ota->om_modules, om_link) {
+ e = htsmsg_create_map();
+ htsmsg_add_str(e, "id", map->om_module->id);
+ htsmsg_add_u32(e, "timeout", map->om_timeout);
+ htsmsg_add_u32(e, "interval", map->om_interval);
+ htsmsg_add_msg(l, NULL, e);
+ }
+ htsmsg_add_msg(c, "modules", l);
+ hts_settings_save(c, "epggrab/otamux/%s", ota->om_mux_uuid);
+}
+
+static void
+epggrab_ota_load_one
+ ( const char *uuid, htsmsg_t *c )
+{
+ htsmsg_t *l, *e;
+ htsmsg_field_t *f;
+ mpegts_mux_t *mm;
+ epggrab_module_ota_t *mod;
+ epggrab_ota_mux_t *ota;
+ epggrab_ota_map_t *map;
+ const char *id;
+
+ mm = mpegts_mux_find(uuid);
+ if (!mm) return;
+
+ ota = calloc(1, sizeof(epggrab_ota_mux_t));
+ ota->om_mux_uuid = strdup(uuid);
+ ota->om_timeout = htsmsg_get_u32_or_default(c, "timeout", 0);
+ ota->om_interval = htsmsg_get_u32_or_default(c, "timeout", 0);
+ if (RB_INSERT_SORTED(&epggrab_ota_all, ota, om_global_link, om_id_cmp)) {
+ free(ota->om_mux_uuid);
+ free(ota);
+ return;
+ }
+ LIST_INSERT_SORTED(&epggrab_ota_pending, ota, om_q_link, om_time_cmp);
+
+ if (!(l = htsmsg_get_list(c, "modules"))) return;
+ HTSMSG_FOREACH(f, l) {
+ if (!(e = htsmsg_field_get_map(f))) continue;
+ if (!(id = htsmsg_get_str(e, "id"))) continue;
+ if (!(mod = (epggrab_module_ota_t*)epggrab_module_find_by_id(id)))
+ continue;
+
+ map = calloc(1, sizeof(epggrab_ota_map_t));
+ map->om_module = mod;
+ map->om_timeout = htsmsg_get_u32_or_default(e, "timeout", 0);
+ map->om_interval = htsmsg_get_u32_or_default(e, "interval", 0);
+ LIST_INSERT_HEAD(&ota->om_modules, map, om_link);
+ }
+}
+
+void
+epggrab_ota_init ( void )
+{
+ htsmsg_t *c, *m;
+ htsmsg_field_t *f;
+ char path[1024];
+ struct stat st;
+
+ /* Add listener */
+ static mpegts_listener_t ml = {
+ .ml_mux_start = epggrab_mux_start,
+ .ml_mux_stop = epggrab_mux_stop,
+ };
+ mpegts_add_listener(&ml);
+
+ /* Delete old config */
+ hts_settings_buildpath(path, sizeof(path), "epggrab/otamux");
+ if (!lstat(path, &st))
+ if (!S_ISDIR(st.st_mode))
+ hts_settings_remove("epggrab/otamux");
+
+ /* Load config */
+ if ((c = hts_settings_load_r(1, "epggrab/otamux"))) {
+ HTSMSG_FOREACH(f, c) {
+ if (!(m = htsmsg_field_get_map(f))) continue;
+ epggrab_ota_load_one(f->hmf_name, m);
+ }
+ }
+
+ /* Init timer (immediate call after full init) */
+ if (LIST_FIRST(&epggrab_ota_pending))
+ gtimer_arm_abs(&epggrab_ota_pending_timer, epggrab_ota_pending_timer_cb,
+ NULL, 0);
+}
+
+/******************************************************************************
+ * Editor Configuration
+ *
+ * vim:sts=2:ts=2:sw=2:et
+ *****************************************************************************/
diff --git a/src/epggrab/private.h b/src/epggrab/private.h
index ac4d6371..7f31e32b 100644
--- a/src/epggrab/private.h
+++ b/src/epggrab/private.h
@@ -101,8 +101,7 @@ epggrab_module_ota_t *epggrab_module_ota_create
/*
* Config handling
*/
-void epggrab_ota_load ( void );
-void epggrab_ota_save ( void );
+void epggrab_ota_init ( void );
/*
* Create/Find a link (unregistered)