MythTV master
ExternalSignalMonitor.cpp
Go to the documentation of this file.
1// -*- Mode: c++ -*-
2
3#include <cerrno>
4#include <cstring>
5
6#include <QtGlobal>
7#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
8#include <QtSystemDetection>
9#endif
10
11#include <fcntl.h>
12#include <unistd.h>
13#ifndef Q_OS_WINDOWS
14#include <sys/select.h>
15#endif
16
19
20#include "ExternalChannel.h"
21#include "ExternalRecorder.h"
24#include "mpeg/atscstreamdata.h"
25#include "mpeg/atsctables.h"
26#include "mpeg/mpegtables.h"
27
28#define LOC QString("ExternSigMon[%1](%2): ").arg(m_inputid).arg(m_loc)
29
45 ExternalChannel *_channel,
46 bool _release_stream,
47 uint64_t _flags)
48 : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags)
49{
50 LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor");
55 {
56 LOG(VB_GENERAL, LOG_ERR, LOC + "Open failed");
59 }
60 else
61 {
63 }
64
66 if (channel && channel->IsBackgroundTuning())
68}
69
74{
75 LOG(VB_CHANNEL, LOG_INFO, LOC + "dtor");
79}
80
85{
86 LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin");
87
89 if (GetStreamData())
90 {
93 }
95
96 LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end");
97}
98
106{
107 if (!m_running || m_exit)
108 return;
109
111 if (channel == nullptr)
112 return;
113
114 if (channel->IsExternalChannelChangeInUse())
115 {
117
118 QMutexLocker locker(&m_statusLock);
119 if (!m_scriptStatus.IsGood())
120 return;
121 }
122
123 if (channel->IsBackgroundTuning())
124 {
125 QMutexLocker locker(&m_statusLock);
126 if (m_scriptStatus.GetValue() < 2)
128
129 if (!m_scriptStatus.IsGood())
130 return;
131 }
132
134 {
136 {
137 m_error = QObject::tr("Error: stream handler died");
138 LOG(VB_CHANNEL, LOG_ERR, LOC + m_error);
139 m_updateDone = true;
140 return;
141 }
142
143 EmitStatus();
144 if (IsAllGood())
146
147 m_updateDone = true;
148 return;
149 }
150
152
153 int strength = GetSignalStrengthPercent();
154 bool is_locked = HasLock();
155
156 // Set SignalMonitorValues
157 {
158 QMutexLocker locker(&m_statusLock);
159 m_signalStrength.SetValue(strength);
160 m_signalLock.SetValue(static_cast<int>(is_locked));
161 }
162
163 EmitStatus();
164 if (IsAllGood())
166
167 // Start table monitoring if we are waiting on any table
168 // and we have a lock.
169 if (is_locked && GetStreamData() &&
173 {
175 {
179 }
180 }
181
182 m_updateDone = true;
183}
184
186{
187 QString result;
188
189 m_streamHandler->ProcessCommand("HasLock?", result);
190 if (result.startsWith("OK:"))
191 {
192 return result.mid(3, 3) == "Yes";
193 }
194 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
195 ("HasLock: invalid response '%1'").arg(result));
196 if (!result.startsWith("WARN"))
197 m_error = QString("HasLock: invalid response '%1'").arg(result);
198 return false;
199}
200
202{
203 QString result;
204
205 m_streamHandler->ProcessCommand("SignalStrengthPercent?", result);
206 if (result.startsWith("OK:"))
207 {
208 bool ok = false;
209 int percent = result.mid(3).toInt(&ok);
210 if (!ok)
211 {
212 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
213 ("GetSignalStrengthPercent: invalid response '%1'")
214 .arg(result));
215 return -1;
216 }
217 return percent;
218 }
219 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
220 ("GetSignalStrengthPercent: invalid response '%1'").arg(result));
221 if (!result.startsWith("WARN"))
222 m_error = QString("GetSignalStrengthPercent: invalid response '%1'")
223 .arg(result);
224 return -1;
225}
226
228{
229 QString result;
230
231 m_streamHandler->ProcessCommand("LockTimeout?", result, 10s);
232 if (result.startsWith("OK:"))
233 {
234 bool ok = false;
235 auto timeout = std::chrono::seconds(result.mid(3).toInt(&ok));
236 if (!ok)
237 {
238 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
239 ("GetLockTimeout: invalid response '%1'")
240 .arg(result));
241 return -1s;
242 }
243 return timeout;
244 }
245 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
246 ("GetLockTimeout: invalid response '%1'").arg(result));
247 if (!result.startsWith("WARN"))
248 m_error = QString("GetLockTimeout: invalid response '%1'").arg(result);
249 return -1s;
250}
#define LOC
Overall structure.
virtual bool IsExternalChannelChangeInUse(void)
virtual int GetInputID(void) const
Definition: channelbase.h:67
int GetMajorID(void)
virtual QString GetDevice(void) const
Returns String representing device, useful for debugging.
Definition: channelbase.h:78
This class is intended to detect the presence of needed tables.
bool IsAllGood(void) const override
void AddFlags(uint64_t _flags) override
MPEGStreamData * GetStreamData()
Returns the MPEG stream data if it exists.
-*- Mode: c++ -*-
bool IsBackgroundTuning(void) const
uint GetTuneStatus(void)
ExternalChannel * GetExternalChannel(void)
void UpdateValues(void) override
Fills in frontend stats and emits status Qt signals.
ExternalStreamHandler * m_streamHandler
std::chrono::seconds GetLockTimeout(void)
void Stop(void) override
Stop signal monitoring and table monitoring threads.
~ExternalSignalMonitor() override
Stops signal monitoring and table monitoring threads.
std::chrono::milliseconds m_lockTimeout
static ExternalStreamHandler * Get(const QString &devname, int inputid, int majorid)
bool ProcessCommand(const QString &cmd, QString &result, std::chrono::milliseconds timeout=4s, uint retry_cnt=3)
static void Return(ExternalStreamHandler *&ref, int inputid)
int GetValue() const
Returns the value.
bool IsGood() const
Returns true if the value is equal to the threshold, or on the right side of the threshold (depends o...
void SetValue(int _value)
static const uint64_t kDTVSigMon_WaitForVCT
QRecursiveMutex m_statusLock
volatile bool m_exit
void SendMessageAllGood(void)
SignalMonitorValue m_signalLock
static const uint64_t kDTVSigMon_WaitForNIT
SignalMonitorValue m_scriptStatus
static const uint64_t kDTVSigMon_WaitForSDT
virtual void Stop()
Stop signal monitoring thread.
volatile bool m_running
ChannelBase * m_channel
static const uint64_t kDTVSigMon_WaitForPMT
virtual void EmitStatus(void)
static const uint64_t kSigMon_WaitForSig
static const uint64_t kDTVSigMon_WaitForPAT
static const uint64_t kDTVSigMon_WaitForMGT
virtual void UpdateValues(void)
This should be overridden to actually do signal monitoring.
SignalMonitorValue m_signalStrength
bool HasAnyFlag(uint64_t _flags) const
bool HasError(void) const
Definition: streamhandler.h:66
bool IsRunning(void) const
virtual void RemoveListener(MPEGStreamData *data)
virtual void AddListener(MPEGStreamData *data, bool allow_section_reader=false, bool needs_buffering=false, const QString &output_file=QString())
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39