diff -Nru vdr-2.3.3/debian/abi-version vdr-2.3.3/debian/abi-version --- vdr-2.3.3/debian/abi-version 2017-03-31 08:53:11.000000000 +0000 +++ vdr-2.3.3/debian/abi-version 2017-04-14 08:49:21.000000000 +0000 @@ -1 +1 @@ -vdr-abi-2.3.3-3yavdr0 +vdr-abi-2.3.3-4yavdr0 diff -Nru vdr-2.3.3/debian/changelog vdr-2.3.3/debian/changelog --- vdr-2.3.3/debian/changelog 2017-03-31 08:53:34.000000000 +0000 +++ vdr-2.3.3/debian/changelog 2017-04-14 08:50:00.000000000 +0000 @@ -1,3 +1,15 @@ +vdr (2.3.3-5yavdr0~xenial) xenial; urgency=medium + + * add vdr-2.3.3-camrelations.patch + + -- Alexander Grothe Fri, 14 Apr 2017 10:49:40 +0200 + +vdr (2.3.3-4yavdr0~xenial) xenial; urgency=medium + + * add fixsvdrpplaylock.diff (can be removed for 2.3.4) + + -- Alexander Grothe Tue, 04 Apr 2017 13:17:44 +0200 + vdr (2.3.3-3yavdr0~xenial) xenial; urgency=medium * set correct abi version diff -Nru vdr-2.3.3/debian/patches/fixsvdrpplaylock.diff vdr-2.3.3/debian/patches/fixsvdrpplaylock.diff --- vdr-2.3.3/debian/patches/fixsvdrpplaylock.diff 1970-01-01 00:00:00.000000000 +0000 +++ vdr-2.3.3/debian/patches/fixsvdrpplaylock.diff 2017-04-04 11:20:00.000000000 +0000 @@ -0,0 +1,66 @@ +Description: Fix a lockup when repeatedly sending a play recording command using svdrp +Author: Klaus Schmiedinger +Origin: http://www.vdr-portal.de/board1-news/board2-vdr-news/p1289947-announce-vdr-developer-version-2-3-3/#post1289947 + +--- a/svdrp.c ++++ b/svdrp.c +@@ -2059,29 +2059,38 @@ + char c = *option; + *option = 0; + if (isnumber(num)) { +- LOCK_RECORDINGS_READ; +- if (const cRecording *Recording = Recordings->Get(strtol(num, NULL, 10) - 1)) { +- if (c) +- option = skipspace(++option); +- cReplayControl::SetRecording(NULL); +- cControl::Shutdown(); +- if (*option) { +- int pos = 0; +- if (strcasecmp(option, "BEGIN") != 0) +- pos = HMSFToIndex(option, Recording->FramesPerSecond()); +- cResumeFile Resume(Recording->FileName(), Recording->IsPesRecording()); +- if (pos <= 0) +- Resume.Delete(); +- else +- Resume.Save(pos); ++ cStateKey StateKey; ++ if (const cRecordings *Recordings = cRecordings::GetRecordingsRead(StateKey)) { ++ if (const cRecording *Recording = Recordings->Get(strtol(num, NULL, 10) - 1)) { ++ cString FileName = Recording->FileName(); ++ cString Title = Recording->Title(); ++ int FramesPerSecond = Recording->FramesPerSecond(); ++ bool IsPesRecording = Recording->IsPesRecording(); ++ StateKey.Remove(); // must give up the lock for the call to cControl::Shutdown() ++ if (c) ++ option = skipspace(++option); ++ cReplayControl::SetRecording(NULL); ++ cControl::Shutdown(); ++ if (*option) { ++ int pos = 0; ++ if (strcasecmp(option, "BEGIN") != 0) ++ pos = HMSFToIndex(option, FramesPerSecond); ++ cResumeFile Resume(FileName, IsPesRecording); ++ if (pos <= 0) ++ Resume.Delete(); ++ else ++ Resume.Save(pos); ++ } ++ cReplayControl::SetRecording(FileName); ++ cControl::Launch(new cReplayControl); ++ cControl::Attach(); ++ Reply(250, "Playing recording \"%s\" [%s]", num, *Title); ++ } ++ else { ++ StateKey.Remove(); ++ Reply(550, "Recording \"%s\" not found", num); + } +- cReplayControl::SetRecording(Recording->FileName()); +- cControl::Launch(new cReplayControl); +- cControl::Attach(); +- Reply(250, "Playing recording \"%s\" [%s]", num, Recording->Title()); + } +- else +- Reply(550, "Recording \"%s\" not found", num); + } + else + Reply(501, "Error in recording number \"%s\"", num); diff -Nru vdr-2.3.3/debian/patches/series vdr-2.3.3/debian/patches/series --- vdr-2.3.3/debian/patches/series 2017-03-30 13:42:48.000000000 +0000 +++ vdr-2.3.3/debian/patches/series 2017-04-14 08:46:17.000000000 +0000 @@ -22,3 +22,5 @@ vdr-2.3.2-aux.patch vdr-2.3-patch-for-permashift.diff vdr-2.3.2_osd2web.diff +fixsvdrpplaylock.diff +vdr-2.3.3-camrelations.diff diff -Nru vdr-2.3.3/debian/patches/vdr-2.3.3-camrelations.diff vdr-2.3.3/debian/patches/vdr-2.3.3-camrelations.diff --- vdr-2.3.3/debian/patches/vdr-2.3.3-camrelations.diff 1970-01-01 00:00:00.000000000 +0000 +++ vdr-2.3.3/debian/patches/vdr-2.3.3-camrelations.diff 2017-04-14 08:48:14.000000000 +0000 @@ -0,0 +1,174 @@ +Description: Fix for CAM access problems +Author: Klaus Schmidinger +--- a/device.c ++++ b/device.c +@@ -99,8 +99,6 @@ + nitFilter = NULL; + + camSlot = NULL; +- startScrambleDetection = 0; +- scramblingTimeout = 0; + + occupiedTimeout = 0; + +@@ -292,7 +290,7 @@ + if (CamSlot->ModuleStatus() == msReady) { + if (CamSlot->ProvidesCa(Channel->Caids())) { + if (!ChannelCamRelations.CamChecked(Channel->GetChannelID(), CamSlot->MasterSlotNumber())) { +- SlotPriority[CamSlot->Index()] = CamSlot->Priority(); ++ SlotPriority[CamSlot->Index()] = CamSlot->MtdActive() ? IDLEPRIORITY : CamSlot->Priority(); // we don't need to take the priority into account here for MTD CAM slots, because they can be used with several devices in parallel + NumUsableSlots++; + } + } +@@ -1733,50 +1731,47 @@ + + void cDevice::Action(void) + { +- time_t LastScrambledPacket = 0; + if (Running() && OpenDvr()) { + while (Running()) { + // Read data from the DVR device: + uchar *b = NULL; + if (GetTSPacket(b)) { + if (b) { +- int Pid = TsPid(b); +- // Check whether the TS packets are scrambled: +- bool DetachReceivers = false; +- bool DescramblingOk = false; +- int CamSlotNumber = 0; +- cCamSlot *cs = NULL; +- if (startScrambleDetection) { +- cs = CamSlot(); +- CamSlotNumber = cs ? cs->MasterSlotNumber() : 0; +- if (CamSlotNumber) { +- if (LastScrambledPacket < startScrambleDetection) +- LastScrambledPacket = startScrambleDetection; +- time_t Now = time(NULL); +- if (TsIsScrambled(b)) { +- LastScrambledPacket = Now; +- if (Now - startScrambleDetection > scramblingTimeout) +- DetachReceivers = true; +- } +- if (Now - LastScrambledPacket > TS_SCRAMBLING_TIME_OK) +- DescramblingOk = true; +- } +- } + // Distribute the packet to all attached receivers: + Lock(); ++ int Pid = TsPid(b); ++ bool IsScrambled = TsIsScrambled(b); + for (int i = 0; i < MAXRECEIVERS; i++) { +- if (receiver[i] && receiver[i]->WantsPid(Pid)) { +- if (DetachReceivers && cs && (!cs->IsActivating() || receiver[i]->Priority() >= LIVEPRIORITY)) { +- dsyslog("CAM %d: won't decrypt channel %s, detaching receiver", CamSlotNumber, *receiver[i]->ChannelID().ToString()); +- ChannelCamRelations.SetChecked(receiver[i]->ChannelID(), CamSlotNumber); +- Detach(receiver[i]); +- } +- else +- receiver[i]->Receive(b, TS_SIZE); +- if (DescramblingOk && receiver[i]->ChannelID().Valid()) { +- dsyslog("CAM %d: decrypts channel %s", CamSlotNumber, *receiver[i]->ChannelID().ToString()); +- ChannelCamRelations.SetDecrypt(receiver[i]->ChannelID(), CamSlotNumber); +- startScrambleDetection = 0; ++ cReceiver *Receiver = receiver[i]; ++ if (Receiver && Receiver->WantsPid(Pid)) { ++ Receiver->Receive(b, TS_SIZE); ++ // Check whether the TS packet is scrambled: ++ if (Receiver->startScrambleDetection) { ++ if (cCamSlot *cs = CamSlot()) { ++ int CamSlotNumber = cs->MasterSlotNumber(); ++ if (Receiver->lastScrambledPacket < Receiver->startScrambleDetection) ++ Receiver->lastScrambledPacket = Receiver->startScrambleDetection; ++ time_t Now = time(NULL); ++ if (IsScrambled) { ++ Receiver->lastScrambledPacket = Now; ++ if (Now - Receiver->startScrambleDetection > Receiver->scramblingTimeout) { ++ if (!cs->IsActivating() || Receiver->Priority() >= LIVEPRIORITY) { ++ if (Receiver->ChannelID().Valid()) { ++ dsyslog("CAM %d: won't decrypt channel %s, detaching receiver", CamSlotNumber, *Receiver->ChannelID().ToString()); ++ ChannelCamRelations.SetChecked(Receiver->ChannelID(), CamSlotNumber); ++ } ++ Detach(Receiver); ++ } ++ } ++ } ++ else if (Now - Receiver->lastScrambledPacket > TS_SCRAMBLING_TIME_OK) { ++ if (Receiver->ChannelID().Valid()) { ++ dsyslog("CAM %d: decrypts channel %s", CamSlotNumber, *Receiver->ChannelID().ToString()); ++ ChannelCamRelations.SetDecrypt(Receiver->ChannelID(), CamSlotNumber); ++ } ++ Receiver->startScrambleDetection = 0; ++ } ++ } + } + } + } +@@ -1840,12 +1835,13 @@ + if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver + camSlot->StartDecrypting(); + if (CamSlots.NumReadyMasterSlots() > 1) { // don't try different CAMs if there is only one +- startScrambleDetection = time(NULL); +- scramblingTimeout = TS_SCRAMBLING_TIMEOUT; ++ Receiver->startScrambleDetection = time(NULL); ++ Receiver->scramblingTimeout = TS_SCRAMBLING_TIMEOUT; + bool KnownToDecrypt = ChannelCamRelations.CamDecrypt(Receiver->ChannelID(), camSlot->MasterSlotNumber()); + if (KnownToDecrypt) +- scramblingTimeout *= 10; // give it time to receive ECM/EMM +- dsyslog("CAM %d: %sknown to decrypt channel %s (scramblingTimeout = %ds)", camSlot->SlotNumber(), KnownToDecrypt ? "" : "not ", *Receiver->ChannelID().ToString(), scramblingTimeout); ++ Receiver->scramblingTimeout *= 10; // give it time to receive ECM/EMM ++ if (Receiver->ChannelID().Valid()) ++ dsyslog("CAM %d: %sknown to decrypt channel %s (scramblingTimeout = %ds)", camSlot->MasterSlotNumber(), KnownToDecrypt ? "" : "not ", *Receiver->ChannelID().ToString(), Receiver->scramblingTimeout); + } + } + Start(); +--- a/device.h ++++ b/device.h +@@ -423,8 +423,6 @@ + // Common Interface facilities: + + private: +- time_t startScrambleDetection; +- int scramblingTimeout; + cCamSlot *camSlot; + public: + virtual bool HasCi(void); +--- a/receiver.c ++++ b/receiver.c +@@ -16,6 +16,9 @@ + device = NULL; + SetPriority(Priority); + numPids = 0; ++ lastScrambledPacket = 0; ++ startScrambleDetection = 0; ++ scramblingTimeout = 0; + SetPids(Channel); + } + +--- a/receiver.h ++++ b/receiver.h +@@ -22,6 +22,9 @@ + int priority; + int pids[MAXRECEIVEPIDS]; + int numPids; ++ time_t lastScrambledPacket; ++ time_t startScrambleDetection; ++ int scramblingTimeout; + bool WantsPid(int Pid); + protected: + cDevice *Device(void) { return device; } +--- a/ci.c ++++ b/ci.c +@@ -2663,6 +2663,13 @@ + void cChannelCamRelations::Save(void) + { + cMutexLock MutexLock(&mutex); ++ struct stat st; ++ if (stat(fileName, &st) == 0) { ++ if ((st.st_mode & S_IWUSR) == 0) { ++ dsyslog("not saving %s (file is read-only)", *fileName); ++ return; ++ } ++ } + dsyslog("saving %s", *fileName); + cSafeFile f(fileName); + if (f.Open()) { diff -Nru vdr-2.3.3/debian/patchinfo vdr-2.3.3/debian/patchinfo --- vdr-2.3.3/debian/patchinfo 2017-03-30 13:45:08.000000000 +0000 +++ vdr-2.3.3/debian/patchinfo 2017-04-14 08:49:33.000000000 +0000 @@ -88,3 +88,13 @@ Patch required for osd2web plugin +fixsvdrpplaylock.diff + Klaus Schmiedinger + + Fix a lockup when repeatedly sending a play recording command using svdrp + +vdr-2.3.3-camrelations.diff + Klaus Schmidinger + + Fix for CAM access problems + diff -Nru vdr-2.3.3/debian/.vdr-patches vdr-2.3.3/debian/.vdr-patches --- vdr-2.3.3/debian/.vdr-patches 2017-03-30 13:45:08.000000000 +0000 +++ vdr-2.3.3/debian/.vdr-patches 2017-04-14 08:49:33.000000000 +0000 @@ -14,3 +14,5 @@ vdr-2.3.2-aux.patch:69754b7558fe43bba799c72a6bd7d15e vdr-2.3-patch-for-permashift.diff:b600b504088f5a07eb9aaf81aac029e4 vdr-2.3.2_osd2web.diff:f15e63a67ff8122221cbc4d14cf27459 +fixsvdrpplaylock.diff:e59d31e53329f9c0128bc173066f5759 +vdr-2.3.3-camrelations.diff:52bab86c5b39dddac959fdae196833b2