|
|
|
@ -1,9 +1,3 @@
|
|
|
|
|
commit 0e0b199ea828148d82b08e0702eb3dc1b49fc5f4
|
|
|
|
|
Author: Stefan Saraev <stefan@saraev.ca>
|
|
|
|
|
Date: Sun Mar 4 15:55:17 2012 +0200
|
|
|
|
|
|
|
|
|
|
vdr-dynamite: adjust to 1.7.25
|
|
|
|
|
|
|
|
|
|
diff --git a/ci.c b/ci.c
|
|
|
|
|
index 0135d07..cf21952 100644
|
|
|
|
|
--- a/ci.c
|
|
|
|
@ -31,12 +25,12 @@ index 74e0270..d38e2dd 100644
|
|
|
|
|
|
|
|
|
|
class cTPDU;
|
|
|
|
|
diff --git a/device.c b/device.c
|
|
|
|
|
index 663f91a..c0810fa 100644
|
|
|
|
|
index 8c527aa..8b0a7e2 100644
|
|
|
|
|
--- a/device.c
|
|
|
|
|
+++ b/device.c
|
|
|
|
|
@@ -70,12 +70,22 @@ cDevice *cDevice::device[MAXDEVICES] = { NULL };
|
|
|
|
|
@@ -69,12 +69,22 @@ int cDevice::currentChannel = 1;
|
|
|
|
|
cDevice *cDevice::device[MAXDEVICES] = { NULL };
|
|
|
|
|
cDevice *cDevice::primaryDevice = NULL;
|
|
|
|
|
cDevice *cDevice::avoidDevice = NULL;
|
|
|
|
|
cList<cDeviceHook> cDevice::deviceHooks;
|
|
|
|
|
-
|
|
|
|
|
-cDevice::cDevice(void)
|
|
|
|
@ -62,7 +56,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
|
|
|
|
|
SetDescription("receiver on device %d", CardIndex() + 1);
|
|
|
|
|
|
|
|
|
|
@@ -106,10 +116,14 @@ cDevice::cDevice(void)
|
|
|
|
|
@@ -105,10 +115,14 @@ cDevice::cDevice(void)
|
|
|
|
|
for (int i = 0; i < MAXRECEIVERS; i++)
|
|
|
|
|
receiver[i] = NULL;
|
|
|
|
|
|
|
|
|
@ -80,7 +74,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cDevice::~cDevice()
|
|
|
|
|
@@ -118,6 +132,29 @@ cDevice::~cDevice()
|
|
|
|
|
@@ -117,6 +131,29 @@ cDevice::~cDevice()
|
|
|
|
|
DetachAllReceivers();
|
|
|
|
|
delete liveSubtitle;
|
|
|
|
|
delete dvbSubtitleConverter;
|
|
|
|
@ -110,7 +104,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool cDevice::WaitForAllDevicesReady(int Timeout)
|
|
|
|
|
@@ -156,6 +193,8 @@ int cDevice::NextCardIndex(int n)
|
|
|
|
|
@@ -155,6 +192,8 @@ int cDevice::NextCardIndex(int n)
|
|
|
|
|
|
|
|
|
|
int cDevice::DeviceNumber(void) const
|
|
|
|
|
{
|
|
|
|
@ -119,7 +113,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
for (int i = 0; i < numDevices; i++) {
|
|
|
|
|
if (device[i] == this)
|
|
|
|
|
return i;
|
|
|
|
|
@@ -326,6 +365,8 @@ bool cDevice::HasCi(void)
|
|
|
|
|
@@ -341,6 +380,8 @@ bool cDevice::HasCi(void)
|
|
|
|
|
|
|
|
|
|
void cDevice::SetCamSlot(cCamSlot *CamSlot)
|
|
|
|
|
{
|
|
|
|
@ -128,7 +122,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
camSlot = CamSlot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -538,6 +579,10 @@ void cDevice::DelLivePids(void)
|
|
|
|
|
@@ -553,6 +594,10 @@ void cDevice::DelLivePids(void)
|
|
|
|
|
|
|
|
|
|
void cDevice::StartSectionHandler(void)
|
|
|
|
|
{
|
|
|
|
@ -139,7 +133,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
if (!sectionHandler) {
|
|
|
|
|
sectionHandler = new cSectionHandler(this);
|
|
|
|
|
AttachFilter(eitFilter = new cEitFilter);
|
|
|
|
|
@@ -549,6 +594,10 @@ void cDevice::StartSectionHandler(void)
|
|
|
|
|
@@ -564,6 +609,10 @@ void cDevice::StartSectionHandler(void)
|
|
|
|
|
|
|
|
|
|
void cDevice::StopSectionHandler(void)
|
|
|
|
|
{
|
|
|
|
@ -150,7 +144,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
if (sectionHandler) {
|
|
|
|
|
delete nitFilter;
|
|
|
|
|
delete sdtFilter;
|
|
|
|
|
@@ -575,12 +624,17 @@ void cDevice::CloseFilter(int Handle)
|
|
|
|
|
@@ -590,12 +639,17 @@ void cDevice::CloseFilter(int Handle)
|
|
|
|
|
|
|
|
|
|
void cDevice::AttachFilter(cFilter *Filter)
|
|
|
|
|
{
|
|
|
|
@ -168,7 +162,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
if (sectionHandler)
|
|
|
|
|
sectionHandler->Detach(Filter);
|
|
|
|
|
}
|
|
|
|
|
@@ -742,6 +796,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
|
|
|
|
@@ -757,6 +811,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
|
|
|
|
sectionHandler->SetStatus(false);
|
|
|
|
|
sectionHandler->SetChannel(NULL);
|
|
|
|
|
}
|
|
|
|
@ -176,7 +170,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
// Tell the camSlot about the channel switch and add all PIDs of this
|
|
|
|
|
// channel to it, for possible later decryption:
|
|
|
|
|
if (camSlot)
|
|
|
|
|
@@ -788,19 +843,27 @@ void cDevice::ForceTransferMode(void)
|
|
|
|
|
@@ -803,19 +858,27 @@ void cDevice::ForceTransferMode(void)
|
|
|
|
|
{
|
|
|
|
|
if (!cTransferControl::ReceiverDevice()) {
|
|
|
|
|
cChannel *Channel = Channels.GetByNumber(CurrentChannel());
|
|
|
|
@ -205,7 +199,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
if (Seconds >= 0)
|
|
|
|
|
occupiedTimeout = time(NULL) + min(Seconds, MAXOCCUPIEDTIMEOUT);
|
|
|
|
|
}
|
|
|
|
|
@@ -1173,7 +1236,10 @@ bool cDevice::Transferring(void) const
|
|
|
|
|
@@ -1188,7 +1251,10 @@ bool cDevice::Transferring(void) const
|
|
|
|
|
|
|
|
|
|
bool cDevice::AttachPlayer(cPlayer *Player)
|
|
|
|
|
{
|
|
|
|
@ -216,7 +210,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
if (player)
|
|
|
|
|
Detach(player);
|
|
|
|
|
DELETENULL(liveSubtitle);
|
|
|
|
|
@@ -1192,6 +1258,8 @@ bool cDevice::AttachPlayer(cPlayer *Player)
|
|
|
|
|
@@ -1207,6 +1273,8 @@ bool cDevice::AttachPlayer(cPlayer *Player)
|
|
|
|
|
|
|
|
|
|
void cDevice::Detach(cPlayer *Player)
|
|
|
|
|
{
|
|
|
|
@ -225,7 +219,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
if (Player && player == Player) {
|
|
|
|
|
cPlayer *p = player;
|
|
|
|
|
player = NULL; // avoids recursive calls to Detach()
|
|
|
|
|
@@ -1211,6 +1279,8 @@ void cDevice::Detach(cPlayer *Player)
|
|
|
|
|
@@ -1226,6 +1294,8 @@ void cDevice::Detach(cPlayer *Player)
|
|
|
|
|
|
|
|
|
|
void cDevice::StopReplay(void)
|
|
|
|
|
{
|
|
|
|
@ -234,7 +228,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
if (player) {
|
|
|
|
|
Detach(player);
|
|
|
|
|
if (IsPrimaryDevice())
|
|
|
|
|
@@ -1493,6 +1563,8 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
|
|
|
|
|
@@ -1508,6 +1578,8 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
|
|
|
|
|
|
|
|
|
|
int cDevice::Priority(void) const
|
|
|
|
|
{
|
|
|
|
@ -243,7 +237,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
int priority = IDLEPRIORITY;
|
|
|
|
|
if (IsPrimaryDevice() && !Replaying() && ActualDevice() == PrimaryDevice())
|
|
|
|
|
priority = TRANSFERPRIORITY; // we use the same value here, no matter whether it's actual Transfer Mode or real live viewing
|
|
|
|
|
@@ -1511,6 +1583,8 @@ bool cDevice::Ready(void)
|
|
|
|
|
@@ -1526,6 +1598,8 @@ bool cDevice::Ready(void)
|
|
|
|
|
|
|
|
|
|
bool cDevice::Receiving(bool Dummy) const
|
|
|
|
|
{
|
|
|
|
@ -252,7 +246,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
cMutexLock MutexLock(&mutexReceiver);
|
|
|
|
|
for (int i = 0; i < MAXRECEIVERS; i++) {
|
|
|
|
|
if (receiver[i])
|
|
|
|
|
@@ -1591,10 +1665,13 @@ bool cDevice::GetTSPacket(uchar *&Data)
|
|
|
|
|
@@ -1606,10 +1680,13 @@ bool cDevice::GetTSPacket(uchar *&Data)
|
|
|
|
|
|
|
|
|
|
bool cDevice::AttachReceiver(cReceiver *Receiver)
|
|
|
|
|
{
|
|
|
|
@ -266,7 +260,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
// activate the following line if you need it - actually the driver should be fixed!
|
|
|
|
|
//#define WAIT_FOR_TUNER_LOCK
|
|
|
|
|
#ifdef WAIT_FOR_TUNER_LOCK
|
|
|
|
|
@@ -1633,6 +1710,8 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
|
|
|
|
|
@@ -1648,6 +1725,8 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
|
|
|
|
|
|
|
|
|
|
void cDevice::Detach(cReceiver *Receiver)
|
|
|
|
|
{
|
|
|
|
@ -275,7 +269,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
if (!Receiver || Receiver->device != this)
|
|
|
|
|
return;
|
|
|
|
|
bool receiversLeft = false;
|
|
|
|
|
@@ -1658,6 +1737,8 @@ void cDevice::Detach(cReceiver *Receiver)
|
|
|
|
|
@@ -1673,6 +1752,8 @@ void cDevice::Detach(cReceiver *Receiver)
|
|
|
|
|
|
|
|
|
|
void cDevice::DetachAll(int Pid)
|
|
|
|
|
{
|
|
|
|
@ -284,7 +278,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
if (Pid) {
|
|
|
|
|
cMutexLock MutexLock(&mutexReceiver);
|
|
|
|
|
for (int i = 0; i < MAXRECEIVERS; i++) {
|
|
|
|
|
@@ -1670,6 +1751,8 @@ void cDevice::DetachAll(int Pid)
|
|
|
|
|
@@ -1685,6 +1766,8 @@ void cDevice::DetachAll(int Pid)
|
|
|
|
|
|
|
|
|
|
void cDevice::DetachAllReceivers(void)
|
|
|
|
|
{
|
|
|
|
@ -293,7 +287,7 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
cMutexLock MutexLock(&mutexReceiver);
|
|
|
|
|
for (int i = 0; i < MAXRECEIVERS; i++)
|
|
|
|
|
Detach(receiver[i]);
|
|
|
|
|
@@ -1741,3 +1824,25 @@ uchar *cTSBuffer::Get(void)
|
|
|
|
|
@@ -1756,3 +1839,25 @@ uchar *cTSBuffer::Get(void)
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
@ -320,10 +314,10 @@ index 663f91a..c0810fa 100644
|
|
|
|
|
+ DynamicDeviceProbes.Del(this, false);
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/device.h b/device.h
|
|
|
|
|
index 23aea97..d4968cc 100644
|
|
|
|
|
index 0d9ac3a..5cb5645 100644
|
|
|
|
|
--- a/device.h
|
|
|
|
|
+++ b/device.h
|
|
|
|
|
@@ -168,7 +168,6 @@ private:
|
|
|
|
|
@@ -169,7 +169,6 @@ private:
|
|
|
|
|
static int nextCardIndex;
|
|
|
|
|
int cardIndex;
|
|
|
|
|
protected:
|
|
|
|
@ -331,7 +325,7 @@ index 23aea97..d4968cc 100644
|
|
|
|
|
virtual ~cDevice();
|
|
|
|
|
virtual bool Ready(void);
|
|
|
|
|
///< Returns true if this device is ready. Devices with conditional
|
|
|
|
|
@@ -195,9 +194,6 @@ protected:
|
|
|
|
|
@@ -196,9 +195,6 @@ protected:
|
|
|
|
|
///< A derived class must call the MakePrimaryDevice() function of its
|
|
|
|
|
///< base class.
|
|
|
|
|
public:
|
|
|
|
@ -341,7 +335,7 @@ index 23aea97..d4968cc 100644
|
|
|
|
|
int DeviceNumber(void) const;
|
|
|
|
|
///< Returns the number of this device (0 ... numDevices).
|
|
|
|
|
virtual bool HasDecoder(void) const;
|
|
|
|
|
@@ -403,9 +399,6 @@ public:
|
|
|
|
|
@@ -404,9 +400,6 @@ public:
|
|
|
|
|
///< Returns true if this device has a Common Interface.
|
|
|
|
|
void SetCamSlot(cCamSlot *CamSlot);
|
|
|
|
|
///< Sets the given CamSlot to be used with this device.
|
|
|
|
@ -351,7 +345,7 @@ index 23aea97..d4968cc 100644
|
|
|
|
|
|
|
|
|
|
// Image Grab facilities
|
|
|
|
|
|
|
|
|
|
@@ -561,9 +554,6 @@ private:
|
|
|
|
|
@@ -562,9 +555,6 @@ private:
|
|
|
|
|
cTsToPes tsToPesSubtitle;
|
|
|
|
|
bool isPlayingVideo;
|
|
|
|
|
protected:
|
|
|
|
@ -361,7 +355,7 @@ index 23aea97..d4968cc 100644
|
|
|
|
|
virtual bool CanReplay(void) const;
|
|
|
|
|
///< Returns true if this device can currently start a replay session.
|
|
|
|
|
virtual bool SetPlayMode(ePlayMode PlayMode);
|
|
|
|
|
@@ -748,6 +738,38 @@ public:
|
|
|
|
|
@@ -749,6 +739,38 @@ public:
|
|
|
|
|
///< Detaches all receivers from this device for this pid.
|
|
|
|
|
virtual void DetachAllReceivers(void);
|
|
|
|
|
///< Detaches all receivers from this device.
|
|
|
|
@ -400,7 +394,7 @@ index 23aea97..d4968cc 100644
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// Derived cDevice classes that can receive channels will have to provide
|
|
|
|
|
@@ -771,4 +793,47 @@ public:
|
|
|
|
|
@@ -772,4 +794,47 @@ public:
|
|
|
|
|
uchar *Get(void);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -590,36 +584,42 @@ index adbe40d..6d117b2 100644
|
|
|
|
|
|
|
|
|
|
#endif //__DVBCI_H
|
|
|
|
|
diff --git a/dvbdevice.c b/dvbdevice.c
|
|
|
|
|
index 1987223..6795dca 100644
|
|
|
|
|
index 4c9268f..e2944e3 100644
|
|
|
|
|
--- a/dvbdevice.c
|
|
|
|
|
+++ b/dvbdevice.c
|
|
|
|
|
@@ -305,12 +305,16 @@ private:
|
|
|
|
|
bool bondedMasterFailed;
|
|
|
|
|
bool SetFrontendType(const cChannel *Channel);
|
|
|
|
|
cString GetBondingParams(const cChannel *Channel = NULL) const;
|
|
|
|
|
- void ClearEventQueue(void) const;
|
|
|
|
|
- bool GetFrontendStatus(fe_status_t &Status) const;
|
|
|
|
|
+ void ClearEventQueue(void);
|
|
|
|
|
+ bool GetFrontendStatus(fe_status_t &Status);
|
|
|
|
|
void ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency);
|
|
|
|
|
@@ -286,7 +286,7 @@ private:
|
|
|
|
|
static cMutex bondMutex;
|
|
|
|
|
enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
|
|
|
|
|
const cDvbDevice *device;
|
|
|
|
|
- int fd_frontend;
|
|
|
|
|
+ mutable int fd_frontend;
|
|
|
|
|
int adapter, frontend;
|
|
|
|
|
uint32_t subsystemId;
|
|
|
|
|
int tuneTimeout;
|
|
|
|
|
@@ -297,7 +297,7 @@ private:
|
|
|
|
|
const cScr *scr;
|
|
|
|
|
bool lnbPowerTurnedOn;
|
|
|
|
|
eTunerStatus tunerStatus;
|
|
|
|
|
- cMutex mutex;
|
|
|
|
|
+ mutable cMutex mutex;
|
|
|
|
|
cCondVar locked;
|
|
|
|
|
cCondVar newSet;
|
|
|
|
|
cDvbTuner *bondedTuner;
|
|
|
|
|
@@ -311,6 +311,10 @@ private:
|
|
|
|
|
void ResetToneAndVoltage(void);
|
|
|
|
|
bool SetFrontend(void);
|
|
|
|
|
virtual void Action(void);
|
|
|
|
|
+
|
|
|
|
|
+ bool isIdle;
|
|
|
|
|
+ bool OpenFrontend(void);
|
|
|
|
|
+ mutable bool isIdle;
|
|
|
|
|
+ bool OpenFrontend(void) const;
|
|
|
|
|
+ bool CloseFrontend(void);
|
|
|
|
|
public:
|
|
|
|
|
cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int Frontend);
|
|
|
|
|
virtual ~cDvbTuner();
|
|
|
|
|
@@ -323,8 +327,11 @@ public:
|
|
|
|
|
bool IsTunedTo(const cChannel *Channel) const;
|
|
|
|
|
void SetChannel(const cChannel *Channel);
|
|
|
|
|
@@ -325,6 +329,9 @@ public:
|
|
|
|
|
bool Locked(int TimeoutMs = 0);
|
|
|
|
|
- int GetSignalStrength(void) const;
|
|
|
|
|
- int GetSignalQuality(void) const;
|
|
|
|
|
+ int GetSignalStrength(void);
|
|
|
|
|
+ int GetSignalQuality(void);
|
|
|
|
|
int GetSignalStrength(void) const;
|
|
|
|
|
int GetSignalQuality(void) const;
|
|
|
|
|
+
|
|
|
|
|
+ bool SetIdle(bool Idle);
|
|
|
|
|
+ bool IsIdle(void) const { return isIdle; }
|
|
|
|
@ -643,45 +643,15 @@ index 1987223..6795dca 100644
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool cDvbTuner::Bond(cDvbTuner *Tuner)
|
|
|
|
|
@@ -518,8 +528,10 @@ bool cDvbTuner::Locked(int TimeoutMs)
|
|
|
|
|
return tunerStatus >= tsLocked;
|
|
|
|
|
}
|
|
|
|
|
@@ -520,6 +530,8 @@ bool cDvbTuner::Locked(int TimeoutMs)
|
|
|
|
|
|
|
|
|
|
-void cDvbTuner::ClearEventQueue(void) const
|
|
|
|
|
+void cDvbTuner::ClearEventQueue(void)
|
|
|
|
|
void cDvbTuner::ClearEventQueue(void) const
|
|
|
|
|
{
|
|
|
|
|
+ if (!OpenFrontend())
|
|
|
|
|
+ return;
|
|
|
|
|
cPoller Poller(fd_frontend);
|
|
|
|
|
if (Poller.Poll(TUNER_POLL_TIMEOUT)) {
|
|
|
|
|
dvb_frontend_event Event;
|
|
|
|
|
@@ -528,7 +540,7 @@ void cDvbTuner::ClearEventQueue(void) const
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-bool cDvbTuner::GetFrontendStatus(fe_status_t &Status) const
|
|
|
|
|
+bool cDvbTuner::GetFrontendStatus(fe_status_t &Status)
|
|
|
|
|
{
|
|
|
|
|
ClearEventQueue();
|
|
|
|
|
while (1) {
|
|
|
|
|
@@ -543,7 +555,7 @@ bool cDvbTuner::GetFrontendStatus(fe_status_t &Status) const
|
|
|
|
|
//#define DEBUG_SIGNALSTRENGTH
|
|
|
|
|
//#define DEBUG_SIGNALQUALITY
|
|
|
|
|
|
|
|
|
|
-int cDvbTuner::GetSignalStrength(void) const
|
|
|
|
|
+int cDvbTuner::GetSignalStrength(void)
|
|
|
|
|
{
|
|
|
|
|
ClearEventQueue();
|
|
|
|
|
uint16_t Signal;
|
|
|
|
|
@@ -570,7 +582,7 @@ int cDvbTuner::GetSignalStrength(void) const
|
|
|
|
|
|
|
|
|
|
#define LOCK_THRESHOLD 5 // indicates that all 5 FE_HAS_* flags are set
|
|
|
|
|
|
|
|
|
|
-int cDvbTuner::GetSignalQuality(void) const
|
|
|
|
|
+int cDvbTuner::GetSignalQuality(void)
|
|
|
|
|
{
|
|
|
|
|
fe_status_t Status;
|
|
|
|
|
if (GetFrontendStatus(Status)) {
|
|
|
|
|
@@ -710,6 +722,8 @@ static int GetRequiredDeliverySystem(const cChannel *Channel, const cDvbTranspon
|
|
|
|
|
|
|
|
|
|
bool cDvbTuner::SetFrontend(void)
|
|
|
|
@ -720,7 +690,7 @@ index 1987223..6795dca 100644
|
|
|
|
|
+ return OpenFrontend();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+bool cDvbTuner::OpenFrontend(void)
|
|
|
|
|
+bool cDvbTuner::OpenFrontend(void) const
|
|
|
|
|
+{
|
|
|
|
|
+ if (fd_frontend >= 0)
|
|
|
|
|
+ return true;
|