Rework the 'error' notfication for subscribers to a more generic and

and flexible transport status tool.
This commit is contained in:
Andreas Öman 2008-05-04 15:31:39 +00:00
parent 0c02b8a597
commit b55dbe7f0f
6 changed files with 54 additions and 45 deletions

2
cwc.c
View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;