From b55dbe7f0f85d7f61a298371da2b891df3e1dc9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Sun, 4 May 2008 15:31:39 +0000 Subject: [PATCH] Rework the 'error' notfication for subscribers to a more generic and and flexible transport status tool. --- cwc.c | 2 +- serviceprobe.c | 53 +++++++++++++++++++++++--------------------------- transports.c | 12 +++++++++--- transports.h | 2 +- tsdemux.c | 6 +++--- tvhead.h | 24 +++++++++++++++-------- 6 files changed, 54 insertions(+), 45 deletions(-) diff --git a/cwc.c b/cwc.c index 1b42fb95..88edae2d 100644 --- a/cwc.c +++ b/cwc.c @@ -700,7 +700,7 @@ cwc_descramble(th_descrambler_t *td, th_transport_t *t, struct th_stream *st, uint8_t *t0; if(ct->ct_keystate == CT_FORBIDDEN) - return TRANSPORT_ERROR_NO_ACCESS; + return 1; if(ct->ct_keystate != CT_RESOLVED) return -1; diff --git a/serviceprobe.c b/serviceprobe.c index 8c06a9e2..19b3220d 100644 --- a/serviceprobe.c +++ b/serviceprobe.c @@ -46,7 +46,8 @@ typedef struct sp { dtimer_t sp_timer; th_muxer_t *sp_muxer; th_subscription_t *sp_s; - int sp_error; + const char *sp_error; + } sp_t; @@ -83,30 +84,12 @@ 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: - errtxt = "Ok"; - break; - case -1: - errtxt = "Timeout, no video detected"; - break; - case TRANSPORT_ERROR_NO_DESCRAMBLER: - errtxt = "No descrambler for stream"; - break; - case TRANSPORT_ERROR_NO_ACCESS: - errtxt = "Access denied"; - break; - default: - errtxt = "Other error"; - break; - } - - syslog(LOG_INFO, "Probed \"%s\" -- %s\n", t->tht_svcname, errtxt); + syslog(LOG_INFO, "Probed \"%s\" -- %s\n", t->tht_svcname, + sp->sp_error ?: "Ok"); - if(sp->sp_error == 0) { + if(sp->sp_error == NULL) { if(t->tht_ch == NULL && t->tht_svcname != NULL) { ch = channel_find(t->tht_svcname, 1, NULL); transport_map_channel(t, ch); @@ -126,21 +109,33 @@ sp_packet_input(void *opaque, th_muxstream_t *tms, th_pkt_t *pkt) if(tms->tms_stream->st_type == HTSTV_MPEG2VIDEO || tms->tms_stream->st_type == HTSTV_H264) { - sp->sp_error = 0; + sp->sp_error = NULL; dtimer_arm(&sp->sp_timer, sp_timeout, sp, 0); } } /** - * Callback when transport hits an error + * Callback when transport changes status */ static void -sp_err_callback(struct th_subscription *s, int errorcode, void *opaque) +sp_status_callback(struct th_subscription *s, int status, void *opaque) { sp_t *sp = opaque; - s->ths_err_callback = NULL; + s->ths_status_callback = NULL; - sp->sp_error = errorcode; + switch(status) { + case TRANSPORT_STATUS_OK: + return; + case TRANSPORT_STATUS_NO_DESCRAMBLER: + sp->sp_error = "No descrambler for stream"; + break; + case TRANSPORT_STATUS_NO_ACCESS: + sp->sp_error = "Access denied"; + break; + default: + sp->sp_error = "Other error"; + break; + } dtimer_arm(&sp->sp_timer, sp_timeout, sp, 0); } @@ -163,7 +158,7 @@ serviceprobe_engage(void) sp = calloc(1, sizeof(sp_t)); sp->sp_s = s = calloc(1, sizeof(th_subscription_t)); - sp->sp_error = -1; + sp->sp_error = "Timeout"; s->ths_title = "probe"; s->ths_weight = INT32_MAX; s->ths_opaque = sp; @@ -177,7 +172,7 @@ serviceprobe_engage(void) sp->sp_muxer = tm = muxer_init(s, sp_packet_input, sp); muxer_play(tm, AV_NOPTS_VALUE); - s->ths_err_callback = sp_err_callback; + s->ths_status_callback = sp_status_callback; dtimer_arm(&sp->sp_timer, sp_timeout, sp, 4); } diff --git a/transports.c b/transports.c index ee098f71..77dd5a63 100644 --- a/transports.c +++ b/transports.c @@ -602,10 +602,16 @@ transport_is_available(th_transport_t *t) * */ void -transport_signal_error(th_transport_t *t, int errorcode) +transport_signal_status(th_transport_t *t, int newstatus) { th_subscription_t *s; + + if(t->tht_last_status != newstatus) + return; + + t->tht_last_status = newstatus; + LIST_FOREACH(s, &t->tht_subscriptions, ths_transport_link) - if(s->ths_err_callback != NULL) - s->ths_err_callback(s, errorcode, s->ths_opaque); + if(s->ths_status_callback != NULL) + s->ths_status_callback(s, newstatus, s->ths_opaque); } diff --git a/transports.h b/transports.h index 216fe18b..b150541b 100644 --- a/transports.h +++ b/transports.h @@ -53,6 +53,6 @@ int transport_is_available(th_transport_t *t); void transport_destroy(th_transport_t *t); -void transport_signal_error(th_transport_t *t, int errorcode); +void transport_signal_status(th_transport_t *t, int newstatus); #endif /* TRANSPORTS_H */ diff --git a/tsdemux.c b/tsdemux.c index fd64043c..e42916e2 100644 --- a/tsdemux.c +++ b/tsdemux.c @@ -225,14 +225,14 @@ ts_recv_packet1(th_transport_t *t, uint8_t *tsb) if(r == 0) return; - if(r == TRANSPORT_ERROR_NO_ACCESS) + if(r == 1) m++; } if(n == 0) { - transport_signal_error(t, TRANSPORT_ERROR_NO_DESCRAMBLER); + transport_signal_status(t, TRANSPORT_STATUS_NO_DESCRAMBLER); } else if(m == n) { - transport_signal_error(t, TRANSPORT_ERROR_NO_ACCESS); + transport_signal_status(t, TRANSPORT_STATUS_NO_ACCESS); } return; } diff --git a/tvhead.h b/tvhead.h index f1f95f40..8bcf8983 100644 --- a/tvhead.h +++ b/tvhead.h @@ -512,6 +512,18 @@ typedef struct th_transport { struct channel *tht_ch; char *tht_chname; + /** + * Last known status (or error) + */ + + int tht_last_status; + +#define TRANSPORT_STATUS_UNKNOWN 0 +#define TRANSPORT_STATUS_OK 1 +#define TRANSPORT_STATUS_NO_DESCRAMBLER 2 +#define TRANSPORT_STATUS_NO_ACCESS 3 +#define TRANSPORT_STATUS_MUX_ERROR 4 + } th_transport_t; @@ -820,14 +832,10 @@ typedef void (subscription_raw_input_t)(struct th_subscription *s, void *opaque); -#define TRANSPORT_ERROR_NO_DESCRAMBLER 1 -#define TRANSPORT_ERROR_NO_ACCESS 2 -#define TRANSPORT_ERROR_MUX_ERROR 3 - -typedef void (subscription_err_callback_t)(struct th_subscription *s, - int errorcode, - void *opaque); +typedef void (subscription_status_callback_t)(struct th_subscription *s, + int status, + void *opaque); typedef struct th_subscription { LIST_ENTRY(th_subscription) ths_global_link; @@ -857,7 +865,7 @@ typedef struct th_subscription { th_muxer_t *ths_muxer; - subscription_err_callback_t *ths_err_callback; + subscription_status_callback_t *ths_status_callback; } th_subscription_t;