From 11dbade9c17a678fe7d8eb287f38395888100574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Tue, 9 Nov 2010 20:08:58 +0000 Subject: [PATCH] Send signalStatus message over HTSP every second. Ticket #300 --- src/dvb/dvb.h | 2 ++ src/dvb/dvb_fe.c | 12 ++++++++++++ src/dvb/dvb_transport.c | 17 +++++++++++++++++ src/htsp.c | 26 +++++++++++++++++++++++--- src/transports.c | 18 ++++++++++++++++++ src/transports.h | 2 ++ src/tvhead.h | 12 ++++++++++++ 7 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 9f155fe5..663fb746 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -307,6 +307,8 @@ void dvb_transport_notify_by_adapter(th_dvb_adapter_t *tda); htsmsg_t *dvb_transport_build_msg(th_transport_t *t); +int dvb_transport_get_signal_status(th_transport_t *t, + signal_status_t *status); /** * DVB Frontend diff --git a/src/dvb/dvb_fe.c b/src/dvb/dvb_fe.c index 4fa1f622..c9e39d7f 100644 --- a/src/dvb/dvb_fe.c +++ b/src/dvb/dvb_fe.c @@ -112,6 +112,18 @@ dvb_fe_monitor(void *aux) } else { status = TDMI_FE_CONSTANT_FEC; } + + /* bit error rate */ + if(ioctl(tda->tda_fe_fd, FE_READ_BER, &tdmi->tdmi_ber) == -1) + tdmi->tdmi_ber = -2; + + /* signal strength */ + if(ioctl(tda->tda_fe_fd, FE_READ_SIGNAL_STRENGTH, &tdmi->tdmi_signal) == -1) + tdmi->tdmi_signal = -2; + + /* signal/noise ratio */ + if(ioctl(tda->tda_fe_fd, FE_READ_SNR, &tdmi->tdmi_snr) == -1) + tdmi->tdmi_snr = -2; } if(status != tdmi->tdmi_fe_status) { diff --git a/src/dvb/dvb_transport.c b/src/dvb/dvb_transport.c index 48650d81..15fbbeb9 100644 --- a/src/dvb/dvb_transport.c +++ b/src/dvb/dvb_transport.c @@ -460,3 +460,20 @@ dvb_transport_notify(th_transport_t *t) htsmsg_add_str(m, "adapterId", tdmi->tdmi_adapter->tda_identifier); notify_by_msg("dvbService", m); } + + +/** + * Get the signal status from a DVB transport + */ +int +dvb_transport_get_signal_status(th_transport_t *t, signal_status_t *status) +{ + th_dvb_mux_instance_t *tdmi = t->tht_dvb_mux_instance; + + status->status_text = dvb_mux_status(tdmi); + status->snr = tdmi->tdmi_snr; + status->signal = tdmi->tdmi_signal; + status->ber = tdmi->tdmi_ber; + status->unc = tdmi->tdmi_uncorrected_blocks; + return 0; +} diff --git a/src/htsp.c b/src/htsp.c index 5f97e6e5..bc09946c 100644 --- a/src/htsp.c +++ b/src/htsp.c @@ -166,7 +166,6 @@ typedef struct htsp_subscription { } htsp_subscription_t; - /** * */ @@ -1430,7 +1429,9 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsp_send(htsp, m, pkt->pkt_payload, &hs->hs_q, pktbuf_len(pkt->pkt_payload)); if(hs->hs_last_report != dispatch_clock) { - /* Send a queue status report every second */ + signal_status_t status; + + /* Send a queue and signal status report every second */ hs->hs_last_report = dispatch_clock; @@ -1461,8 +1462,27 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) /* We use a special queue for queue status message so they're not blocked by anything else */ - htsp_send_message(hs->hs_htsp, m, &hs->hs_htsp->htsp_hmq_qstatus); + + + if(!transport_get_signal_status(hs->hs_s->ths_transport, &status)) { + + m = htsmsg_create_map(); + htsmsg_add_str(m, "method", "signalStatus"); + htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); + + htsmsg_add_str(m, "feStatus", status.status_text); + if(status.snr != -2) + htsmsg_add_u32(m, "feSNR", status.snr); + if(status.signal != -2) + htsmsg_add_u32(m, "feSignal", status.signal); + if(status.ber != -2) + htsmsg_add_u32(m, "feBER", status.ber); + if(status.unc != -2) + htsmsg_add_u32(m, "feUNC", status.unc); + htsp_send_message(hs->hs_htsp, m, &hs->hs_htsp->htsp_hmq_qstatus); + } + } pkt_ref_dec(pkt); } diff --git a/src/transports.c b/src/transports.c index 96c983ce..e6449e82 100644 --- a/src/transports.c +++ b/src/transports.c @@ -1025,3 +1025,21 @@ transport_refresh_channel(th_transport_t *t) if(t->tht_ch != NULL) htsp_channel_update(t->tht_ch); } + + + +/** + * Get the signal status from a transport + */ +int +transport_get_signal_status(th_transport_t *t, signal_status_t *status) +{ + // get signal status from the transport + switch(t->tht_type) { + case TRANSPORT_DVB: + return dvb_transport_get_signal_status(t, status); + default: + return -1; + } +} + diff --git a/src/transports.h b/src/transports.h index 75892b82..71fe54fb 100644 --- a/src/transports.h +++ b/src/transports.h @@ -98,4 +98,6 @@ void transport_refresh_channel(th_transport_t *t); int tss2errcode(int tss); +int transport_get_signal_status(th_transport_t *t, signal_status_t *status); + #endif /* TRANSPORTS_H */ diff --git a/src/tvhead.h b/src/tvhead.h index e3f26838..13ec36fb 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -168,6 +168,18 @@ typedef enum { #define SCT_ISVIDEO(t) ((t) == SCT_MPEG2VIDEO || (t) == SCT_H264) #define SCT_ISAUDIO(t) ((t) == SCT_MPEG2AUDIO || (t) == SCT_AC3 || \ (t) == SCT_AAC) + +/** + * The signal status of a tuner + */ +typedef struct signal_status { + const char *status_text; /* adapter status text */ + int snr; /* signal/noise ratio */ + int signal; /* signal strength */ + int ber; /* bit error rate */ + int unc; /* uncorrected blocks */ +} signal_status_t; + /** * A streaming pad generates data. * It has one or more streaming targets attached to it.