return 0;
}
+/**
+ *
+ */
+void
+bouquet_delete(bouquet_t *bq)
+{
+ if (bq == NULL) return;
+ bq->bq_enabled = 0;
+ bouquet_map_to_channels(bq);
+ if (!bq->bq_shield) {
+ hts_settings_remove("bouquet/%s", idnode_uuid_as_sstr(&bq->bq_id));
+ bouquet_destroy(bq);
+ } else {
+ idnode_set_free(bq->bq_services);
+ bq->bq_services = idnode_set_create(1);
+ bouquet_save(bq, 1);
+ }
+}
+
/**
*
*/
static void
bouquet_class_delete(idnode_t *self)
{
- bouquet_t *bq = (bouquet_t *)self;
-
- bq->bq_enabled = 0;
- bouquet_map_to_channels(bq);
- if (!bq->bq_shield) {
- hts_settings_remove("bouquet/%s", idnode_uuid_as_sstr(&bq->bq_id));
- bouquet_destroy(bq);
- } else {
- idnode_set_free(bq->bq_services);
- bq->bq_services = idnode_set_create(1);
- bouquet_save(bq, 1);
- }
+ bouquet_delete((bouquet_t *)self);
}
static const char *
#include "settings.h"
#include "htsstr.h"
#include "channels.h"
+#include "bouquet.h"
#include <sys/socket.h>
#include <sys/types.h>
return RB_FIND(&iptv_handlers, &ih, link, ih_cmp);
}
+/* **************************************************************************
+ * IPTV bouquet
+ * *************************************************************************/
+
+static bouquet_t *
+iptv_bouquet_get (iptv_network_t *in, int create)
+{
+ char buf[128];
+ snprintf(buf, sizeof(buf), "iptv-network://%s", idnode_uuid_as_sstr(&in->mn_id));
+ return bouquet_find_by_source(in->in_url, buf, create);
+}
+
+static void
+iptv_bouquet_update(void *aux)
+{
+ iptv_network_t *in = aux;
+ mpegts_mux_t *mm;
+ mpegts_service_t *ms;
+ bouquet_t *bq = in->in_bouquet ? iptv_bouquet_get(in, 1) : NULL;
+ uint32_t seen = 0;
+ if (bq == NULL)
+ return;
+ LIST_FOREACH(mm, &in->mn_muxes, mm_network_link)
+ LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) {
+ bouquet_add_service(bq, (service_t *)ms, ((iptv_mux_t *)mm)->mm_iptv_chnum, 0);
+ seen++;
+ }
+ bouquet_completed(bq, seen);
+}
+
+void
+iptv_bouquet_trigger(iptv_network_t *in, int timeout)
+{
+ gtimer_arm(&in->in_bouquet_timer, iptv_bouquet_update, in, timeout);
+}
+
+
/* **************************************************************************
* IPTV input
* *************************************************************************/
{
return tvh_gettext_lang(lang, N_("IPTV"));
}
+
extern const idclass_t mpegts_input_class;
const idclass_t iptv_input_class = {
.ic_super = &mpegts_input_class,
char *icon_url = in->in_icon_url;
char *icon_url_sane = in->in_icon_url_sane;
+ gtimer_disarm(&in->in_bouquet_timer);
+
if (in->mn_id.in_class == &iptv_auto_network_class)
iptv_auto_network_done(in);
/* Remove config */
- if (delconf)
+ if (delconf) {
hts_settings_remove("input/iptv/networks/%s",
idnode_uuid_as_sstr(&in->mn_id));
+ bouquet_delete(iptv_bouquet_get(in, 0));
+ }
/* delete */
free(in->in_remove_args);
iptv_auto_network_trigger(in);
}
+static void
+iptv_auto_network_class_notify_bouquet( void *in, const char *lang )
+{
+ iptv_network_t *mn = in;
+ bouquet_t *bq;
+ if (mn->in_bouquet) {
+ iptv_bouquet_trigger(mn, 0);
+ } else {
+ if (mn->in_bouquet) {
+ bq = iptv_bouquet_get(mn, 0);
+ if (bq)
+ bouquet_delete(bq);
+ }
+ }
+}
+
static htsmsg_t *
iptv_auto_network_class_charset_list(void *o, const char *lang)
{
.notify = iptv_auto_network_class_notify_url,
.opts = PO_MULTILINE
},
+ {
+ .type = PT_BOOL,
+ .id = "bouquet",
+ .name = N_("Create bouquet"),
+ .off = offsetof(iptv_network_t, in_bouquet),
+ .notify = iptv_auto_network_class_notify_bouquet,
+ },
{
.type = PT_STR,
.id = "ctx_charset",
#define IPTV_KILL_USR1 4
#define IPTV_KILL_USR2 5
+struct bouquet;
+
extern pthread_mutex_t iptv_lock;
typedef struct iptv_input iptv_input_t;
char *in_url;
char *in_url_sane;
+ int in_bouquet;
+ gtimer_t in_bouquet_timer;
char *in_ctx_charset;
int64_t in_channel_number;
uint32_t in_refetch_period;
extern iptv_input_t *iptv_input;
extern iptv_network_t *iptv_network;
+
+void iptv_bouquet_trigger(iptv_network_t *in, int timeout);
int iptv_url_set ( char **url, char **sane_url, const char *str, int allow_file, int allow_pipe );
void iptv_mux_load_all ( void );
( iptv_mux_t *im, uint16_t sid, uint16_t pmt,
const char *uuid, htsmsg_t *conf )
{
+ iptv_network_t *in = (iptv_network_t *)im->mm_network;
iptv_service_t *is = (iptv_service_t*)
mpegts_service_create0(calloc(1, sizeof(mpegts_service_t)),
&mpegts_service_class, uuid,
if (im->mm_iptv_svcname)
is->s_dvb_svcname = strdup(im->mm_iptv_svcname);
+ if (in->in_bouquet)
+ iptv_bouquet_trigger(in, 1);
+
return is;
}