typedef struct epggrab_module_ota epggrab_module_ota_t;
typedef struct epggrab_module_ota_scraper epggrab_module_ota_scraper_t;
typedef struct epggrab_ota_mux epggrab_ota_mux_t;
+typedef struct epggrab_ota_mux_eit_plist epggrab_ota_mux_eit_plist_t;
typedef struct epggrab_ota_map epggrab_ota_map_t;
typedef struct epggrab_ota_svc_link epggrab_ota_svc_link_t;
RB_ENTRY(epggrab_ota_svc_link) link;
};
+struct epggrab_ota_mux_eit_plist {
+ LIST_ENTRY(epggrab_ota_mux_eit_plist) link;
+ const char *src;
+ void *priv;
+};
+
/*
* TODO: this could be embedded in the mux itself, but by using a soft-link
* and keeping it here I can somewhat isolate it from the mpegts code
TAILQ_ENTRY(epggrab_ota_mux) om_q_link;
RB_ENTRY(epggrab_ota_mux) om_global_link;
+
+ LIST_HEAD(, epggrab_ota_mux_eit_plist) om_eit_plist;
+ mtimer_t om_eit_timer;
};
/*
uint8_t om_first;
uint8_t om_forced;
uint64_t om_tune_count;
- enum {
- EPGGRAB_OTA_MUX_EIT_IDLE,
- EPGGRAB_OTA_MUX_EIT_NIT,
- EPGGRAB_OTA_MUX_EIT_SDT
- } om_eit_state;
RB_HEAD(,epggrab_ota_svc_link) om_svcs; ///< Muxes we carry data for
void *om_opaque;
};
/* Transponder tuning */
int (*start) ( epggrab_ota_map_t *map, struct mpegts_mux *mm );
+ int (*stop) ( epggrab_ota_map_t *map, struct mpegts_mux *mm );
int (*tune) ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om,
struct mpegts_mux *mm );
void *opaque;
static TAILQ_HEAD(, eit_private) eit_private_list;
+static void eit_install_handlers(void *aux);
+
/* ************************************************************************
* Status handling
* ***********************************************************************/
( epggrab_ota_map_t *map, mpegts_mux_t *dm )
{
epggrab_module_ota_t *m = map->om_module;
+ epggrab_ota_mux_t *om;
/* Disabled */
if (!m->enabled && !map->om_forced) return -1;
+ om = epggrab_ota_find_mux(dm);
+ if (!om) return -1;
+
+ mtimer_arm_rel(&om->om_eit_timer, eit_install_handlers, dm, sec2mono(20));
+ return 0;
+}
+
+static int _eit_stop
+ ( epggrab_ota_map_t *map, mpegts_mux_t *dm )
+{
+ epggrab_ota_mux_t *om;
+
+ om = epggrab_ota_find_mux(dm);
+ if (!om) return -1;
+
+ mtimer_disarm(&om->om_eit_timer);
+
return 0;
}
return 1;
}
-static void eit_install_handlers
- (mpegts_mux_t *dm, eit_private_t *priv, const char *src, int state)
+static void eit_install_handlers(void *aux)
{
+ mpegts_mux_t *dm = aux;
epggrab_ota_mux_t *om;
epggrab_ota_map_t *map;
- epggrab_module_ota_t *m = priv->module;
- int pid, opts = 0;
-
- if (priv->bat_pid) {
- mpegts_table_add(dm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL,
- "ebat", LS_TBL_BASE, MT_CRC, priv->bat_pid, MPS_WEIGHT_EIT);
- }
+ epggrab_module_ota_t *m;
+ epggrab_ota_mux_eit_plist_t *plist;
+ eit_private_t *priv, *priv2;
+ int pid, opts;
om = epggrab_ota_find_mux(dm);
if (!om)
return;
- if (state == EPGGRAB_OTA_MUX_EIT_SDT) {
- /* check, if NIT EIT is already installed */
- LIST_FOREACH(map, &om->om_modules, om_link)
- if (map->om_eit_state == EPGGRAB_OTA_MUX_EIT_NIT)
- return;
- }
- LIST_FOREACH(map, &om->om_modules, om_link) {
- if (map->om_module == m)
- break;
- }
- if (!map || (!m->enabled && !map->om_forced)) {
- tvhtrace(m->subsys, "%s - module '%s' not enabled", src, m->id);
- return;
+
+ priv = NULL;
+ LIST_FOREACH(plist, &om->om_eit_plist, link) {
+ priv2 = (eit_private_t *)plist->priv;
+ if (!priv || priv->module->priority < priv2->module->priority) {
+ m = priv->module;
+ LIST_FOREACH(map, &om->om_modules, om_link) {
+ if (map->om_module == m)
+ break;
+ }
+ if (!map || (!m->enabled && !map->om_forced)) {
+ tvhtrace(m->subsys, "handlers - module '%s' not enabled", m->id);
+ continue;
+ }
+ priv = priv2;
+ }
}
- if (map->om_eit_state != EPGGRAB_OTA_MUX_EIT_IDLE) {
- tvhtrace(m->subsys, "%s - module '%s' already installed", src, m->id);
- return;
+
+ if (priv->bat_pid) {
+ mpegts_table_add(dm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL,
+ "ebat", LS_TBL_BASE, MT_CRC, priv->bat_pid, MPS_WEIGHT_EIT);
}
- map->om_eit_state = state;
- tvhtrace(m->subsys, "%s - detected module '%s'", src, m->id);
+ m = priv->module;
+
+ tvhtrace(m->subsys, "handlers - detected module '%s'", m->id);
priv = (eit_private_t *)m->opaque;
pid = priv->pid;
+ opts = 0;
/* Standard (0x12) */
if (pid == 0) {
mpegts_table_add(dm, 0, 0, _eit_callback, map, map->om_module->id, LS_TBL_EIT,
MT_CRC | opts, pid, MPS_WEIGHT_EIT);
// TODO: might want to limit recording to EITpf only
- tvhdebug(m->subsys, "%s: installed table handlers (%s)", m->id, src);
+ tvhdebug(m->subsys, "%s: installed table handlers", m->id);
+}
+
+static void eit_queue_priv
+ (mpegts_mux_t *dm, const char *src, eit_private_t *priv)
+{
+ epggrab_ota_mux_t *om;
+ epggrab_ota_mux_eit_plist_t *plist, *plist2;
+
+ om = epggrab_ota_find_mux(dm);
+ if (!om)
+ return;
+
+ LIST_FOREACH(plist2, &om->om_eit_plist, link)
+ if (plist2->priv == priv)
+ return;
+
+ tvhtrace(LS_TBL_EIT, "%s - detected module '%s'", src, priv->module->id);
+ plist = calloc(1, sizeof(*plist));
+ plist->src = src;
+ plist->priv = priv;
+ LIST_INSERT_HEAD(&om->om_eit_plist, plist, link);
}
void eit_nit_callback
if (!priv)
return;
- eit_install_handlers(dm, priv, "NIT", EPGGRAB_OTA_MUX_EIT_NIT);
+ eit_queue_priv(dm, "NIT", priv);
}
void eit_sdt_callback(mpegts_table_t *mt, uint32_t sdtpriv)
eit_sdt_t *sdt;
eit_private_t *priv = NULL;
- /* do not rerun */
- assert(mt->mt_bat == NULL || mt->mt_bat == mt);
- if (mt->mt_bat)
- return;
- mt->mt_bat = mt;
-
tvhtrace(LS_TBL_EIT, "SDT - tsid %04X (%d) onid %04X (%d) private %08X",
dm->mm_tsid, dm->mm_tsid, dm->mm_onid, dm->mm_onid, sdtpriv);
if (!priv)
return;
- eit_install_handlers(dm, priv, "SDT", EPGGRAB_OTA_MUX_EIT_SDT);
+ eit_queue_priv(dm, "SDT", priv);
}
static void _eit_scrape_clear(eit_module_t *mod)
ops = calloc(1, sizeof(*ops));
priv = calloc(1, sizeof(*priv));
ops->start = _eit_start;
+ ops->stop = _eit_stop;
ops->done = _eit_done;
ops->activate = _eit_activate;
ops->process_data = _eit_process_data;
return timeout;
}
+static void
+epggrab_ota_free_eit_plist ( epggrab_ota_mux_t *ota )
+{
+ epggrab_ota_mux_eit_plist_t *plist;
+
+ while ((plist = LIST_FIRST(&ota->om_eit_plist)) != NULL)
+ free(plist);
+}
+
static int
epggrab_ota_queue_one( epggrab_ota_mux_t *om )
{
assert(om->om_q_type == EPGGRAB_OTA_MUX_ACTIVE);
TAILQ_REMOVE(&epggrab_ota_active, om, om_q_link);
om->om_q_type = EPGGRAB_OTA_MUX_IDLE;
+ LIST_FOREACH(map, &om->om_modules, om_link)
+ if (map->om_module->stop)
+ map->om_module->stop(map, mm);
if (reason == EPGGRAB_OTA_DONE_STOLEN) {
/* Do not requeue completed muxes */
if (!om->om_done && om->om_requeue) {
break;
}
}
+ epggrab_ota_free_eit_plist(om);
LIST_FOREACH(map, &om->om_modules, om_link) {
map->om_first = 1;
map->om_forced = 0;
if (modname && !strcmp(modname, map->om_module->id))
map->om_forced = 1;
map->om_complete = 0;
- map->om_eit_state = EPGGRAB_OTA_MUX_EIT_IDLE;
if (map->om_module->start(map, mm) < 0) {
map->om_complete = 1;
} else
tvhtrace(LS_EPGGRAB, "loading config for %s", mm->mm_nicename);
ota = calloc(1, sizeof(epggrab_ota_mux_t));
+ LIST_INIT(&ota->om_eit_plist);
ota->om_mux_uuid = mm->mm_id.in_uuid;
if (RB_INSERT_SORTED(&epggrab_ota_all, ota, om_global_link, om_id_cmp)) {
free(ota);
free(map);
}
free(ota->om_force_modname);
+ epggrab_ota_free_eit_plist(ota);
free(ota);
}