#include "tvheadend.h"
#include "psi.h"
#include "epg.h"
+#include "epggrab.h"
#include "channels.h"
#include "dtable.h"
#include "notify.h"
assert(x == NULL);
- epg_channel_map_add(ch);
+ epggrab_channel_add(ch);
htsp_channel_add(ch);
return ch;
channel_set_name(ch, name);
- epg_channel_map_add(ch);
+ epggrab_channel_add(ch);
tvh_str_update(&ch->ch_icon, htsmsg_get_str(c, "icon"));
RB_REMOVE(&channel_name_tree, ch, ch_name_link);
channel_set_name(ch, newname);
- epg_channel_map_mod(ch);
+ epggrab_channel_mod(ch);
LIST_FOREACH(t, &ch->ch_services, s_ch_link)
t->s_config_save(t);
s->ths_channel = NULL;
}
- epg_channel_map_rem(ch);
+ epggrab_channel_rem(ch);
+ epg_channel_unlink(ch);
hts_settings_remove("channels/%d", ch->ch_id);
htsp_channel_update(ch);
}
-/**
- *
- */
-void
-channel_set_epg_source(channel_t *ch, epg_channel_t *ec)
-{
- lock_assert(&global_lock);
-
- if(ec == ch->ch_epg_channel)
- return;
-
- ch->ch_epg_channel = ec;
-
- if(ec != NULL)
- tvh_str_update(&ch->ch_icon, ec->icon);
-
- channel_save(ch);
- htsp_channel_update(ch);
-}
-
/**
*
*/
#ifndef CHANNELS_H
#define CHANNELS_H
+#include "epg.h"
+
LIST_HEAD(channel_tag_mapping_list, channel_tag_mapping);
TAILQ_HEAD(channel_tag_queue, channel_tag);
LIST_HEAD(, service) ch_services;
LIST_HEAD(, th_subscription) ch_subscriptions;
- struct epg_channel *ch_epg_channel;
- LIST_ENTRY(channel) ch_eulink;
+ /* EPG fields */
+ epg_object_tree_t ch_epg_schedule;
+ epg_broadcast_t *ch_epg_now;
+ epg_broadcast_t *ch_epg_next;
+ gtimer_t ch_epg_timer;
gtimer_t ch_epg_timer_head;
gtimer_t ch_epg_timer_current;
void channel_merge(channel_t *dst, channel_t *src);
-void channel_set_epg_source(channel_t *ch, struct epg_channel *ec);
-
void channel_set_epg_postpre_time(channel_t *ch, int pre, int mins);
void channel_set_number(channel_t *ch, int number);
{
channel_tag_mapping_t *ctm;
- if (!e->channel || !e->channel->channel) return 0;
+ if (!e->channel) return 0;
if(dae->dae_enabled == 0 || dae->dae_weekdays == 0)
return 0;
return 0; // Avoid super wildcard match
if(dae->dae_channel != NULL &&
- dae->dae_channel != e->channel->channel)
+ dae->dae_channel != e->channel)
return 0;
if(dae->dae_channel_tag != NULL) {
LIST_FOREACH(ctm, &dae->dae_channel_tag->ct_ctms, ctm_tag_link)
- if(ctm->ctm_channel == e->channel->channel)
+ if(ctm->ctm_channel == e->channel)
break;
if(ctm == NULL)
return 0;
epg_broadcast_t *e, const char *creator,
dvr_autorec_entry_t *dae, dvr_prio_t pri)
{
- if(!e->channel || !e->channel->channel || !e->episode->title)
+ if(!e->channel || !e->episode->title)
return NULL;
return _dvr_entry_create(config_name, e,
- e->channel->channel, e->start, e->stop,
+ e->channel, e->start, e->stop,
e->episode->title,
e->episode->description ? e->episode->description
: e->episode->summary,
{
dvr_entry_t *de;
- LIST_FOREACH(de, &e->channel->channel->ch_dvrs, de_channel_link)
+ LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link)
if(de->de_bcast == e) return de;
return NULL;
}
if (e->episode->title == NULL)
return NULL;
- LIST_FOREACH(de, &e->channel->channel->ch_dvrs, de_channel_link)
+ LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link)
if ((abs(de->de_start - e->start) < 600) && (abs(de->de_stop - e->stop) < 600)) {
return de;
}
}
#endif
- if(e->channel->channel != NULL)
- addtag(q, build_tag_string("TVCHANNEL", e->channel->channel->ch_name, 0, NULL));
+ if(e->channel != NULL)
+ addtag(q, build_tag_string("TVCHANNEL", e->channel->ch_name, 0, NULL));
if(ee->title != NULL)
addtag(q, build_tag_string("TITLE", ee->title, 0, NULL));
#ifndef EPG_H
#define EPG_H
-#include "channels.h"
#include "settings.h"
+/*
+ * Forward decls
+ */
+struct channel;
+struct channel_tag;
+
/*
* Map types
*/
RB_HEAD(epg_brand_tree, epg_brand);
RB_HEAD(epg_season_tree, epg_season);
RB_HEAD(epg_episode_tree, epg_episode);
-RB_HEAD(epg_channel_tree, epg_channel);
RB_HEAD(epg_broadcast_tree, epg_broadcast);
/*
typedef struct epg_season epg_season_t;
typedef struct epg_episode epg_episode_t;
typedef struct epg_broadcast epg_broadcast_t;
-typedef struct epg_channel epg_channel_t;
typedef struct epg_object_list epg_object_list_t;
typedef struct epg_object_tree epg_object_tree_t;
typedef struct epg_brand_tree epg_brand_tree_t;
typedef struct epg_season_tree epg_season_tree_t;
typedef struct epg_episode_tree epg_episode_tree_t;
-typedef struct epg_channel_tree epg_channel_tree_t;
typedef struct epg_broadcast_tree epg_broadcast_tree_t;
/* ************************************************************************
{
epg_object_t _; ///< Parent object
- uint32_t dvb_id; ///< DVB identifier
time_t start; ///< Start time
time_t stop; ///< End time
RB_ENTRY(epg_broadcast) elink; ///< Episode link
epg_episode_t *episode; ///< Episode shown
- epg_channel_t *channel; ///< Channel being broadcast on
+ struct channel *channel; ///< Channel being broadcast on
} epg_broadcast_t;
/* Lookup */
epg_broadcast_t *epg_broadcast_find_by_time
- ( epg_channel_t *ch, time_t start, time_t stop, int create, int *save );
-epg_broadcast_t *epg_broadcast_find_by_id ( uint64_t id, epg_channel_t *ch );
+ ( struct channel *ch, time_t start, time_t stop, int create, int *save );
+epg_broadcast_t *epg_broadcast_find_by_id ( uint64_t id, struct channel *ch );
/* Mutators */
int epg_broadcast_set_episode ( epg_broadcast_t *b, epg_episode_t *e )
* Channel - provides mapping from EPG channels to real channels
* ***********************************************************************/
-/* Object */
-typedef struct epg_channel
-{
- epg_object_t _; ///< Parent object
-
- char *name; ///< Channel name
- char *icon; ///< Channel icon
- char **sname; ///< DVB svc names (to map)
- int **sid; ///< DVB svc ids (to map)
-
- epg_object_tree_t schedule; ///< List of broadcasts
- LIST_ENTRY(epg_channel) umlink; ///< Unmapped channel link
- channel_t *channel; ///< Link to real channel
-
- epg_broadcast_t *now; ///< Current broadcast
- epg_broadcast_t *next; ///< Next broadcast
-
- gtimer_t expire; ///< Expiration timer
-} epg_channel_t;
-
-/* Lookup */
-epg_channel_t *epg_channel_find_by_uri
- ( const char *uri, int create, int *save );
-epg_channel_t *epg_channel_find_by_id ( uint64_t id );
-
-/* Mutators */
-int epg_channel_set_name ( epg_channel_t *c, const char *n )
- __attribute__((warn_unused_result));
-int epg_channel_set_icon ( epg_channel_t *c, const char *i )
- __attribute__((warn_unused_result));
-int epg_channel_set_channel ( epg_channel_t *c, channel_t *ch );
-
/* Accessors */
epg_broadcast_t *epg_channel_get_broadcast
- ( epg_channel_t *ch, time_t start, time_t stop, int create, int *save );
-
-/* Serialization */
-htsmsg_t *epg_channel_serialize ( epg_channel_t *b );
-epg_channel_t *epg_channel_deserialize ( htsmsg_t *m, int create, int *save );
+ ( struct channel *ch, time_t start, time_t stop, int create, int *save );
-/* Channel mapping */
-void epg_channel_map_add ( channel_t *ch );
-void epg_channel_map_rem ( channel_t *ch );
-void epg_channel_map_mod ( channel_t *ch );
+/* Unlink */
+void epg_channel_unlink ( struct channel *ch );
/* ************************************************************************
* Querying
void epg_query_sort(epg_query_result_t *eqr);
/* Query routines */
-void epg_query0(epg_query_result_t *eqr, channel_t *ch, channel_tag_t *ct,
- uint8_t type, const char *title);
+void epg_query0(epg_query_result_t *eqr, struct channel *ch,
+ struct channel_tag *ct, uint8_t type, const char *title);
void epg_query(epg_query_result_t *eqr, const char *channel, const char *tag,
const char *contentgroup, const char *title);
void (*disable) ( void );
htsmsg_t* (*grab) ( const char *opts );
int (*parse) ( htsmsg_t *data, epggrab_stats_t *stats );
+ void (*ch_add) ( struct channel *ch );
+ void (*ch_rem) ( struct channel *ch );
+ void (*ch_mod) ( struct channel *ch );
} epggrab_module_t;
/*
void epggrab_set_advanced ( uint32_t count, epggrab_sched_t* sched );
void epggrab_set_eit ( uint32_t eit );
+/*
+ * Channel handling
+ */
+void epggrab_channel_add ( struct channel *ch );
+void epggrab_channel_rem ( struct channel *ch );
+void epggrab_channel_mod ( struct channel *ch );
+
#endif /* __EPGGRAB_H__ */
if(ch->ch_icon != NULL)
htsmsg_add_str(out, "channelIcon", ch->ch_icon);
- if (ch->ch_epg_channel) {
- now = ch->ch_epg_channel->now;
- next = ch->ch_epg_channel->next;
- htsmsg_add_u32(out, "eventId", now ? now->_.id : 0);
- htsmsg_add_u32(out, "nextEventId", next ? next->_.id : 0);
- }
+ now = ch->ch_epg_now;
+ next = ch->ch_epg_next;
+ htsmsg_add_u32(out, "eventId", now ? now->_.id : 0);
+ htsmsg_add_u32(out, "nextEventId", next ? next->_.id : 0);
LIST_FOREACH(ctm, &ch->ch_ctms, ctm_channel_link) {
ct = ctm->ctm_tag;
out = htsmsg_create_map();
htsmsg_add_u32(out, "eventId", e->_.id);
- htsmsg_add_u32(out, "channelId", e->channel->channel->ch_id);
+ htsmsg_add_u32(out, "channelId", e->channel->ch_id);
htsmsg_add_u32(out, "start", e->start);
htsmsg_add_u32(out, "stop", e->stop);
if(e->episode->title != NULL)
htsmsg_add_str(m, "method", "channelUpdate");
htsmsg_add_u32(m, "channelId", ch->ch_id);
- now = ch->ch_epg_channel->now;
- next = ch->ch_epg_channel->next;
+ now = ch->ch_epg_now;
+ next = ch->ch_epg_next;
htsmsg_add_u32(m, "eventId", now ? now->_.id : 0);
htsmsg_add_u32(m, "nextEventId", next ? next->_.id : 0);
htsp_async_send(m);
for(i = start; i < end; i++) {
e = eqr.eqr_array[i];
ee = e->episode;
- ch = e->channel->channel;
+ ch = e->channel;
if (!ch||!ee) continue;
m = htsmsg_create_map();
/* Alternative broadcasts */
if (!strcmp(type, "alternative")) {
RB_FOREACH(ebc, &ee->broadcasts, elink) {
- ch = ebc->channel->channel;
+ ch = ebc->channel;
if ( !ch ) continue; // skip something not viewable
if ( ebc == e ) continue; // skip self
count++;
days[a.tm_wday], a.tm_mday, a.tm_mon + 1,
a.tm_hour, a.tm_min, b.tm_hour, b.tm_min);
- // TODO: use real channel?
htsbuf_qprintf(hq, "<hr><b>\"%s\": \"%s\"</b><br><br>",
- e->channel->name, e->episode->title);
+ e->channel->ch_name, e->episode->title);
dvr_status = de != NULL ? de->de_sched_state : DVR_NOSTATE;
sm->sm_data = NULL;
epg_broadcast_t *e = NULL;
- if(s->ths_channel) e = s->ths_channel->ch_epg_channel->now;
+ if(s->ths_channel) e = s->ths_channel->ch_epg_now;
if(e && event_id != e->_.id) {
event_id = e->_.id;