Fix various bugs related to channel <-> service mappings

This commit is contained in:
Andreas Öman 2008-05-03 06:55:56 +00:00
parent cb32905c3c
commit 0d7cbe9ac2
15 changed files with 91 additions and 81 deletions

View file

@ -413,13 +413,13 @@ ajax_cheditor(http_connection_t *hc, http_reply_t *hr,
tcp_qprintf(tq, "<div>Sources:</div>");
LIST_FOREACH(t, &ch->ch_transports, tht_channel_link) {
LIST_FOREACH(t, &ch->ch_transports, tht_ch_link) {
ajax_box_begin(tq, AJAX_BOX_BORDER, NULL, NULL, NULL);
tcp_qprintf(tq, "<div style=\"overflow: auto; width: 100%\">");
tcp_qprintf(tq, "<div style=\"float: left; width: 13%%\">%s</div>",
val2str(t->tht_type, sourcetypetab) ?: "???");
tcp_qprintf(tq, "<div style=\"float: left; width: 87%%\">\"%s\"%s</div>",
t->tht_servicename, t->tht_scrambled ? " - (scrambled)" : "");
t->tht_svcname, t->tht_scrambled ? " - (scrambled)" : "");
s = t->tht_sourcename ? t->tht_sourcename(t) : NULL;
tcp_qprintf(tq, "</div><div style=\"overflow: auto; width: 100%\">");

View file

@ -134,7 +134,7 @@ ajax_transport_build_list(http_connection_t *hc, tcp_queue_t *tq,
ajax_table_cell(&ta, NULL, "%d", t->tht_dvb_service_id);
ajax_table_cell(&ta, NULL, "%s", t->tht_scrambled ? "Yes" : "No");
ajax_table_cell(&ta, NULL, "%s", transport_servicetype_txt(t));
ajax_table_cell(&ta, NULL, "%s", t->tht_servicename ?: "");
ajax_table_cell(&ta, NULL, "%s", t->tht_svcname ?: "");
ajax_table_cell(&ta, NULL,
"<a href=\"javascript:void(0)\" "
@ -142,9 +142,9 @@ ajax_transport_build_list(http_connection_t *hc, tcp_queue_t *tq,
"{parameters: {'%s': 'selected'}})\">"
"<img id=\"map_%s\" src=\"/gfx/%smapped.png\"></a>",
t->tht_identifier, t->tht_identifier,
t->tht_channel ? "" : "un");
t->tht_ch ? "" : "un");
if(t->tht_channel == NULL) {
if(t->tht_ch == NULL) {
/* Unmapped */
ajax_table_cell(&ta, "chname",
"<a href=\"javascript:void(0)\" "
@ -152,9 +152,9 @@ ajax_transport_build_list(http_connection_t *hc, tcp_queue_t *tq,
"'/ajax/transport_rename_channel/%s', '%s')\">"
"%s</a>",
t->tht_identifier, t->tht_identifier,
t->tht_channelname, t->tht_channelname);
t->tht_chname, t->tht_chname);
} else {
ajax_table_cell(&ta, "chname", "%s", t->tht_channel->ch_name);
ajax_table_cell(&ta, "chname", "%s", t->tht_ch->ch_name);
}
ajax_table_cell_checkbox(&ta);
@ -254,8 +254,8 @@ ajax_transport_rename_channel(http_connection_t *hc, http_reply_t *hr,
if((newname = http_arg_get(&hc->hc_req_args, "newname")) == NULL)
return HTTP_STATUS_BAD_REQUEST;
free((void *)t->tht_channelname);
t->tht_channelname = strdup(newname);
free((void *)t->tht_chname);
t->tht_chname = strdup(newname);
ajax_a_jsfuncf(tq, newname,
"tentative_chname('chname_%s', "
@ -273,12 +273,12 @@ ajax_transport_rename_channel(http_connection_t *hc, http_reply_t *hr,
static void
dvb_map_channel(th_transport_t *t, tcp_queue_t *tq)
{
transport_map_channel(t);
transport_map_channel(t, NULL);
tcp_qprintf(tq,
"$('chname_%s').innerHTML='%s';\n\r"
"$('map_%s').src='/gfx/mapped.png';\n\r",
t->tht_identifier, t->tht_channel->ch_name,
t->tht_identifier, t->tht_ch->ch_name,
t->tht_identifier);
}
@ -299,7 +299,7 @@ dvb_unmap_channel(th_transport_t *t, tcp_queue_t *tq)
"';\n\r"
"$('map_%s').src='/gfx/unmapped.png';\n\r",
t->tht_identifier, t->tht_identifier, t->tht_identifier,
t->tht_channelname, t->tht_channelname, t->tht_identifier);
t->tht_chname, t->tht_chname, t->tht_identifier);
}
@ -327,13 +327,13 @@ ajax_transport_op(http_connection_t *hc, http_reply_t *hr,
continue;
if(!strcmp(op, "toggle")) {
if(t->tht_channel)
if(t->tht_ch)
dvb_unmap_channel(t, tq);
else
dvb_map_channel(t, tq);
} else if(!strcmp(op, "map") && t->tht_channel == NULL) {
} else if(!strcmp(op, "map") && t->tht_ch == NULL) {
dvb_map_channel(t, tq);
} else if(!strcmp(op, "unmap") && t->tht_channel != NULL) {
} else if(!strcmp(op, "unmap") && t->tht_ch != NULL) {
dvb_unmap_channel(t, tq);
} else if(!strcmp(op, "probe")) {
serviceprobe_add(t);

View file

@ -116,9 +116,8 @@ avgen_init(void)
t->tht_provider = strdup("HTS Tvheadend");
t->tht_identifier = strdup("test1");
t->tht_servicename = strdup("test1");
transport_map_channel(t);
transport_map_channel(t, ch);
}

View file

@ -461,9 +461,9 @@ channel_rename(channel_t *ch, const char *newname)
LIST_REMOVE(ch, ch_global_link);
channel_set_name(ch, newname);
LIST_FOREACH(t, &ch->ch_transports, tht_channel_link) {
free(t->tht_servicename);
t->tht_servicename = strdup(newname);
LIST_FOREACH(t, &ch->ch_transports, tht_ch_link) {
free(t->tht_chname);
t->tht_chname = strdup(newname);
t->tht_config_change(t);
}
@ -497,6 +497,9 @@ channel_delete(channel_t *ch)
autorec_destroy_by_channel(ch);
snprintf(buf, sizeof(buf), "%s/channels/%s", settings_dir, ch->ch_sname);
unlink(buf);
free((void *)ch->ch_name);
free((void *)ch->ch_sname);
free(ch->ch_icon);
@ -505,8 +508,6 @@ channel_delete(channel_t *ch)
LIST_REMOVE(ch, ch_global_link);
free(ch);
snprintf(buf, sizeof(buf), "%s/channels/%s", settings_dir, ch->ch_sname);
unlink(buf);
}
@ -524,10 +525,7 @@ channel_merge(channel_t *dst, channel_t *src)
while((t = LIST_FIRST(&src->ch_transports)) != NULL) {
transport_unmap_channel(t);
free(t->tht_servicename);
t->tht_servicename = strdup(dst->ch_name);
transport_map_channel(t);
transport_map_channel(t, dst);
t->tht_config_change(t);
}

4
cwc.c
View file

@ -503,7 +503,7 @@ cwc_dispatch_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len)
if(ct->ct_keystate != CT_FORBIDDEN) {
syslog(LOG_ERR,
"Can not descramble \"%s\" for service \"%s\", access denied",
t->tht_identifier, t->tht_servicename);
t->tht_identifier, t->tht_svcname);
ct->ct_keystate = CT_FORBIDDEN;
}
@ -513,7 +513,7 @@ cwc_dispatch_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len)
if(ct->ct_keystate != CT_RESOLVED)
syslog(LOG_INFO,
"Obtained key for \"%s\" for service \"%s\"",
t->tht_identifier, t->tht_servicename);
t->tht_identifier, t->tht_svcname);
ct->ct_keystate = CT_RESOLVED;
set_control_words(ct->ct_keys, msg + 3, msg + 3 + 8);

34
dvb.c
View file

@ -581,13 +581,13 @@ dvb_tdmi_save(th_dvb_mux_instance_t *tdmi)
if(t->tht_provider != NULL)
fprintf(fp, "\tprovider = %s\n", t->tht_provider);
if(t->tht_servicename)
fprintf(fp, "\tservicename = %s\n", t->tht_servicename);
if(t->tht_svcname)
fprintf(fp, "\tservicename = %s\n", t->tht_svcname);
if(t->tht_channelname)
fprintf(fp, "\tchannelname = %s\n", t->tht_channelname);
if(t->tht_chname)
fprintf(fp, "\tchannelname = %s\n", t->tht_chname);
fprintf(fp, "\tmapped = %d\n", t->tht_channel ? 1 : 0);
fprintf(fp, "\tmapped = %d\n", t->tht_ch ? 1 : 0);
psi_save_transport(fp, t);
@ -634,21 +634,21 @@ dvb_tdmi_load(th_dvb_mux_instance_t *tdmi)
t->tht_provider = strdup(v);
v = config_get_str_sub(&ce->ce_sub, "servicename", "unknown");
free((void *)t->tht_servicename);
t->tht_servicename = strdup(v);
free((void *)t->tht_svcname);
t->tht_svcname = strdup(v);
v = config_get_str_sub(&ce->ce_sub, "channelname", NULL);
if(v != NULL) {
free((void *)t->tht_channelname);
t->tht_channelname = strdup(v);
free((void *)t->tht_chname);
t->tht_chname = strdup(v);
} else {
t->tht_channelname = strdup(t->tht_servicename);
t->tht_chname = strdup(t->tht_svcname);
}
psi_load_transport(&ce->ce_sub, t);
if(atoi(config_get_str_sub(&ce->ce_sub, "mapped", "0"))) {
transport_map_channel(t);
transport_map_channel(t, NULL);
}
}
config_free0(&cl);
@ -738,14 +738,14 @@ dvb_tda_clone(th_dvb_adapter_t *dst, th_dvb_adapter_t *src)
if(t_src->tht_provider != NULL)
t_dst->tht_provider = strdup(t_src->tht_provider);
if(t_src->tht_servicename != NULL)
t_dst->tht_servicename = strdup(t_src->tht_servicename);
if(t_src->tht_svcname != NULL)
t_dst->tht_svcname = strdup(t_src->tht_svcname);
if(t_src->tht_channelname != NULL)
t_dst->tht_channelname = strdup(t_src->tht_channelname);
if(t_src->tht_chname != NULL)
t_dst->tht_chname = strdup(t_src->tht_chname);
if(t_src->tht_channel != NULL)
transport_map_channel(t_dst);
if(t_src->tht_ch != NULL)
transport_map_channel(t_dst, t_src->tht_ch);

