Now retuning if the received transponder's SDT doesn't contain the expected values for NID and TID

This commit is contained in:
Klaus Schmidinger 2020-05-04 08:50:20 +02:00
parent 6e0f5287ea
commit 5705ffbd2b
6 changed files with 65 additions and 8 deletions

View File

@ -285,6 +285,7 @@ Uwe Scheffler <linux_dvb@uni.de>
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 <matjaz.thaler@guest.arnes.si>
for improving AC3 decoding when replaying DVDs
@ -3586,6 +3587,8 @@ Helmut Binder <cco@aon.at>
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 <uli@uli-eckhardt.de>
for reporting a problem with shutdown after user inactivity in case a plugin is

View File

@ -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).

View File

@ -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:

View File

@ -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;

40
sdt.c
View File

@ -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;

10
sdt.h
View File

@ -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