uint8_t om_complete; ///< Has completed a scan
uint8_t om_requeue; ///< Requeue when stolen
uint8_t om_save; ///< something changed
+ uint8_t om_detected; ///< detected some activity
mtimer_t om_timer; ///< Per mux active timer
mtimer_t om_data_timer; ///< Any EPG data seen?
+ mtimer_t om_handlers_timer; ///< Run handlers callback
int64_t om_retry_time; ///< Next time to retry
char *om_force_modname;///< Force this module
RB_ENTRY(epggrab_ota_mux) om_global_link;
LIST_HEAD(, epggrab_ota_mux_eit_plist) om_eit_plist;
- mtimer_t om_eit_timer;
};
/*
/* Transponder tuning */
int (*start) ( epggrab_ota_map_t *map, struct mpegts_mux *mm );
int (*stop) ( epggrab_ota_map_t *map, struct mpegts_mux *mm );
+ void (*handlers) (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;
skel->activate = ops->activate;
skel->start = ops->start;
skel->stop = ops->stop;
+ skel->handlers = ops->handlers;
skel->done = ops->done;
skel->tune = ops->tune;
skel->process_data = ops->process_data;
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 )
+static void _eit_install_handlers
+ ( epggrab_ota_map_t *_map, mpegts_mux_t *dm )
{
epggrab_ota_mux_t *om;
+ epggrab_ota_map_t *map;
+ 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 -1;
+ if (!om)
+ return;
- mtimer_disarm(&om->om_eit_timer);
+ priv = NULL;
+ map = NULL;
+ LIST_FOREACH(plist, &om->om_eit_plist, link) {
+ priv2 = (eit_private_t *)plist->priv;
+ if (!priv || priv->module->priority < priv2->module->priority) {
+ m = priv2->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;
+ }
+ }
- return 0;
+ if (!priv)
+ return;
+
+ epggrab_ota_free_eit_plist(om);
+
+ 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);
+ }
+
+ 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) {
+ pid = DVB_EIT_PID;
+ opts = MT_RECORD;
+ }
+
+ 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", m->id);
}
static int _eit_activate(void *m, int e)
return 1;
}
-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;
- epggrab_ota_mux_eit_plist_t *plist;
- eit_private_t *priv, *priv2;
- int pid, opts;
-
- om = epggrab_ota_find_mux(dm);
- if (!om)
- 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 (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);
- }
-
- 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) {
- pid = DVB_EIT_PID;
- opts = MT_RECORD;
- }
-
- 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", m->id);
-}
-
static void eit_queue_priv
(mpegts_mux_t *dm, const char *src, eit_private_t *priv)
{
plist->src = src;
plist->priv = priv;
LIST_INSERT_HEAD(&om->om_eit_plist, plist, link);
+
+ om->om_detected = 1;
}
void eit_nit_callback
ops = calloc(1, sizeof(*ops));
priv = calloc(1, sizeof(*priv));
ops->start = _eit_start;
- ops->stop = _eit_stop;
+ ops->handlers = _eit_install_handlers;
ops->done = _eit_done;
ops->activate = _eit_activate;
ops->process_data = _eit_process_data;
static void epggrab_ota_timeout_cb ( void *p );
static void epggrab_ota_data_timeout_cb ( void *p );
+static void epggrab_ota_handlers_timeout_cb ( void *p );
static void epggrab_ota_kick_cb ( void *p );
static void epggrab_mux_start ( mpegts_mux_t *mm, void *p );
return timeout;
}
-static void
+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)
+ while ((plist = LIST_FIRST(&ota->om_eit_plist)) != NULL) {
+ LIST_REMOVE(plist, link);
free(plist);
+ }
}
static int
mtimer_disarm(&om->om_timer);
mtimer_disarm(&om->om_data_timer);
+ mtimer_disarm(&om->om_handlers_timer);
assert(om->om_q_type == EPGGRAB_OTA_MUX_ACTIVE);
TAILQ_REMOVE(&epggrab_ota_active, om, om_q_link);
TAILQ_INSERT_TAIL(&epggrab_ota_active, om, om_q_link);
om->om_q_type = EPGGRAB_OTA_MUX_ACTIVE;
+ om->om_detected = 0;
grace = mpegts_input_grace(mmi->mmi_input, mm);
mtimer_arm_rel(&om->om_timer, epggrab_ota_timeout_cb, om,
sec2mono(epggrab_ota_timeout_get() + grace));
mtimer_arm_rel(&om->om_data_timer, epggrab_ota_data_timeout_cb, om,
sec2mono(30 + grace)); /* 30 seconds to receive any EPG info */
+ mtimer_arm_rel(&om->om_data_timer, epggrab_ota_handlers_timeout_cb, om,
+ sec2mono(5 + grace));
if (modname) {
LIST_FOREACH(m, &epggrab_modules, link)
if (!strcmp(m->id, modname)) {
}
}
+static void
+epggrab_ota_handlers_timeout2_cb ( void *p )
+{
+ epggrab_ota_mux_t *om = p;
+ epggrab_ota_map_t *map;
+ mpegts_mux_t *mm;
+
+ lock_assert(&global_lock);
+
+ if (!om)
+ return;
+
+ mm = mpegts_mux_find0(&om->om_mux_uuid);
+ if (!mm)
+ return;
+
+ /* Run handlers */
+ LIST_FOREACH(map, &om->om_modules, om_link) {
+ if (!map->om_complete && map->om_module->handlers)
+ map->om_module->handlers(map, mm);
+ }
+}
+
+static void
+epggrab_ota_handlers_timeout_cb ( void *p )
+{
+ epggrab_ota_mux_t *om = p;
+ epggrab_ota_map_t *map;
+
+ lock_assert(&global_lock);
+
+ if (!om)
+ return;
+
+ /* Test for any valid data reception */
+ LIST_FOREACH(map, &om->om_modules, om_link) {
+ if (!map->om_first)
+ break;
+ }
+
+ if (!om->om_detected && map == NULL) {
+ /* wait longer */
+ mtimer_arm_rel(&om->om_handlers_timer, epggrab_ota_handlers_timeout_cb,
+ om, sec2mono(5));
+ } else {
+ mtimer_arm_rel(&om->om_handlers_timer, epggrab_ota_handlers_timeout2_cb,
+ om, sec2mono(20));
+ }
+}
+
static void
epggrab_ota_kick_cb ( void *p )
{
mtimer_disarm(&ota->om_timer);
mtimer_disarm(&ota->om_data_timer);
+ mtimer_disarm(&ota->om_handlers_timer);
if (head != NULL)
TAILQ_REMOVE(head, ota, om_q_link);
RB_REMOVE(&epggrab_ota_all, ota, om_global_link);
typedef struct epggrab_ota_module_ops {
int (*start) (epggrab_ota_map_t *map, struct mpegts_mux *mm);
int (*stop) (epggrab_ota_map_t *map, struct mpegts_mux *mm);
+ void (*handlers) (epggrab_ota_map_t *map, struct mpegts_mux *mm);
int (*activate) (void *m, int e);
void (*done) (void *m);
int (*tune) (epggrab_ota_map_t *map, epggrab_ota_mux_t *om,
void epggrab_ota_create_and_register_by_id
( epggrab_module_ota_t *mod, uint16_t onid, uint16_t tsid,
int period, int interval, const char *name );
+void epggrab_ota_free_eit_plist ( epggrab_ota_mux_t *ota );
/*
* Delete
if (tableid != 0x42 && tableid != 0x46) return -1;
r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len,
tableid, extraid, 8, &st, §, &last, &ver, 0);
- if (r != 1) {
- if (r == 0) {
- /* install EIT handlers, but later than from optional NIT */
- if (mm->mm_start_monoclock + sec2mono(10) < mclk())
- eit_sdt_callback(mt, mt->mt_priv);
- }
+ if (r != 1)
return r;
- }
/* ID */
tvhdebug(mt->mt_subsys, "%s: onid %04X (%d) tsid %04X (%d)",
}
}
+ eit_sdt_callback(mt, mt->mt_priv);
+
/* Done */
return dvb_table_end((mpegts_psi_table_t *)mt, st, sect);
}