diff options
author | Lars Hanisch <dvb@flensrocker.de> | 2011-02-17 03:41:25 +0100 |
---|---|---|
committer | Lars Hanisch <dvb@flensrocker.de> | 2011-02-17 03:41:25 +0100 |
commit | 43df82e98abfdbc0ed36bace8ed1fd2ec3fc821d (patch) | |
tree | bf4d7c5bc367ff6e723356fa59d9742210bddc3d | |
parent | b59fef0e72038d8f7f9576ceb0cfd2a49983a00b (diff) | |
download | vdr-plugin-dynamite-43df82e98abfdbc0ed36bace8ed1fd2ec3fc821d.tar.gz vdr-plugin-dynamite-43df82e98abfdbc0ed36bace8ed1fd2ec3fc821d.tar.bz2 |
add manual option to set a device into idle mode
dvbdevices should close all their handles and can't be used for epg-scan.
So be careful to not disable all devices or you won't get epg.
A timer or channel-switch should reactivate the device (hopefully).
-rw-r--r-- | HISTORY | 5 | ||||
-rw-r--r-- | README | 9 | ||||
-rw-r--r-- | dynamicdevice.c | 21 | ||||
-rw-r--r-- | dynamicdevice.h | 1 | ||||
-rw-r--r-- | dynamite.c | 38 | ||||
-rw-r--r-- | patches/vdr-1.7.16-dynamite-subdevice.patch | 52 |
6 files changed, 108 insertions, 18 deletions
@@ -93,3 +93,8 @@ VDR Plugin 'dynamite' Revision History - add parsing of udev-property "dynamite_timeout_handler_arg" - add "dynamite.GetTSTimeoutHandler = /path/to/program" to setup.conf - call external program on GetTS-timeout + +2011-02-18: Version 0.0.5i + +- add idle option to cDevice, "idle"-devices must close all their handles. + They are ignored by the epg-scan. @@ -105,6 +105,15 @@ UNLD /dev/path/to/device Remove the lock of the device so it can be detached alternate command: UnlockDevice +"dynamite-SetIdle-v0.1" +SetIdle /dev/path/to/device + Try to set the device to idle so it won't be used by epg-scan + and can close all its handles + +"dynamite-SetNotIdle-v0.1" +SetNotIdle /dev/path/to/device + Revoke the idle state of the device + (no Service-interface) LSTD Lists all devices managed by this plugin. The first column is an id, diff --git a/dynamicdevice.c b/dynamicdevice.c index b808fe9..bde3806 100644 --- a/dynamicdevice.c +++ b/dynamicdevice.c @@ -216,6 +216,27 @@ eDynamicDeviceReturnCode cDynamicDevice::SetLockDevice(const char *DevPath, bool return ddrcSuccess; } +eDynamicDeviceReturnCode cDynamicDevice::SetIdle(const char *DevPath, bool Idle) +{ + if (!DevPath) + return ddrcNotSupported; + + cMutexLock lock(&arrayMutex); + int freeIndex = -1; + int index = -1; + if (isnumber(DevPath)) + index = strtol(DevPath, NULL, 10) - 1; + else + index = IndexOf(DevPath, freeIndex); + + if ((index < 0) || (index >= numDynamicDevices)) + return ddrcNotFound; + + ((cDevice*)dynamicdevice[index])->SetIdle(Idle); + isyslog("dynamite: set device %s to %s", DevPath, (Idle ? "idle" : "not idle")); + return ddrcSuccess; +} + eDynamicDeviceReturnCode cDynamicDevice::SetGetTSTimeout(const char *DevPath, int Seconds) { if (!DevPath || (Seconds < 0)) diff --git a/dynamicdevice.h b/dynamicdevice.h index ed1a352..43df2c8 100644 --- a/dynamicdevice.h +++ b/dynamicdevice.h @@ -35,6 +35,7 @@ public: static eDynamicDeviceReturnCode AttachDevice(const char *DevPath); static eDynamicDeviceReturnCode DetachDevice(const char *DevPath); static eDynamicDeviceReturnCode SetLockDevice(const char *DevPath, bool Lock); + static eDynamicDeviceReturnCode SetIdle(const char *DevPath, bool Idle); static eDynamicDeviceReturnCode SetGetTSTimeout(const char *DevPath, int Seconds); static void SetDefaultGetTSTimeout(int Seconds); static eDynamicDeviceReturnCode SetGetTSTimeoutHandlerArg(const char *DevPath, const char *Arg); @@ -219,6 +219,16 @@ bool cPluginDynamite::Service(const char *Id, void *Data) cDynamicDevice::SetLockDevice((const char*)Data, false); return true; } + if (strcmp(Id, "dynamite-SetIdle-v0.1") == 0) { + if (Data != NULL) + cDynamicDevice::SetIdle((const char*)Data, true); + return true; + } + if (strcmp(Id, "dynamite-SetNotIdle-v0.1") == 0) { + if (Data != NULL) + cDynamicDevice::SetIdle((const char*)Data, false); + return true; + } if (strcmp(Id, "dynamite-SetGetTSTimeout-v0.1") == 0) { if (Data != NULL) { int replyCode; @@ -277,12 +287,16 @@ const char **cPluginDynamite::SVDRPHelpPages(void) " e.g. SCND '/dev/dvb/adapter*/frontend*'\n" " alternate command: ScanDevices", "LCKD /dev/path/to/device\n" - " alternate command: LockDevice", " Lock the device so it can't be detached\n" " alternate command: LockDevice", "UNLD /dev/path/to/device\n" " Remove the lock of the device so it can be detached\n" " alternate command: UnlockDevice", + "SetIdle /dev/path/to/device\n" + " Try to set the device to idle so it won't be used by epg-scan\n" + " and can close all its handles", + "SetNotIdle /dev/path/to/device\n" + " Revoke the idle state of the device", "LSTD\n" " Lists all devices managed by this plugin. The first column is an id,\n" " the second column is the devicepath passed with ATTD\n" @@ -356,6 +370,28 @@ cString cPluginDynamite::SVDRPCommand(const char *Command, const char *Option, i } } + int idle = 0; + if (strcasecmp(Command, "SetIdle") == 0) + idle = 1; + else if (strcasecmp(Command, "SetNotIdle") == 0) + idle = 2; + if (idle > 0) { + switch (cDynamicDevice::SetIdle(Option, (idle == 1))) { + case ddrcSuccess: + return cString::sprintf("device %s is %s", Option, (idle == 1 ? "idle" : "not idle")); + case ddrcNotFound: + { + ReplyCode = 550; + return cString::sprintf("device %s not found", Option); + } + default: + { + ReplyCode = 550; + return cString::sprintf("can't set device %s to %s and I don't know why...", Option, (idle == 1 ? "idle" : "not idle")); + } + } + } + if ((strcasecmp(Command, "SGTT") == 0) || (strcasecmp(Command, "SetGetTSTimeout") == 0)) { cString ret; int len = strlen(Option); diff --git a/patches/vdr-1.7.16-dynamite-subdevice.patch b/patches/vdr-1.7.16-dynamite-subdevice.patch index 4862c3b..456f7ab 100644 --- a/patches/vdr-1.7.16-dynamite-subdevice.patch +++ b/patches/vdr-1.7.16-dynamite-subdevice.patch @@ -242,7 +242,7 @@ index 681049b..356fb76 100644 + DynamicDeviceProbes.Del(this, false); +} diff --git a/device.h b/device.h -index cb3bc2c..9722bfd 100644 +index cb3bc2c..64c4c36 100644 --- a/device.h +++ b/device.h @@ -163,7 +163,6 @@ private: @@ -312,7 +312,7 @@ index cb3bc2c..9722bfd 100644 + bool IsSubDevice(void) const { return (parentDevice != NULL); } + bool HasSubDevice(void) const { return (subDevice != NULL); } + cDevice *SubDevice(void) const { return subDevice; } -+ bool IsIdle(void) const { return isIdle; } ++ bool IsIdle(void) const { if (parentDevice) return parentDevice->IsIdle(); return isIdle; } + bool SetIdle(bool Idle); + virtual bool SetIdleDevice(bool Idle, bool TestOnly) { return false; } + ///< Called by SetIdle @@ -385,7 +385,7 @@ index 5289bbd..ea54bdb 100644 int cDvbCiAdapter::Read(uint8_t *Buffer, int MaxLength) diff --git a/dvbdevice.c b/dvbdevice.c -index f32b350..e33301a 100644 +index f32b350..2c2f459 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -259,6 +259,7 @@ private: @@ -396,10 +396,11 @@ index f32b350..e33301a 100644 int tuneTimeout; int lockTimeout; time_t lastTimeoutReport; -@@ -269,25 +270,29 @@ private: +@@ -269,30 +270,37 @@ private: cMutex mutex; cCondVar locked; cCondVar newSet; ++ bool isIdle; + bool OpenFrontend(void); + bool CloseFrontend(void); bool GetFrontendStatus(fe_status_t &Status, int TimeoutMs = 0); @@ -414,6 +415,7 @@ index f32b350..e33301a 100644 void Set(const cChannel *Channel); bool Locked(int TimeoutMs = 0); + bool SetIdle(bool Idle); ++ bool IsIdle(void) const { return isIdle; } }; -cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType) @@ -428,7 +430,13 @@ index f32b350..e33301a 100644 tuneTimeout = 0; lockTimeout = 0; lastTimeoutReport = 0; -@@ -305,6 +310,8 @@ cDvbTuner::~cDvbTuner() + diseqcCommands = NULL; + tunerStatus = tsIdle; ++ isIdle = false; + if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) + CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power + SetDescription("tuner on frontend %d/%d", adapter, frontend); +@@ -305,6 +313,8 @@ cDvbTuner::~cDvbTuner() newSet.Broadcast(); locked.Broadcast(); Cancel(3); @@ -437,12 +445,15 @@ index f32b350..e33301a 100644 } bool cDvbTuner::IsTunedTo(const cChannel *Channel) const -@@ -339,8 +346,43 @@ bool cDvbTuner::Locked(int TimeoutMs) +@@ -339,8 +349,47 @@ bool cDvbTuner::Locked(int TimeoutMs) return tunerStatus >= tsLocked; } +bool cDvbTuner::SetIdle(bool Idle) +{ ++ if (isIdle == Idle) ++ return true; ++ isIdle = Idle; + if (Idle) + return CloseFrontend(); + return OpenFrontend(); @@ -459,6 +470,7 @@ index f32b350..e33301a 100644 + //XXX modifiy if you use lnb-sharing-patch + if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) + CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power ++ isIdle = false; + return true; +} + @@ -467,10 +479,10 @@ index f32b350..e33301a 100644 + if (fd_frontend < 0) + return true; + cMutexLock MutexLock(&mutex); -+ close(fd_frontend); -+ fd_frontend = -1; + tunerStatus = tsIdle; + newSet.Broadcast(); ++ close(fd_frontend); ++ fd_frontend = -1; + return true; +} + @@ -481,7 +493,7 @@ index f32b350..e33301a 100644 if (TimeoutMs) { cPoller Poller(fd_frontend); if (Poller.Poll(TimeoutMs)) { -@@ -367,6 +409,8 @@ static unsigned int FrequencyToHz(unsigned int f) +@@ -367,6 +416,8 @@ static unsigned int FrequencyToHz(unsigned int f) bool cDvbTuner::SetFrontend(void) { @@ -490,14 +502,14 @@ index f32b350..e33301a 100644 #define MAXFRONTENDCMDS 16 #define SETCMD(c, d) { Frontend[CmdSeq.num].cmd = (c);\ Frontend[CmdSeq.num].u.data = (d);\ -@@ -526,9 +570,11 @@ void cDvbTuner::Action(void) +@@ -526,9 +577,11 @@ void cDvbTuner::Action(void) bool LostLock = false; fe_status_t Status = (fe_status_t)0; while (Running()) { - fe_status_t NewStatus; - if (GetFrontendStatus(NewStatus, 10)) - Status = NewStatus; -+ if (!dvbdevice->IsIdle()) { ++ if (!isIdle) { + fe_status_t NewStatus; + if (GetFrontendStatus(NewStatus, 10)) + Status = NewStatus; @@ -505,7 +517,7 @@ index f32b350..e33301a 100644 cMutexLock MutexLock(&mutex); switch (tunerStatus) { case tsIdle: -@@ -661,7 +707,8 @@ const char *DeliverySystems[] = { +@@ -661,7 +714,8 @@ const char *DeliverySystems[] = { NULL }; @@ -515,7 +527,7 @@ index f32b350..e33301a 100644 { adapter = Adapter; frontend = Frontend; -@@ -678,7 +725,7 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend) +@@ -678,7 +732,7 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend) fd_ca = DvbOpen(DEV_DVB_CA, adapter, frontend, O_RDWR); if (fd_ca >= 0) @@ -524,7 +536,7 @@ index f32b350..e33301a 100644 // The DVR device (will be opened and closed as needed): -@@ -718,7 +765,7 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend) +@@ -718,7 +772,7 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend) else p = (char *)"unknown modulations"; isyslog("frontend %d/%d provides %s with %s (\"%s\")", adapter, frontend, DeliverySystems[frontendType], p, frontendInfo.name); @@ -533,7 +545,7 @@ index f32b350..e33301a 100644 } } else -@@ -823,6 +870,22 @@ bool cDvbDevice::Ready(void) +@@ -823,6 +877,27 @@ bool cDvbDevice::Ready(void) return true; } @@ -553,11 +565,16 @@ index f32b350..e33301a 100644 + return true; +} + ++bool cDvbDevice::CanScanForEPG(void) const ++{ ++ return !IsIdle() && !dvbTuner->IsIdle(); ++} ++ bool cDvbDevice::HasCi(void) { return ciAdapter; diff --git a/dvbdevice.h b/dvbdevice.h -index ff606fd..f941499 100644 +index ff606fd..7ca1a87 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -102,7 +102,7 @@ class cDvbTuner; @@ -569,7 +586,7 @@ index ff606fd..f941499 100644 static cString DvbName(const char *Name, int Adapter, int Frontend); static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError = false); private: -@@ -123,10 +123,12 @@ private: +@@ -123,10 +123,13 @@ private: fe_delivery_system frontendType; int fd_dvr, fd_ca; public: @@ -579,6 +596,7 @@ index ff606fd..f941499 100644 virtual bool Ready(void); + virtual bool SetIdleDevice(bool Idle, bool TestOnly); ++ virtual bool CanScanForEPG(void) const; + // Common Interface facilities: |