00001
00002
00003 #include <cerrno>
00004 #include <cstring>
00005 #include <cmath>
00006
00007 #include <unistd.h>
00008
00009 #include "mythcontext.h"
00010 #include "mythdbcon.h"
00011 #include "dvbsignalmonitor.h"
00012 #include "dvbchannel.h"
00013 #include "dvbstreamdata.h"
00014 #include "atscstreamdata.h"
00015 #include "mpegtables.h"
00016 #include "atsctables.h"
00017 #include "cardutil.h"
00018
00019 #include "dvbtypes.h"
00020 #include "dvbchannel.h"
00021 #include "dvbrecorder.h"
00022 #include "dvbstreamhandler.h"
00023
00024 #define LOC QString("DVBSM(%1): ").arg(channel->GetDevice())
00025 #define LOC_WARN QString("DVBSM(%1), Warning: ").arg(channel->GetDevice())
00026 #define LOC_ERR QString("DVBSM(%1), Error: ").arg(channel->GetDevice())
00027
00043 DVBSignalMonitor::DVBSignalMonitor(int db_cardnum, DVBChannel* _channel,
00044 uint64_t _flags, const char *_name)
00045 : DTVSignalMonitor(db_cardnum, _channel, _flags, _name),
00046
00047
00048
00049 signalToNoise (tr("Signal To Noise"), "snr",
00050 0, true, 0, 65535, 0),
00051 bitErrorRate (tr("Bit Error Rate"), "ber",
00052 65535, false, 0, 65535, 0),
00053 uncorrectedBlocks(tr("Uncorrected Blocks"), "ucb",
00054 65535, false, 0, 65535, 0),
00055 rotorPosition (tr("Rotor Progress"), "pos",
00056 100, true, 0, 100, 0),
00057 streamHandlerStarted(false),
00058 streamHandler(NULL)
00059 {
00060
00061 int wait = 3000;
00062 int threshold = 0;
00063
00064 signalLock.SetTimeout(wait);
00065 signalStrength.SetTimeout(wait);
00066 signalStrength.SetThreshold(threshold);
00067
00068
00069
00070 signalStrength.SetRange(0, 65535);
00071
00072 bool ok;
00073 _channel->HasLock(&ok);
00074 if (!ok)
00075 VERBOSE(VB_IMPORTANT, LOC_ERR + "Can not read DVB status" + ENO);
00076
00077 uint64_t rmflags = 0;
00078
00079 #define DVB_IO(FLAG, METHOD, MSG) \
00080 do { if (HasFlags(FLAG)) { bool ok; _channel->METHOD(&ok); \
00081 if (!ok) { \
00082 VERBOSE(VB_IMPORTANT, LOC_WARN+"Can not "+MSG+ENO); \
00083 rmflags |= FLAG; } \
00084 else { \
00085 VERBOSE(VB_CHANNEL, LOC + "Can " + MSG); } } } while (false)
00086
00087 DVB_IO(kDTVSigMon_WaitForSig, GetSignalStrength,
00088 "measure Signal Strength");
00089 DVB_IO(kDVBSigMon_WaitForSNR, GetSNR,
00090 "measure S/N");
00091 DVB_IO(kDVBSigMon_WaitForBER, GetBitErrorRate,
00092 "measure Bit Error Rate");
00093 DVB_IO(kDVBSigMon_WaitForUB, GetUncorrectedBlockCount,
00094 "count Uncorrected Blocks");
00095
00096 #undef DVB_IO
00097
00098 RemoveFlags(rmflags);
00099
00100 VERBOSE(VB_CHANNEL, LOC + "DVBSignalMonitor::ctor " +
00101 QString("initial flags %1").arg(sm_flags_to_string(flags)));
00102
00103 minimum_update_rate = _channel->GetMinSignalMonitorDelay();
00104 if (minimum_update_rate > 30)
00105 usleep(minimum_update_rate * 1000);
00106
00107 streamHandler = DVBStreamHandler::Get(_channel->GetCardNum());
00108 }
00109
00113 DVBSignalMonitor::~DVBSignalMonitor()
00114 {
00115 Stop();
00116 DVBStreamHandler::Return(streamHandler);
00117 }
00118
00119 void DVBSignalMonitor::deleteLater(void)
00120 {
00121 disconnect();
00122 Stop();
00123 DTVSignalMonitor::deleteLater();
00124 }
00125
00126
00127 void DVBSignalMonitor::SetRotorTarget(float target)
00128 {
00129 QMutexLocker locker(&statusLock);
00130 rotorPosition.SetThreshold((int)roundf(100 * target));
00131 }
00132
00133 void DVBSignalMonitor::GetRotorStatus(bool &was_moving, bool &is_moving)
00134 {
00135 DVBChannel *dvbchannel = dynamic_cast<DVBChannel*>(channel);
00136 const DiSEqCDevRotor *rotor = dvbchannel->GetRotor();
00137
00138 QMutexLocker locker(&statusLock);
00139 was_moving = rotorPosition.GetValue() < 100;
00140 int pos = (int)truncf(rotor->GetProgress() * 100);
00141 rotorPosition.SetValue(pos);
00142 is_moving = rotorPosition.GetValue() < 100;
00143 }
00144
00148 void DVBSignalMonitor::Stop(void)
00149 {
00150 VERBOSE(VB_CHANNEL, LOC + "Stop() -- begin");
00151 SignalMonitor::Stop();
00152 if (GetStreamData())
00153 streamHandler->RemoveListener(GetStreamData());
00154 streamHandlerStarted = false;
00155 streamHandler->SetRetuneAllowed(false, NULL, NULL);
00156 VERBOSE(VB_CHANNEL, LOC + "Stop() -- end");
00157 }
00158
00159 QStringList DVBSignalMonitor::GetStatusList(bool kick)
00160 {
00161 QStringList list = DTVSignalMonitor::GetStatusList(kick);
00162 statusLock.lock();
00163 if (HasFlags(kDVBSigMon_WaitForSNR))
00164 list<<signalToNoise.GetName()<<signalToNoise.GetStatus();
00165 if (HasFlags(kDVBSigMon_WaitForBER))
00166 list<<bitErrorRate.GetName()<<bitErrorRate.GetStatus();
00167 if (HasFlags(kDVBSigMon_WaitForUB))
00168 list<<uncorrectedBlocks.GetName()<<uncorrectedBlocks.GetStatus();
00169 if (HasFlags(kDVBSigMon_WaitForPos))
00170 list<<rotorPosition.GetName()<<rotorPosition.GetStatus();
00171 statusLock.unlock();
00172 return list;
00173 }
00174
00175 void DVBSignalMonitor::HandlePMT(uint program_num, const ProgramMapTable *pmt)
00176 {
00177 DTVSignalMonitor::HandlePMT(program_num, pmt);
00178
00179 if (pmt->ProgramNumber() == (uint)programNumber)
00180 GetDVBChannel()->SetPMT(pmt);
00181 }
00182
00183 void DVBSignalMonitor::HandleSTT(const SystemTimeTable *stt)
00184 {
00185 DTVSignalMonitor::HandleSTT(stt);
00186 GetDVBChannel()->SetTimeOffset(GetStreamData()->TimeOffset());
00187 }
00188
00189 void DVBSignalMonitor::HandleTDT(const TimeDateTable *tdt)
00190 {
00191 DTVSignalMonitor::HandleTDT(tdt);
00192 GetDVBChannel()->SetTimeOffset(GetStreamData()->TimeOffset());
00193 }
00194
00195 DVBChannel *DVBSignalMonitor::GetDVBChannel(void)
00196 {
00197 return dynamic_cast<DVBChannel*>(channel);
00198 }
00199
00206 void DVBSignalMonitor::UpdateValues(void)
00207 {
00208 if (!running || exit)
00209 return;
00210
00211 if (streamHandlerStarted)
00212 {
00213 EmitDVBSignals();
00214 if (IsAllGood())
00215 emit AllGood();
00216
00217
00218 update_done = true;
00219 return;
00220 }
00221
00222 AddFlags(kDTVSigMon_WaitForSig);
00223
00224
00225 if (HasFlags(SignalMonitor::kDVBSigMon_WaitForPos))
00226 {
00227 if (GetDVBChannel()->GetRotor())
00228 {
00229 if (!streamHandler->IsRetuneAllowed())
00230 streamHandler->SetRetuneAllowed(true, this, GetDVBChannel());
00231 streamHandler->RetuneMonitor();
00232 }
00233 else
00234 RemoveFlags(SignalMonitor::kDVBSigMon_WaitForPos);
00235 }
00236
00237 bool wasLocked = false, isLocked = false;
00238 uint sig = 0, snr = 0, ber = 0, ublocks = 0;
00239
00240
00241 bool has_lock = GetDVBChannel()->HasLock();
00242 if (HasFlags(kDTVSigMon_WaitForSig))
00243 sig = (uint) (GetDVBChannel()->GetSignalStrength() * 65535);
00244 if (HasFlags(kDVBSigMon_WaitForSNR))
00245 snr = (uint) (GetDVBChannel()->GetSNR() * 65535);
00246 if (HasFlags(kDVBSigMon_WaitForBER))
00247 ber = (uint) GetDVBChannel()->GetBitErrorRate();
00248 if (HasFlags(kDVBSigMon_WaitForUB))
00249 ublocks = (uint) GetDVBChannel()->GetUncorrectedBlockCount();
00250
00251 has_lock |= streamHandler->IsRunning();
00252
00253
00254 {
00255 QMutexLocker locker(&statusLock);
00256
00257
00258
00259
00260
00261
00262 wasLocked = signalLock.IsGood();
00263 signalLock.SetValue((has_lock) ? 1 : 0);
00264 isLocked = signalLock.IsGood();
00265
00266 if (HasFlags(kDTVSigMon_WaitForSig))
00267 signalStrength.SetValue(sig);
00268 if (HasFlags(kDVBSigMon_WaitForSNR))
00269 signalToNoise.SetValue(snr);
00270 if (HasFlags(kDVBSigMon_WaitForBER))
00271 bitErrorRate.SetValue(ber);
00272 if (HasFlags(kDVBSigMon_WaitForUB))
00273 uncorrectedBlocks.SetValue(ublocks);
00274 }
00275
00276
00277 if (wasLocked != isLocked)
00278 {
00279 VERBOSE(VB_CHANNEL, LOC + "UpdateValues -- Signal "
00280 <<(isLocked ? "Locked" : "Lost"));
00281 }
00282
00283 EmitDVBSignals();
00284 if (IsAllGood())
00285 emit AllGood();
00286
00287
00288
00289 if (isLocked && GetStreamData() &&
00290 (!HasFlags(kDVBSigMon_WaitForPos) || rotorPosition.IsGood()) &&
00291 HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT |
00292 kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT |
00293 kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT))
00294 {
00295 streamHandler->AddListener(GetStreamData(), true, false);
00296 streamHandlerStarted = true;
00297 }
00298
00299 update_done = true;
00300 }
00301
00302 #define EMIT(SIGNAL_FUNC, SIGNAL_VAL) \
00303 do { statusLock.lock(); \
00304 SignalMonitorValue val = SIGNAL_VAL; \
00305 statusLock.unlock(); \
00306 emit SIGNAL_FUNC(val); } while (false)
00307
00311 void DVBSignalMonitor::EmitDVBSignals(void)
00312 {
00313
00314 EMIT(StatusSignalLock, signalLock);
00315 if (HasFlags(kDTVSigMon_WaitForSig))
00316 EMIT(StatusSignalStrength, signalStrength);
00317 if (HasFlags(kDVBSigMon_WaitForSNR))
00318 EMIT(StatusSignalToNoise, signalToNoise);
00319 if (HasFlags(kDVBSigMon_WaitForBER))
00320 EMIT(StatusBitErrorRate, bitErrorRate);
00321 if (HasFlags(kDVBSigMon_WaitForUB))
00322 EMIT(StatusUncorrectedBlocks, uncorrectedBlocks);
00323 if (HasFlags(kDVBSigMon_WaitForPos))
00324 EMIT(StatusRotorPosition, rotorPosition);
00325 }
00326
00327 #undef EMIT