MythTV master
ExternalSignalMonitor.cpp
Go to the documentation of this file.
1// -*- Mode: c++ -*-
2
3#include <cerrno>
4#include <cstring>
5
6#include <fcntl.h>
7#include <unistd.h>
8#if !defined(_WIN32)
9#include <sys/select.h>
10#endif
11
14
15#include "ExternalChannel.h"
16#include "ExternalRecorder.h"
19#include "mpeg/atscstreamdata.h"
20#include "mpeg/atsctables.h"
21#include "mpeg/mpegtables.h"
22
23#define LOC QString("ExternSigMon[%1](%2): ").arg(m_inputid).arg(m_loc)
24
40 ExternalChannel *_channel,
41 bool _release_stream,
42 uint64_t _flags)
43 : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags)
44{
45 LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor");
50 {
51 LOG(VB_GENERAL, LOG_ERR, LOC + "Open failed");
54 }
55 else
56 {
58 }
59
61 if (channel && channel->IsBackgroundTuning())
63}
64
69{
70 LOG(VB_CHANNEL, LOG_INFO, LOC + "dtor");
74}
75
80{
81 LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin");
82
84 if (GetStreamData())
85 {
88 }
90
91 LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end");
92}
93
101{
102 if (!m_running || m_exit)
103 return;
104
106 if (channel == nullptr)
107 return;
108
109 if (channel->IsExternalChannelChangeInUse())
110 {
112
113 QMutexLocker locker(&m_statusLock);
114 if (!m_scriptStatus.IsGood())
115 return;
116 }
117
118 if (channel->IsBackgroundTuning())
119 {
120 QMutexLocker locker(&m_statusLock);
121 if (m_scriptStatus.GetValue() < 2)
123
124 if (!m_scriptStatus.IsGood())
125 return;
126 }
127
129 {
131 {
132 m_error = QObject::tr("Error: stream handler died");
133 LOG(VB_CHANNEL, LOG_ERR, LOC + m_error);
134 m_updateDone = true;
135 return;
136 }
137
138 EmitStatus();
139 if (IsAllGood())
141
142 m_updateDone = true;
143 return;
144 }
145
147
148 int strength = GetSignalStrengthPercent();
149 bool is_locked = HasLock();
150
151 // Set SignalMonitorValues
152 {
153 QMutexLocker locker(&m_statusLock);
154 m_signalStrength.SetValue(strength);
155 m_signalLock.SetValue(static_cast<int>(is_locked));
156 }
157
158 EmitStatus();
159 if (IsAllGood())
161
162 // Start table monitoring if we are waiting on any table
163 // and we have a lock.
164 if (is_locked && GetStreamData() &&
168 {
170 {
174 }
175 }
176
177 m_updateDone = true;
178}
179
181{
182 QString result;
183
184 m_streamHandler->ProcessCommand("HasLock?", result);
185 if (result.startsWith("OK:"))
186 {
187 return result.mid(3, 3) == "Yes";
188 }
189 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
190 ("HasLock: invalid response '%1'").arg(result));
191 if (!result.startsWith("WARN"))
192 m_error = QString("HasLock: invalid response '%1'").arg(result);
193 return false;
194}
195
197{
198 QString result;
199
200 m_streamHandler->ProcessCommand("SignalStrengthPercent?", result);
201 if (result.startsWith("OK:"))
202 {
203 bool ok = false;
204 int percent = result.mid(3).toInt(&ok);
205 if (!ok)
206 {
207 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
208 ("GetSignalStrengthPercent: invalid response '%1'")
209 .arg(result));
210 return -1;
211 }
212 return percent;
213 }
214 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
215 ("GetSignalStrengthPercent: invalid response '%1'").arg(result));
216 if (!result.startsWith("WARN"))
217 m_error = QString("GetSignalStrengthPercent: invalid response '%1'")
218 .arg(result);
219 return -1;
220}
221
223{
224 QString result;
225
226 m_streamHandler->ProcessCommand("LockTimeout?", result, 10s);
227 if (result.startsWith("OK:"))
228 {
229 bool ok = false;
230 auto timeout = std::chrono::seconds(result.mid(3).toInt(&ok));
231 if (!ok)
232 {
233 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
234 ("GetLockTimeout: invalid response '%1'")
235 .arg(result));
236 return -1s;
237 }
238 return timeout;
239 }
240 LOG(VB_CHANNEL, LOG_ERR, LOC + QString
241 ("GetLockTimeout: invalid response '%1'").arg(result));
242 if (!result.startsWith("WARN"))
243 m_error = QString("GetLockTimeout: invalid response '%1'").arg(result);
244 return -1s;
245}
#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