int nbid_count;
} eit_nit_t;
+typedef struct eit_sdt {
+ LIST_ENTRY(eit_sdt) link;
+ uint16_t onid[32];
+ uint16_t tsid[32];
+ int onid_count;
+ int tsid_count;
+} eit_sdt_t;
+
typedef struct eit_private
{
TAILQ_ENTRY(eit_private) link;
uint16_t pid;
uint16_t bat_pid;
int conv;
+ uint32_t sdt_enable;
uint32_t hacks;
- uint32_t nitpriv;
+ uint32_t priv;
LIST_HEAD(, eit_nit) nit;
+ LIST_HEAD(, eit_sdt) sdt;
epggrab_ota_module_ops_t *ops;
} eit_private_t;
return 1;
}
-void eit_nit_callback(mpegts_table_t *mt, uint16_t nbid, const char *name, uint32_t nitpriv)
+static void eit_install_handlers
+ (mpegts_mux_t *dm, eit_private_t *priv, const char *src, int state)
{
- mpegts_mux_t *dm = mt->mt_mux;
epggrab_ota_mux_t *om;
epggrab_ota_map_t *map;
- epggrab_module_ota_t *m = NULL;
+ 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);
+ }
+
+ 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;
+ }
+ if (map->om_eit_state != EPGGRAB_OTA_MUX_EIT_IDLE) {
+ tvhtrace(m->subsys, "%s - module '%s' already installed", src, m->id);
+ return;
+ }
+ map->om_eit_state = state;
+
+ tvhtrace(m->subsys, "%s - detected module '%s'", src, m->id);
+ priv = (eit_private_t *)m->opaque;
+ pid = priv->pid;
+
+ /* 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 (%s)", m->id, src);
+}
+
+void eit_nit_callback
+ (mpegts_table_t *mt, uint16_t nbid, const char *name, uint32_t nitpriv)
+{
+ mpegts_mux_t *dm = mt->mt_mux;
eit_nit_t *nit;
eit_private_t *priv = NULL;
- int pid, opts = 0;
tvhtrace(LS_TBL_EIT, "NIT - tsid %04X (%d) onid %04X (%d) nbid %04X (%d) network name '%s' private %08X",
dm->mm_tsid, dm->mm_tsid, dm->mm_onid, dm->mm_onid, nbid, nbid, name, nitpriv);
TAILQ_FOREACH(priv, &eit_private_list, link) {
- m = priv->module;
- if (priv->nitpriv && priv->nitpriv != nitpriv)
+ if (priv->priv && priv->priv != nitpriv)
continue;
if (LIST_FIRST(&priv->nit)) {
LIST_FOREACH(nit, &priv->nit, link) {
if (!priv)
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);
- }
+ eit_install_handlers(dm, priv, "NIT", EPGGRAB_OTA_MUX_EIT_NIT);
+}
- om = epggrab_ota_find_mux(dm);
- if (!om)
- 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, "NIT - module '%s' not enabled", m->id);
+void eit_sdt_callback(mpegts_table_t *mt, uint32_t sdtpriv)
+{
+ mpegts_mux_t *dm = mt->mt_mux;
+ 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(m->subsys, "NIT - detected module '%s'", m->id);
- priv = (eit_private_t *)m->opaque;
- pid = priv->pid;
+ 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);
- /* Standard (0x12) */
- if (pid == 0) {
- pid = DVB_EIT_PID;
- opts = MT_RECORD;
+ TAILQ_FOREACH(priv, &eit_private_list, link) {
+ if (!priv->sdt_enable)
+ continue;
+ if (priv->priv && priv->priv != sdtpriv)
+ continue;
+ if (LIST_FIRST(&priv->sdt)) {
+ LIST_FOREACH(sdt, &priv->sdt, link) {
+ if (eit_nit_array_check(dm->mm_onid, sdt->onid, sdt->onid_count))
+ continue;
+ if (eit_nit_array_check(dm->mm_tsid, sdt->tsid, sdt->tsid_count))
+ continue;
+ break;
+ }
+ if (sdt)
+ break;
+ } else {
+ break;
+ }
}
- 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);
+ if (!priv)
+ return;
+
+ eit_install_handlers(dm, priv, "SDT", EPGGRAB_OTA_MUX_EIT_SDT);
}
static void _eit_scrape_clear(eit_module_t *mod)
epggrab_ota_module_ops_t *ops;
eit_private_t *priv;
eit_nit_t *nit;
+ eit_sdt_t *sdt;
const char *s;
htsmsg_t *map, *e;
htsmsg_field_t *f;
s = htsmsg_get_str(conf, "conv");
if (s && strcmp(s, "huffman") == 0)
priv->conv = EIT_CONV_HUFFMAN;
- priv->nitpriv = htsmsg_get_u32_or_default(conf, "priv", 0);
+ priv->priv = htsmsg_get_u32_or_default(conf, "priv", 0);
map = htsmsg_get_map(conf, "nit");
if (map) {
HTSMSG_FOREACH(f, map) {
LIST_INSERT_HEAD(&priv->nit, nit, link);
}
}
+ priv->sdt_enable = htsmsg_get_u32_or_default(conf, "sdt_enable", 0);
+ map = htsmsg_get_map(conf, "sdt");
+ if (map) {
+ HTSMSG_FOREACH(f, map) {
+ sdt = calloc(1, sizeof(*sdt));
+ if ((e = htsmsg_field_get_map(f)) != NULL) {
+ eit_parse_list(e, "onid", nit->onid, ARRAY_SIZE(sdt->onid), &sdt->onid_count);
+ eit_parse_list(e, "tsid", nit->tsid, ARRAY_SIZE(sdt->tsid), &sdt->tsid_count);
+ }
+ LIST_INSERT_HEAD(&priv->sdt, sdt, link);
+ }
+ }
map = htsmsg_get_map(conf, "hacks");
if (map) {
HTSMSG_FOREACH(f, map) {