View file

@ -255,7 +255,7 @@ dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
if(t == NULL)
return;
ch = t->tht_channel;
ch = t->tht_ch;
if(ch == NULL)
return;
@ -410,7 +410,7 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
t->tht_servicetype != stype ||
t->tht_scrambled != free_ca_mode ||
strcmp(t->tht_provider ?: "", provider) ||
strcmp(t->tht_servicename ?: "", chname );
strcmp(t->tht_svcname ?: "", chname );
t->tht_servicetype = stype;
t->tht_scrambled = free_ca_mode;
@ -418,11 +418,11 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
free((void *)t->tht_provider);
t->tht_provider = strdup(provider);
free((void *)t->tht_servicename);
t->tht_servicename = strdup(chname);
free((void *)t->tht_svcname);
t->tht_svcname = strdup(chname);
if(t->tht_channelname == NULL)
t->tht_channelname = strdup(chname);
if(t->tht_chname == NULL)
t->tht_chname = strdup(chname);
}
break;
}

View file

@ -156,8 +156,7 @@ file_input_init(void)
t->tht_provider = strdup("HTS Tvheadend");
t->tht_identifier = strdup(ch->ch_name);
t->tht_file_input = fi;
t->tht_servicename = strdup(ch->ch_name);
transport_map_channel(t);
transport_map_channel(t, ch);
}
}

