tvheadend/src/input/mpegts/iptv/iptv_mux.c
2014-08-01 14:37:23 +02:00

198 lines
5.4 KiB
C

/*
* IPTV Input
*
* Copyright (C) 2013 Andreas Öman
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "iptv_private.h"
#include "settings.h"
/*
* Class
*/
extern const idclass_t mpegts_mux_class;
extern const idclass_t mpegts_mux_instance_class;
static int
iptv_mux_url_set ( void *p, const void *v )
{
iptv_mux_t *im = p;
const char *str = v;
char *buf, port[16] = "";
size_t len;
url_t url;
if (strcmp(str, im->mm_iptv_url ?: "")) {
if (str == NULL || *str == '\0') {
free(im->mm_iptv_url);
free(im->mm_iptv_url_sane);
im->mm_iptv_url = NULL;
im->mm_iptv_url_sane = NULL;
return 1;
}
memset(&url, 0, sizeof(url));
if (!urlparse(str ?: "", &url)) {
free(im->mm_iptv_url);
free(im->mm_iptv_url_sane);
im->mm_iptv_url = str ? strdup(str) : NULL;
if (im->mm_iptv_url) {
len = strlen(url.scheme) + 3 +
strlen(url.host) + 1 +
/* port */ 16 +
strlen(url.path) + 1 +
strlen(url.query) + 2;
buf = alloca(len);
if (url.port)
snprintf(port, sizeof(port), "%d", url.port);
snprintf(buf, len, "%s%s%s%s%s%s",
url.scheme ?: "", url.scheme ? "://" : "",
url.host ?: "",
url.path ?: "", url.query ? "?" : "",
url.query);
im->mm_iptv_url_sane = strdup(buf);
} else {
im->mm_iptv_url_sane = NULL;
}
urlreset(&url);
return 1;
}
urlreset(&url);
}
return 0;
}
const idclass_t iptv_mux_class =
{
.ic_super = &mpegts_mux_class,
.ic_class = "iptv_mux",
.ic_caption = "IPTV Multiplex",
.ic_properties = (const property_t[]){
{
.type = PT_STR,
.id = "iptv_url",
.name = "URL",
.off = offsetof(iptv_mux_t, mm_iptv_url),
.set = iptv_mux_url_set,
},
{
.type = PT_STR,
.id = "iptv_interface",
.name = "Interface",
.off = offsetof(iptv_mux_t, mm_iptv_interface),
},
{
.type = PT_BOOL,
.id = "iptv_atsc",
.name = "ATSC",
.off = offsetof(iptv_mux_t, mm_iptv_atsc),
},
{
.type = PT_STR,
.id = "iptv_muxname",
.name = "Mux Name",
.off = offsetof(iptv_mux_t, mm_iptv_muxname),
},
{
.type = PT_STR,
.id = "iptv_sname",
.name = "Service Name",
.off = offsetof(iptv_mux_t, mm_iptv_svcname),
},
{}
}
};
static void
iptv_mux_config_save ( mpegts_mux_t *mm )
{
htsmsg_t *c = htsmsg_create_map();
mpegts_mux_save(mm, c);
hts_settings_save(c, "input/iptv/networks/%s/muxes/%s/config",
idnode_uuid_as_str(&mm->mm_network->mn_id),
idnode_uuid_as_str(&mm->mm_id));
htsmsg_destroy(c);
}
static void
iptv_mux_delete ( mpegts_mux_t *mm, int delconf )
{
char *url;
iptv_mux_t *im = (iptv_mux_t*)mm;
if (delconf)
hts_settings_remove("input/iptv/networks/%s/muxes/%s/config",
idnode_uuid_as_str(&mm->mm_network->mn_id),
idnode_uuid_as_str(&mm->mm_id));
url = im->mm_iptv_url; // Workaround for silly printing error
free(im->mm_iptv_interface);
free(im->mm_iptv_svcname);
mpegts_mux_delete(mm, delconf);
free(url);
}
static void
iptv_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len )
{
iptv_mux_t *im = (iptv_mux_t*)mm;
if(im->mm_iptv_muxname) {
strncpy(buf, im->mm_iptv_muxname, len);
buf[len-1] = '\0';
} else if(im->mm_iptv_url_sane) {
strncpy(buf, im->mm_iptv_url_sane, len);
buf[len-1] = '\0';
} else
*buf = 0;
}
/*
* Create
*/
iptv_mux_t *
iptv_mux_create0 ( iptv_network_t *in, const char *uuid, htsmsg_t *conf )
{
htsmsg_t *c, *e;
htsmsg_field_t *f;
/* Create Mux */
iptv_mux_t *im =
mpegts_mux_create(iptv_mux, uuid, (mpegts_network_t*)in,
MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, conf);
/* Callbacks */
im->mm_display_name = iptv_mux_display_name;
im->mm_config_save = iptv_mux_config_save;
im->mm_delete = iptv_mux_delete;
/* Create Instance */
(void)mpegts_mux_instance_create(mpegts_mux_instance, NULL,
(mpegts_input_t*)iptv_input,
(mpegts_mux_t*)im);
/* Services */
c = hts_settings_load_r(1, "input/iptv/networks/%s/muxes/%s/services",
idnode_uuid_as_str(&in->mn_id),
idnode_uuid_as_str(&im->mm_id));
if (c) {
HTSMSG_FOREACH(f, c) {
if (!(e = htsmsg_field_get_map(f))) continue;
(void)iptv_service_create0(im, 0, 0, f->hmf_name, e);
}
}
htsmsg_destroy(c);
return im;
}