From 3be19d4b8a7493c3b65233c3d73115895cead402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Thu, 18 Mar 2010 20:48:03 +0000 Subject: [PATCH] Some refactoring of error codes. Also make DVR log reason on SMT_STOP --- src/dvb/dvb_adapter.c | 3 +- src/dvb/dvb_fe.c | 2 +- src/dvb/dvb_transport.c | 6 ++-- src/dvr/dvr_rec.c | 11 ++++--- src/htsp.c | 12 ++++--- src/rtsp.c | 2 +- src/streaming.c | 43 ++++++++++++++++++++++-- src/streaming.h | 2 ++ src/subscriptions.c | 10 +++--- src/subscriptions.h | 2 +- src/transports.c | 23 +++++-------- src/transports.h | 10 ++---- src/tvhead.h | 73 ++++++++++++++++++++++++++++++++++++----- 13 files changed, 147 insertions(+), 52 deletions(-) diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index 858c2b95..6f909bf6 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -504,7 +504,8 @@ dvb_adapter_clean(th_dvb_adapter_t *tda) lock_assert(&global_lock); while((t = LIST_FIRST(&tda->tda_transports)) != NULL) - transport_remove_subscriber(t, NULL); /* Flushes all subscribers */ + /* Flush all subscribers */ + transport_remove_subscriber(t, NULL, SM_CODE_SUBSCRIPTION_OVERRIDDEN); } diff --git a/src/dvb/dvb_fe.c b/src/dvb/dvb_fe.c index 4f7329a0..c68876ed 100644 --- a/src/dvb/dvb_fe.c +++ b/src/dvb/dvb_fe.c @@ -452,7 +452,7 @@ dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason) tvhlog(LOG_ERR, "dvb", "\"%s\" tuning to \"%s\"" " -- Front configuration failed -- %s, frequency: %ld", tda->tda_rootpath, buf, strerror(errno), p->frequency); - return TRANSPORT_NOSTART_TUNING_FAILED; + return SM_CODE_TUNING_FAILED; } tda->tda_mux_current = tdmi; diff --git a/src/dvb/dvb_transport.c b/src/dvb/dvb_transport.c index b7064ab2..75de80cc 100644 --- a/src/dvb/dvb_transport.c +++ b/src/dvb/dvb_transport.c @@ -113,10 +113,10 @@ dvb_transport_start(th_transport_t *t, unsigned int weight, int force_start) lock_assert(&global_lock); if(tda->tda_rootpath == NULL) - return TRANSPORT_NOSTART_NO_HARDWARE; + return SM_CODE_NO_HW_ATTACHED; if(t->tht_dvb_mux_instance && !t->tht_dvb_mux_instance->tdmi_enabled) - return TRANSPORT_NOSTART_MUX_NOT_ENABLED; /* Mux is disabled */ + return SM_CODE_MUX_NOT_ENABLED; /* Mux is disabled */ /* Check if adapter is idle, or already tuned */ @@ -127,7 +127,7 @@ dvb_transport_start(th_transport_t *t, unsigned int weight, int force_start) w = transport_compute_weight(&tda->tda_transports); if(w >= weight && !force_start) /* We are outranked by weight, cant use it */ - return TRANSPORT_NOSTART_NOT_FREE; + return SM_CODE_NOT_FREE; dvb_adapter_clean(tda); } diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index e7300386..541ca2cc 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -463,6 +463,10 @@ dvr_thread(void *aux) break; case SMT_STOP: + tvhlog(sm->sm_code ? LOG_ERR : LOG_INFO, + "pvr", "Recording stopped: \"%s\": %s", + de->de_filename ?: de->de_title, + streaming_code2txt(sm->sm_code)); dvr_thread_epilog(de); break; @@ -475,10 +479,9 @@ dvr_thread(void *aux) } break; - case SMT_NOSOURCE: - dvr_rec_fatal_error(de, - "Unable to start -- %s", - transport_nostart2txt(sm->sm_code)); + case SMT_NOSTART: + dvr_rec_fatal_error(de, "Unable to start -- %s", + streaming_code2txt(sm->sm_code)); break; case SMT_MPEGTS: diff --git a/src/htsp.c b/src/htsp.c index 75ee2af1..51061dba 100644 --- a/src/htsp.c +++ b/src/htsp.c @@ -1467,11 +1467,15 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss) * Send a 'subscriptionStart' stop */ static void -htsp_subscription_stop(htsp_subscription_t *hs) +htsp_subscription_stop(htsp_subscription_t *hs, const char *err) { htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "method", "subscriptionStop"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); + + if(err != NULL) + htsmsg_add_str(m, "status", err); + htsp_send(hs->hs_htsp, m, NULL, &hs->hs_q, 0); } @@ -1525,15 +1529,15 @@ htsp_streaming_input(void *opaque, streaming_message_t *sm) break; case SMT_STOP: - htsp_subscription_stop(hs); + htsp_subscription_stop(hs, streaming_code2txt(sm->sm_code)); break; case SMT_TRANSPORT_STATUS: htsp_subscription_transport_status(hs, sm->sm_code); break; - case SMT_NOSOURCE: - htsp_subscription_status(hs, transport_nostart2txt(sm->sm_code)); + case SMT_NOSTART: + htsp_subscription_status(hs, streaming_code2txt(sm->sm_code)); break; case SMT_MPEGTS: diff --git a/src/rtsp.c b/src/rtsp.c index eae6f580..7160cbf2 100644 --- a/src/rtsp.c +++ b/src/rtsp.c @@ -463,7 +463,7 @@ rtsp_streaming_input(void *opaque, streaming_message_t *sm) } break; - case SMT_NOSOURCE: + case SMT_NOSTART: pthread_mutex_lock(&rtsp->rtsp_start_mutex); rtsp->rtsp_start_error = transport_nostart2txt(sm->sm_code); pthread_cond_signal(&rtsp->rtsp_start_cond); diff --git a/src/streaming.c b/src/streaming.c index 82b1eff3..d679e898 100644 --- a/src/streaming.c +++ b/src/streaming.c @@ -172,7 +172,7 @@ streaming_msg_clone(streaming_message_t *src) case SMT_STOP: case SMT_TRANSPORT_STATUS: - case SMT_NOSOURCE: + case SMT_NOSTART: dst->sm_code = src->sm_code; break; @@ -230,7 +230,7 @@ streaming_msg_free(streaming_message_t *sm) case SMT_TRANSPORT_STATUS: break; - case SMT_NOSOURCE: + case SMT_NOSTART: break; case SMT_MPEGTS: @@ -291,3 +291,42 @@ streaming_queue_clear(struct streaming_message_queue *q) streaming_msg_free(sm); } } + + +/** + * + */ +const char * +streaming_code2txt(int code) +{ + switch(code) { + case SM_CODE_OK: return "OK"; + + case SM_CODE_SOURCE_RECONFIGURED: + return "Soruce reconfigured"; + case SM_CODE_BAD_SOURCE: + return "Source quality is bad"; + case SM_CODE_SOURCE_DELETED: + return "Source deleted"; + case SM_CODE_SUBSCRIPTION_OVERRIDDEN: + return "Subscription overridden"; + + case SM_CODE_NO_HW_ATTACHED: + return "No hardware present"; + case SM_CODE_MUX_NOT_ENABLED: + return "Mux not enabled"; + case SM_CODE_NOT_FREE: + return "Adapter in use by other subscription"; + case SM_CODE_TUNING_FAILED: + return "Tuning failed"; + case SM_CODE_SVC_NOT_ENABLED: + return "No service enabled"; + case SM_CODE_BAD_SIGNAL: + return "Too bad signal quality"; + case SM_CODE_NO_SOURCE: + return "No source available"; + + default: + return "Unknown reason"; + } +} diff --git a/src/streaming.h b/src/streaming.h index d75fdbd4..1c91aace 100644 --- a/src/streaming.h +++ b/src/streaming.h @@ -85,5 +85,7 @@ void streaming_start_unref(streaming_start_t *ss); int streaming_pad_probe_type(streaming_pad_t *sp, streaming_message_type_t smt); + +const char *streaming_code2txt(int code); #endif /* STREAMING_H_ */ diff --git a/src/subscriptions.c b/src/subscriptions.c index 14a5fb7f..5489741b 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -104,7 +104,7 @@ subscription_link_transport(th_subscription_t *s, th_transport_t *t) * Called from transport code */ void -subscription_unlink_transport(th_subscription_t *s) +subscription_unlink_transport(th_subscription_t *s, int reason) { streaming_message_t *sm; th_transport_t *t = s->ths_transport; @@ -117,7 +117,7 @@ subscription_unlink_transport(th_subscription_t *s) if(LIST_FIRST(&t->tht_components) != NULL && s->ths_state == SUBSCRIPTION_GOT_TRANSPORT) { // Send a STOP message to the subscription client - sm = streaming_msg_create_code(SMT_STOP, 0); + sm = streaming_msg_create_code(SMT_STOP, reason); streaming_target_deliver(s->ths_output, sm); } @@ -153,7 +153,7 @@ subscription_reschedule(void *aux) if(s->ths_state != SUBSCRIPTION_BAD_TRANSPORT) continue; /* And it seems to work ok, so we're happy */ skip = s->ths_transport; - transport_remove_subscriber(s->ths_transport, s); + transport_remove_subscriber(s->ths_transport, s, SM_CODE_BAD_SOURCE); } else { skip = NULL; } @@ -164,7 +164,7 @@ subscription_reschedule(void *aux) if(t == NULL) { /* No transport available */ - sm = streaming_msg_create_code(SMT_NOSOURCE, errorcode); + sm = streaming_msg_create_code(SMT_NOSTART, errorcode); streaming_target_deliver(s->ths_output, sm); continue; } @@ -195,7 +195,7 @@ subscription_unsubscribe(th_subscription_t *s) } if(t != NULL) - transport_remove_subscriber(t, s); + transport_remove_subscriber(t, s, SM_CODE_OK); if(s->ths_start_message != NULL) streaming_msg_free(s->ths_start_message); diff --git a/src/subscriptions.h b/src/subscriptions.h index 34b32120..abf6d81a 100644 --- a/src/subscriptions.h +++ b/src/subscriptions.h @@ -77,7 +77,7 @@ th_subscription_t *subscription_create_from_transport(th_transport_t *t, void subscription_stop(th_subscription_t *s); -void subscription_unlink_transport(th_subscription_t *s); +void subscription_unlink_transport(th_subscription_t *s, int reason); void subscription_dummy_join(const char *id, int first); diff --git a/src/transports.c b/src/transports.c index 89351183..3172e928 100644 --- a/src/transports.c +++ b/src/transports.c @@ -61,12 +61,6 @@ const char * transport_nostart2txt(int code) { switch(code) { - case TRANSPORT_NOSTART_NO_HARDWARE: return "No hardware present"; - case TRANSPORT_NOSTART_MUX_NOT_ENABLED: return "Mux not enabled"; - case TRANSPORT_NOSTART_NOT_FREE: return "Adapter in use by other subscription"; - case TRANSPORT_NOSTART_TUNING_FAILED: return "Tuning failed"; - case TRANSPORT_NOSTART_SVC_NOT_ENABLED: return "No service enabled"; - case TRANSPORT_NOSTART_BAD_SIGNAL: return "Too bad signal quality"; } return "Unknown error"; } @@ -239,16 +233,17 @@ transport_stop(th_transport_t *t) * Global lock must be held */ void -transport_remove_subscriber(th_transport_t *t, th_subscription_t *s) +transport_remove_subscriber(th_transport_t *t, th_subscription_t *s, + int reason) { lock_assert(&global_lock); if(s == NULL) { while((s = LIST_FIRST(&t->tht_subscriptions)) != NULL) { - subscription_unlink_transport(s); + subscription_unlink_transport(s, reason); } } else { - subscription_unlink_transport(s); + subscription_unlink_transport(s, reason); } if(LIST_FIRST(&t->tht_subscriptions) == NULL) @@ -389,7 +384,7 @@ transport_find(channel_t *ch, unsigned int weight, const char *loginfo, LIST_FOREACH(t, &ch->ch_transports, tht_ch_link) { if(!t->tht_enabled) { - error = TRANSPORT_NOSTART_SVC_NOT_ENABLED; + error = SM_CODE_SVC_NOT_ENABLED; if(loginfo != NULL) { tvhlog(LOG_NOTICE, "Transport", "%s: Skipping \"%s\" -- not enabled", loginfo, transport_nicename(t)); @@ -398,7 +393,7 @@ transport_find(channel_t *ch, unsigned int weight, const char *loginfo, } if(t->tht_quality_index(t) < 10) { - error = TRANSPORT_NOSTART_BAD_SIGNAL; + error = SM_CODE_BAD_SIGNAL; if(loginfo != NULL) { tvhlog(LOG_NOTICE, "Transport", "%s: Skipping \"%s\" -- Quality below 10%", @@ -427,7 +422,7 @@ transport_find(channel_t *ch, unsigned int weight, const char *loginfo, off = 0; } - error = TRANSPORT_NOSTART_NO_HARDWARE; + error = SM_CODE_NO_SOURCE; /* First, try all transports without stealing */ for(i = off; i < cnt; i++) { @@ -517,7 +512,7 @@ transport_destroy(th_transport_t *t) serviceprobe_delete(t); while((s = LIST_FIRST(&t->tht_subscriptions)) != NULL) { - subscription_unlink_transport(s); + subscription_unlink_transport(s, SM_CODE_SOURCE_DELETED); } if(t->tht_ch != NULL) { @@ -840,7 +835,7 @@ transport_restart(th_transport_t *t, int had_components) lock_assert(&t->tht_stream_mutex); if(had_components) { - sm = streaming_msg_create_code(SMT_STOP, 0); + sm = streaming_msg_create_code(SMT_STOP, SM_CODE_SOURCE_RECONFIGURED); streaming_pad_deliver(&t->tht_streaming_pad, sm); streaming_msg_free(sm); } diff --git a/src/transports.h b/src/transports.h index f55b7a1a..366549eb 100644 --- a/src/transports.h +++ b/src/transports.h @@ -25,13 +25,6 @@ #include "htsmsg.h" #include "subscriptions.h" -#define TRANSPORT_NOSTART_NO_HARDWARE 1 -#define TRANSPORT_NOSTART_MUX_NOT_ENABLED 2 -#define TRANSPORT_NOSTART_NOT_FREE 3 -#define TRANSPORT_NOSTART_TUNING_FAILED 4 -#define TRANSPORT_NOSTART_SVC_NOT_ENABLED 5 -#define TRANSPORT_NOSTART_BAD_SIGNAL 6 - void transport_init(void); unsigned int transport_compute_weight(struct th_transport_list *head); @@ -68,7 +61,8 @@ int transport_is_tv(th_transport_t *t); void transport_destroy(th_transport_t *t); -void transport_remove_subscriber(th_transport_t *t, th_subscription_t *s); +void transport_remove_subscriber(th_transport_t *t, th_subscription_t *s, + int reason); void transport_set_streaming_status_flags(th_transport_t *t, int flag); diff --git a/src/tvhead.h b/src/tvhead.h index c3c8fa38..d300e726 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -187,19 +187,76 @@ TAILQ_HEAD(streaming_message_queue, streaming_message); * Streaming messages types */ typedef enum { - SMT_PACKET, // sm_data is a th_pkt. Unref when destroying msg - SMT_START, // sm_data is a stream_start, - // see transport_build_stream_start() - SMT_STOP , // no extra payload right now - SMT_TRANSPORT_STATUS, // sm_code is TSS_ ...something - SMT_EXIT, // Used to signal exit to threads - SMT_NOSOURCE, - SMT_MPEGTS, // sm_data is raw MPEG TS + /** + * Packet with data. + * + * sm_data points to a th_pkt. th_pkt will be unref'ed when + * the message is destroyed + */ + SMT_PACKET, + + /** + * Stream start + * + * sm_data points to a stream_start struct. + * See transport_build_stream_start() + */ + + SMT_START, + + /** + * Transport status + * + * Notification about status of source, see TSS_ flags + */ + SMT_TRANSPORT_STATUS, + + /** + * Streaming stop. + * + * End of streaming. If sm_code is 0 this was a result to an + * unsubscription. Otherwise the reason was external and the + * subscription scheduler will attempt to start a new streaming + * session. + */ + SMT_STOP, + + /** + * Streaming unable to start. + * + * sm_code indicates reason. Scheduler will try to restart + */ + SMT_NOSTART, + + /** + * Raw MPEG TS data + */ + SMT_MPEGTS, + + /** + * Internal message to exit receiver + */ + SMT_EXIT, } streaming_message_type_t; #define SMT_TO_MASK(x) (1 << ((unsigned int)x)) +#define SM_CODE_OK 0 + +#define SM_CODE_SOURCE_RECONFIGURED 100 +#define SM_CODE_BAD_SOURCE 101 +#define SM_CODE_SOURCE_DELETED 102 +#define SM_CODE_SUBSCRIPTION_OVERRIDDEN 103 + +#define SM_CODE_NO_HW_ATTACHED 200 +#define SM_CODE_MUX_NOT_ENABLED 201 +#define SM_CODE_NOT_FREE 202 +#define SM_CODE_TUNING_FAILED 203 +#define SM_CODE_SVC_NOT_ENABLED 204 +#define SM_CODE_BAD_SIGNAL 205 +#define SM_CODE_NO_SOURCE 206 + /** * Streaming messages are sent from the pad to its receivers */