From 5705ffbd2ba1cd6644e7bc7b10686963d3d8ef9f Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Mon, 4 May 2020 08:50:20 +0200 Subject: [PATCH] Now retuning if the received transponder's SDT doesn't contain the expected values for NID and TID --- CONTRIBUTORS | 3 +++ HISTORY | 5 ++++- device.h | 4 +++- dvbdevice.c | 11 ++++++++++- sdt.c | 40 ++++++++++++++++++++++++++++++++++++---- sdt.h | 10 +++++++++- 6 files changed, 65 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 3d9afe94..d9195fb8 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -285,6 +285,7 @@ Uwe Scheffler for reporting a black screen while a "Recording started" message is displayed for reporting a problem with the lock on the Channels list in cDisplayChannel still being held when Flush() was called + for reporting a problem with failed tuning in SCR systems Matjaz Thaler for improving AC3 decoding when replaying DVDs @@ -3586,6 +3587,8 @@ Helmut Binder for fixing updating the checksum in the CA table after mapping EMM PIDs for MTD for fixing a compiler warning in ExchangeChars() for suggesting to add __attribute__((packed)) to tIndexPes and tIndexTs + for helping with the implementation of retuning if the received transponder's SDT + doesn't contain the expected values for NID and TID Ulrich Eckhardt for reporting a problem with shutdown after user inactivity in case a plugin is diff --git a/HISTORY b/HISTORY index 4832ca91..cdb644a1 100644 --- a/HISTORY +++ b/HISTORY @@ -9420,8 +9420,11 @@ Video Disk Recorder Revision History - Fixed handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting in "backwards compatibility mode" according to ETSI EN 300 468 (thanks to Onur Sentürk). -2020-04-11: +2020-05-04: - Fixed moving channels between number groups in SVDRP's MOVC command and the Channels menu, in case a channel is moved to a higher number and into a numbered group (reported by Manuel Reimer). +- Now retuning if the received transponder's SDT doesn't contain the expected values + for NID and TID (thanks to Uwe Scheffler for reporting a problem with failed tuning + in SCR systems, and Helmut Binder for helping with the implementation). diff --git a/device.h b/device.h index 39621a3c..8b77d48e 100644 --- a/device.h +++ b/device.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 4.13 2019/05/28 14:47:09 kls Exp $ + * $Id: device.h 4.14 2020/05/04 08:50:20 kls Exp $ */ #ifndef __DEVICE_H @@ -450,6 +450,8 @@ public: ///< Attaches the given filter to this device. void Detach(cFilter *Filter); ///< Detaches the given filter from this device. + const cSdtFilter *SdtFilter(void) const { return sdtFilter; } + cSectionHandler *SectionHandler(void) const { return sectionHandler; } // Common Interface facilities: diff --git a/dvbdevice.c b/dvbdevice.c index 70671b30..562d2697 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 4.21 2019/05/28 14:40:49 kls Exp $ + * $Id: dvbdevice.c 4.22 2020/05/04 08:50:20 kls Exp $ */ #include "dvbdevice.h" @@ -1701,6 +1701,7 @@ void cDvbTuner::Action(void) } } tunerStatus = tsTuned; + device->SectionHandler()->SetStatus(true); // may have been turned off when retuning Timer.Set(tuneTimeout + (scr ? rand() % SCR_RANDOM_TIMEOUT : 0)); if (positioner) continue; @@ -1733,6 +1734,14 @@ void cDvbTuner::Action(void) isyslog("frontend %d/%d regained lock on channel %d (%s), tp %d", adapter, frontend, channel.Number(), channel.Name(), channel.Transponder()); LostLock = false; } + if (device->SdtFilter()->TransponderWrong()) { + isyslog("frontend %d/%d is not receiving transponder %d for channel %d (%s) - retuning", adapter, frontend, channel.Transponder(), channel.Number(), channel.Name()); + device->SectionHandler()->SetStatus(false); + tunerStatus = tsSet; + lastDiseqc = NULL; + lastSource = 0; + continue; + } tunerStatus = tsLocked; locked.Broadcast(); lastTimeoutReport = 0; diff --git a/sdt.c b/sdt.c index 05cd931b..99efc0e8 100644 --- a/sdt.c +++ b/sdt.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: sdt.c 4.5 2015/08/02 11:33:23 kls Exp $ + * $Id: sdt.c 4.6 2020/05/04 08:50:20 kls Exp $ */ #include "sdt.h" @@ -23,8 +23,13 @@ static bool DebugSdt = false; cSdtFilter::cSdtFilter(cPatFilter *PatFilter) { source = cSource::stNone; + lastSource = cSource::stNone; + lastTransponder = 0; + lastNid = 0; + lastTid = 0; patFilter = PatFilter; - Set(0x11, 0x42); // SDT + transponderState = tsUnknown; + Set(0x11, 0x42); // SDT actual TS } void cSdtFilter::SetStatus(bool On) @@ -34,6 +39,7 @@ void cSdtFilter::SetStatus(bool On) sectionSyncer.Reset(); if (!On) source = cSource::stNone; + transponderState = tsUnknown; } void cSdtFilter::Trigger(int Source) @@ -45,11 +51,37 @@ void cSdtFilter::Trigger(int Source) void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) { cMutexLock MutexLock(&mutex); - if (!(source && Transponder())) - return; SI::SDT sdt(Data, false); if (!sdt.CheckCRCAndParse()) return; + if (transponderState == tsUnknown) { + // The transponder can be verified with any section, no sync required: + int Nid = sdt.getOriginalNetworkId(); + int Tid = sdt.getTransportStreamId(); + if (Source() != lastSource || !ISTRANSPONDER(Transponder(), lastTransponder)) { + // We expect a change in NID/TID: + if (Nid && Tid && Nid == lastNid && Tid == lastTid) { + transponderState = tsWrong; + dsyslog("SDT: channel %d NID/TID (%d/%d) not found, got %d/%d", Channel()->Number(), Channel()->Nid(), Channel()->Tid(), Nid, Tid); + return; + } + } + // NID/TID is acceptable: + lastSource = Source(); + lastTransponder = Transponder(); + lastNid = Nid; + lastTid = Tid; + if (Nid == Channel()->Nid() && Tid == Channel()->Tid()) { + // NID/TID correspond with the channel data: + transponderState = tsVerified; + } + else { + // NID/TID differ from the channel data, but we accept it, since this *is* the data for this transponder: + transponderState = tsAccepted; + } + } + if (!(source && Transponder())) + return; if (!sectionSyncer.Sync(sdt.getVersionNumber(), sdt.getSectionNumber(), sdt.getLastSectionNumber())) return; cStateKey StateKey; diff --git a/sdt.h b/sdt.h index 01653f45..128b51ad 100644 --- a/sdt.h +++ b/sdt.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: sdt.h 3.1 2014/03/10 14:40:54 kls Exp $ + * $Id: sdt.h 4.1 2020/05/04 08:50:20 kls Exp $ */ #ifndef __SDT_H @@ -15,16 +15,24 @@ class cSdtFilter : public cFilter { private: + enum eTransponderState { tsUnknown, tsWrong, tsAccepted, tsVerified }; cMutex mutex; cSectionSyncer sectionSyncer; int source; + int lastSource; + int lastTransponder; + int lastNid; + int lastTid; cPatFilter *patFilter; + enum eTransponderState transponderState; protected: virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length); public: cSdtFilter(cPatFilter *PatFilter); virtual void SetStatus(bool On); void Trigger(int Source); + bool TransponderVerified(void) const { return transponderState == tsVerified; } // returns true if the expected NIT/TID have been received in the SDT + bool TransponderWrong(void) const { return transponderState == tsWrong; } // returns true if an expected change of NIT/TID has not happened }; #endif //__SDT_H