*/
#include <string.h>
+
#include "tvheadend.h"
#include "channels.h"
#include "dvb/dvb.h"
typedef struct eit_status
{
- int tid;
- int tsid;
- int sid;
- int sec;
+ LIST_ENTRY(eit_status) link;
+ int tid;
+ uint16_t tsid;
+ uint16_t sid;
+ uint32_t sec[8];
+ int done;
} eit_status_t;
+typedef LIST_HEAD(, eit_status) eit_status_list_t;
+
+static eit_status_t *eit_status_find
+ ( eit_status_list_t *el, int tableid, uint16_t tsid, uint16_t sid,
+ uint8_t sec, uint8_t lst, uint8_t seg )
+{
+ int i;
+ uint32_t msk;
+ eit_status_t *sta;
+
+ /* Find */
+ LIST_FOREACH(sta, el, link)
+ if (sta->tid == tableid && sta->tsid == tsid && sta->sid == sid)
+ break;
+
+ /* Already complete */
+ if (sta && sta->done) return NULL;
+
+ /* Insert new entry */
+ if (!sta) {
+ sta = calloc(1, sizeof(eit_status_t));
+ LIST_INSERT_HEAD(el, sta, link);
+ sta->tid = tableid;
+ sta->tsid = tsid;
+ sta->sid = sid;
+ for (i = 0; i < (lst / 32); i++)
+ sta->sec[i] = 0xFFFFFFFF;
+ if (lst % 32)
+ sta->sec[i] = (0xFFFFFFFF >> (31-(lst%32)));
+ }
+
+ /* Get section mask */
+ if (sec == seg) {
+ msk = 0xFF << (((sec/8)%4) * 8);
+ } else {
+ msk = 0x1 << (sec%32);
+ }
+
+ /* Already seen */
+ if (!(sta->sec[sec/32] & msk)) return NULL;
+
+ /* Update */
+ sta->sec[sec/32] &= ~msk;
+ sta->done = 1;
+ for (i = 0; i < 8; i++ )
+ if (sta->sec[i]) sta->done = 0;
+ return sta;
+}
typedef struct eit_event
{
/* Find broadcast */
ebc = epg_broadcast_find_by_time(svc->s_ch, start, stop, eid, 1, &save2);
+ tvhlog(LOG_DEBUG, mod->id, "eid=%5d, start=%lu, stop=%lu, ebc=%p", eid, start, stop, ebc);
if (!ebc) return dllen + 12;
/* Mark re-schedule detect (only now/next) */
epggrab_ota_mux_t *ota;
th_dvb_adapter_t *tda;
service_t *svc;
+ eit_status_list_t *stal;
eit_status_t *sta;
int resched = 0, save = 0;
uint16_t tsid, sid;
/* Invalid */
- if(tableid < 0x4e || tableid > 0x6f || len < 11)
- return -1;
+ if(tableid < 0x4e || tableid > 0x6f || len < 11) return -1;
+
+ /* Don't process */
+ if((ptr[2] & 1) == 0) return 0;
/* Get OTA */
ota = epggrab_ota_find((epggrab_module_ota_t*)mod, tdmi);
if (!ota || !ota->status) return -1;
- sta = ota->status;
+ stal = ota->status;
/* Already complete */
if (epggrab_ota_is_complete(ota)) return 0;
sid = ptr[0] << 8 | ptr[1];
tsid = ptr[5] << 8 | ptr[6];
- /* Started */
- if (epggrab_ota_begin(ota)) {
- sta->tid = tableid;
- sta->tsid = tsid;
- sta->sid = sid;
- sta->sec = ptr[3];
-
- /* Complete */
- } else if (sta->tid == tableid &&
- sta->sec == ptr[3] &&
- sta->tsid == tsid &&
- sta->sid == sid) {
- epggrab_ota_complete(ota);
- return 0;
- }
-
- /* Don't process */
- if((ptr[2] & 1) == 0) return 0;
-
/* Get transport stream */
// Note: tableid=0x4f,0x60-0x6f is other TS
// so must find the tdmi
/* Ignore (not primary EPG service) */
if (!service_is_primary_epg(svc)) return 0;
+ sta = eit_status_find(stal, tableid, tsid, sid, ptr[3], ptr[4],
+ ptr[9]);
+ if (!sta) return 0;
+
+ /* Started */
+ if (epggrab_ota_begin(ota)) {
+ // nothing/clear?
+
+ /* Check end */
+ } else if (sta->done) {
+ LIST_FOREACH(sta, stal, link)
+ if (!sta->done) break;
+ }
+
/* Register as interesting */
if (tableid < 0x50)
epggrab_ota_register(ota, 20, 300); // 20s grab, 5min interval
// Note: this does mean you will get a slight oddity for muxes that
// carry both, since they will end up with setting of 600/300
- /* Up to date */
-#if TODO_INCLUDE_EIT_VER_CHECK
- ver = ptr[2] >> 1 & 0x1f;
- if (svc->s_dvb_eit_version[tableid-0x4f] == ver) return 0;
- svc->s_dvb_eit_version[tableid-0x4e] = ver;
-#endif
-
/* Process events */
len -= 11;
ptr += 11;
len -= r;
ptr += r;
}
+
+ /* Complete */
+ if (!sta) epggrab_ota_complete(ota);
/* Update EPG */
if (resched) epggrab_resched();
* Module Setup
* ***********************************************************************/
+static void _eit_ota_destroy ( epggrab_ota_mux_t *ota )
+{
+ eit_status_t *sta;
+ eit_status_list_t *stal = ota->status;
+
+ /* Remove all entries */
+ while ((sta = LIST_FIRST(stal))) {
+ LIST_REMOVE(sta, link);
+ free(sta);
+ }
+
+ free(stal);
+ free(ota);
+}
+
static void _eit_start
( epggrab_module_ota_t *m, th_dvb_mux_instance_t *tdmi )
{
epggrab_ota_mux_t *ota;
if (!m->enabled) return;
if (!(ota = epggrab_ota_create(m, tdmi))) return;
- if (!ota->status)
- ota->status = calloc(1, sizeof(eit_status_t));
- if (!strcmp("freesat", m->id))
- tdt_add(tdmi, NULL, _eit_callback, m, m->id, TDT_CRC, 0xf02, NULL);
- else
+ if (!ota->status) {
+ ota->status = calloc(1, sizeof(eit_status_list_t));
+ ota->destroy = _eit_ota_destroy;
+ }
+ if (!strcmp("freesat", m->id)) {
+#ifdef IGNORE_TOO_SLOW
+ tdt_add(tdmi, NULL, _eit_callback, m, m->id, TDT_CRC, 3841, NULL);
+#endif
+ tdt_add(tdmi, NULL, _eit_callback, m, m->id, TDT_CRC, 3003, NULL);
+ } else
tdt_add(tdmi, NULL, _eit_callback, m, m->id, TDT_CRC, 0x12, NULL);
- tvhlog(LOG_DEBUG, m->id, "install table handlers");
+ tvhlog(LOG_INFO, m->id, "install table handlers");
}
static int _eit_enable ( void *m, uint8_t e )
/* Register interest */
if (e) {
if (!strcmp(mod->id, "freesat"))
+#ifdef IGNORE_TOO_SLOW
epggrab_ota_create_and_register_by_id((epggrab_module_ota_t*)mod,
0, 2050,
- 600, 3600);
+ 600, 3600, "ASTRA");
+#endif
+ epggrab_ota_create_and_register_by_id((epggrab_module_ota_t*)mod,
+ 0, 2315,
+ 600, 3600, "Freesat");
/* Remove all links */
} else {
epggrab_ota_destroy_by_module((epggrab_module_ota_t*)mod);