View file

@ -236,7 +236,7 @@ iptv_configure_transport(th_transport_t *t, const char *iptv_type,
inet_ntoa(t->tht_iptv_group_addr), t->tht_iptv_port);
t->tht_identifier = strdup(buf);
t->tht_channelname = strdup(channel_name);
t->tht_chname = strdup(channel_name);
LIST_INSERT_HEAD(&iptv_probing_transports, t, tht_active_link);
startupcounter++;
@ -278,7 +278,7 @@ iptv_probe_done(th_transport_t *t, int timeout)
iptv_stop_feed(t);
if(!timeout)
transport_map_channel(t);
transport_map_channel(t, NULL);
else
LIST_INSERT_HEAD(&iptv_stale_transports, t, tht_active_link);

View file

@ -84,6 +84,7 @@ sp_timeout(void *aux, int64_t now)
sp_t *sp = aux;
th_transport_t *t = sp->sp_s->ths_transport;
const char *errtxt;
channel_t *ch;
switch(sp->sp_error) {
case 0:
@ -103,11 +104,13 @@ sp_timeout(void *aux, int64_t now)
break;
}
syslog(LOG_INFO, "Probed \"%s\" -- %s\n", t->tht_servicename, errtxt);
syslog(LOG_INFO, "Probed \"%s\" -- %s\n", t->tht_svcname, errtxt);
if(sp->sp_error == 0) {
if(t->tht_channel == NULL && t->tht_servicename != NULL) {
transport_map_channel(t);
if(t->tht_ch == NULL && t->tht_svcname != NULL) {
ch = channel_find(t->tht_svcname, 1, NULL);
transport_map_channel(t, ch);
t->tht_config_change(t);
}
}

View file

@ -180,7 +180,7 @@ tt_decode_line(th_transport_t *t, uint8_t *buf)
uint8_t mpag, line, s12, s34, c;
int page, magidx, i;
tt_mag_t *mag;
channel_t *ch = t->tht_channel;
channel_t *ch = t->tht_ch;
tt_decoder_t *ttd = &ch->ch_tt;
tt_page_t *ttp;

View file

@ -281,13 +281,13 @@ transport_find(channel_t *ch, unsigned int weight)
/* First, sort all transports in order */
LIST_FOREACH(t, &ch->ch_transports, tht_channel_link)
LIST_FOREACH(t, &ch->ch_transports, tht_ch_link)
if(!t->tht_disabled)
cnt++;
vec = alloca(cnt * sizeof(th_transport_t *));
i = 0;
LIST_FOREACH(t, &ch->ch_transports, tht_channel_link)
LIST_FOREACH(t, &ch->ch_transports, tht_ch_link)
if(!t->tht_disabled)
vec[i++] = t;
@ -433,9 +433,9 @@ transport_destroy(th_transport_t *t)
free((void *)t->tht_name);
if(t->tht_channel != NULL) {
t->tht_channel = NULL;
LIST_REMOVE(t, tht_channel_link);
if(t->tht_ch != NULL) {
t->tht_ch = NULL;
LIST_REMOVE(t, tht_ch_link);
}
LIST_REMOVE(t, tht_mux_link);
@ -444,8 +444,8 @@ transport_destroy(th_transport_t *t)
transport_flush_subscribers(t);
free(t->tht_identifier);
free(t->tht_servicename);
free(t->tht_channelname);
free(t->tht_svcname);
free(t->tht_chname);
free(t->tht_provider);
while((st = LIST_FIRST(&t->tht_streams)) != NULL) {
@ -524,19 +524,26 @@ transport_add_stream(th_transport_t *t, int pid, tv_streamtype_t type)
*
*/
void
transport_map_channel(th_transport_t *t)
transport_map_channel(th_transport_t *t, channel_t *ch)
{
channel_t *ch = channel_find(t->tht_servicename, 1, NULL);
assert(t->tht_ch == NULL);
assert(t->tht_channel == NULL);
if(ch == NULL) {
if(t->tht_chname == NULL)
return;
ch = channel_find(t->tht_chname, 1, NULL);
} else {
free(t->tht_chname);
t->tht_chname = strdup(ch->ch_name);
}
avgstat_init(&t->tht_cc_errors, 3600);
avgstat_init(&t->tht_rate, 10);
assert(t->tht_identifier != NULL);
t->tht_channel = ch;
t->tht_ch = ch;
LIST_INSERT_HEAD(&ch->ch_transports, t, tht_channel_link);
LIST_INSERT_HEAD(&ch->ch_transports, t, tht_ch_link);
}
/**
@ -545,8 +552,8 @@ transport_map_channel(th_transport_t *t)
void
transport_unmap_channel(th_transport_t *t)
{
t->tht_channel = NULL;
LIST_REMOVE(t, tht_channel_link);
t->tht_ch = NULL;
LIST_REMOVE(t, tht_ch_link);
}

View file

@ -32,7 +32,7 @@ th_transport_t *transport_create(const char *identifier, int type,
th_transport_t *transport_find_by_identifier(const char *identifier);
void transport_map_channel(th_transport_t *t);
void transport_map_channel(th_transport_t *t, channel_t *ch);
void transport_unmap_channel(th_transport_t *t);

View file

@ -418,9 +418,6 @@ typedef struct th_transport {
LIST_ENTRY(th_transport) tht_active_link;
LIST_ENTRY(th_transport) tht_channel_link;
struct channel *tht_channel;
LIST_HEAD(, th_subscription) tht_subscriptions;
int (*tht_start_feed)(struct th_transport *t, unsigned int weight,
@ -474,8 +471,7 @@ typedef struct th_transport {
} u;
char *tht_identifier;
char *tht_servicename;
char *tht_channelname;
char *tht_svcname;
char *tht_provider;
enum {
@ -508,6 +504,14 @@ typedef struct th_transport {
TAILQ_ENTRY(th_transport) tht_probe_link;
int tht_on_probe_queue;
/**
* Channel mapping
*/
LIST_ENTRY(th_transport) tht_ch_link;
struct channel *tht_ch;
char *tht_chname;
} th_transport_t;

4
v4l.c
View file

@ -97,9 +97,9 @@ v4l_configure_transport(th_transport_t *t, const char *muxname,
snprintf(buf, sizeof(buf), "analog_%u", t->tht_v4l_frequency);
t->tht_identifier = strdup(buf);
t->tht_servicename = strdup(channel_name);
t->tht_chname = strdup(channel_name);
transport_map_channel(t);
transport_map_channel(t, NULL);
return 0;
}