typedef struct epggrab_module_ota epggrab_module_ota_t;
typedef struct epggrab_ota_mux epggrab_ota_mux_t;
typedef struct epggrab_ota_map epggrab_ota_map_t;
+typedef struct epggrab_ota_svc_link epggrab_ota_svc_link_t;
LIST_HEAD(epggrab_module_list, epggrab_module);
typedef struct epggrab_module_list epggrab_module_list_t;
int sock; ///< Socket descriptor
};
+struct epggrab_ota_svc_link
+{
+ char *uuid;
+ RB_ENTRY(epggrab_ota_svc_link) link;
+};
+
/*
* 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
char *om_mux_uuid; ///< Soft-link to mux
LIST_HEAD(,epggrab_ota_map) om_modules; ///< List of linked mods
+ int om_complete; ///< Has completed a scan
int om_active;
int om_timeout; ///< User configurable
int om_interval;
LIST_ENTRY(epggrab_ota_mux) om_q_link;
RB_ENTRY(epggrab_ota_mux) om_global_link;
+ RB_HEAD(,epggrab_ota_svc_link) om_svcs; ///< Muxes we carry data for
};
/*
/* Transponder tuning */
void (*start) ( epggrab_module_ota_t *m, struct mpegts_mux *mm );
void (*done) ( epggrab_module_ota_t *m );
- int (*tune) ( epggrab_module_ota_t *m, struct mpegts_mux *mm );
+ int (*tune) ( epggrab_module_ota_t *m, epggrab_ota_mux_t *om );
};
/*
#include "input.h"
#include "input/mpegts/dvb_charset.h"
+SKEL_DECLARE(svc_link_skel, epggrab_ota_svc_link_t);
+
+static int
+osl_cmp ( epggrab_ota_svc_link_t *a, epggrab_ota_svc_link_t *b )
+{
+ return strcmp(a->uuid, b->uuid);
+}
+
/* ************************************************************************
* Status handling
* ***********************************************************************/
epggrab_module_t *mod = mt->mt_opaque;
epggrab_ota_mux_t *ota = NULL;
mpegts_table_state_t *st;
+ epggrab_ota_svc_link_t *osl;
/* Validate */
if(tableid < 0x4e || tableid > 0x6f || len < 11)
/* Get service */
svc = mpegts_mux_find_service(mm, sid);
- // TODO: have lost the concept of the primary EPG service!
- if (!svc || !LIST_FIRST(&svc->s_channels))
+ if (!svc)
+ goto done;
+
+ /* Register this */
+ SKEL_ALLOC(svc_link_skel);
+ svc_link_skel->uuid = (char*)idnode_uuid_as_str(&svc->s_id);
+ osl = RB_INSERT_SORTED(&ota->om_svcs, svc_link_skel, link, osl_cmp);
+ if (!osl) {
+ svc_link_skel->uuid = strdup(svc_link_skel->uuid);
+ SKEL_USED(svc_link_skel);
+ }
+
+ /* No point processing */
+ if (!LIST_FIRST(&svc->s_channels))
goto done;
/* Process events */
}
static int _eit_tune
- ( epggrab_module_ota_t *m, mpegts_mux_t *mm )
+ ( epggrab_module_ota_t *m, epggrab_ota_mux_t *om )
{
- return 1;
+ int r = 0;
+ mpegts_service_t *s;
+ epggrab_ota_svc_link_t *osl, *nxt;
+
+ lock_assert(&global_lock);
+
+ /* Have gathered enough info to decide */
+ if (!om->om_complete)
+ return 1;
+
+ /* Non-standard (known to carry FULL network info) */
+ if (!strcmp(m->id, "uk_freesat") ||
+ !strcmp(m->id, "viasat_baltic"))
+ return 1;
+
+ /* Check if any services are mapped */
+ // TODO: using indirect ref's like this is inefficient, should
+ // consider changeing it?
+ for (osl = RB_FIRST(&om->om_svcs); osl != NULL; osl = nxt) {
+ nxt = RB_NEXT(osl, link);
+ if (!(s = mpegts_service_find_by_uuid(osl->uuid))) {
+ RB_REMOVE(&om->om_svcs, osl, link);
+ free(osl->uuid);
+ free(osl);
+ } else {
+ if (LIST_FIRST(&s->s_channels))
+ r = 1;
+ }
+ }
+
+ return r;
}
void eit_init ( void )
.tune = _eit_tune,
};
+ SKEL_USED(svc_link_skel);
+
epggrab_module_ota_create(NULL, "eit", "EIT: DVB Grabber", 1, &ops, NULL);
epggrab_module_ota_create(NULL, "uk_freesat", "UK: Freesat", 5, &ops, NULL);
epggrab_module_ota_create(NULL, "uk_freeview", "UK: Freeview", 5, &ops, NULL);
free(mod->summary);
}
-static int _opentv_tune ( epggrab_module_ota_t *m, mpegts_mux_t *mm )
+static int _opentv_tune
+ ( epggrab_module_ota_t *m, epggrab_ota_mux_t *om )
{
return 1;
}
lock_assert(&global_lock);
tvhdebug(mod->id, "grab complete");
+ /* Mark */
+ if (!ota->om_complete) {
+ ota->om_complete = 1;
+ epggrab_ota_save(ota);
+ }
+
/* Test for completion */
LIST_FOREACH(map, &ota->om_modules, om_link) {
if (map->om_module == mod) {
/* Check we have modules attached and enabled */
LIST_FOREACH(map, &om->om_modules, om_link) {
if (map->om_module->enabled &&
- map->om_module->tune && map->om_module->tune(map->om_module, mm))
+ map->om_module->tune && map->om_module->tune(map->om_module, om))
break;
}
if (!map) {
epggrab_ota_map_t *map;
htsmsg_t *e, *l, *c = htsmsg_create_map();
+ htsmsg_add_u32(c, "complete", ota->om_complete);
htsmsg_add_u32(c, "timeout", ota->om_timeout);
htsmsg_add_u32(c, "interval", ota->om_interval);
l = htsmsg_create_list();
void (*start) (epggrab_module_ota_t *m, struct mpegts_mux *mm);
int (*enable) (void *m, uint8_t e );
void (*done) (epggrab_module_ota_t*m);
- int (*tune) (epggrab_module_ota_t *m, struct mpegts_mux *mm);
+ int (*tune) (epggrab_module_ota_t *m, epggrab_ota_mux_t *om );
} epggrab_ota_module_ops_t;
epggrab_module_ota_t *epggrab_module_ota_create
mpegts_service_t *mpegts_service_find
( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, int create, int *save );
+#define mpegts_service_find_by_uuid(u)\
+ idnode_find(u, &mpegts_service_class)
+
void mpegts_service_delete ( service_t *s, int delconf );
/*