diff --git a/HISTORY b/HISTORY index 25955c6..051e23b 100644 --- a/HISTORY +++ b/HISTORY @@ -1,6 +1,7 @@ VDR Plugin 'streamdev' Revision History --------------------------------------- +- added support for VDR 1.7.19 SignalStrength/SignalQuality - analog video channels use the same transponder and pid for different channels, so streamdev-client must always issue TUNE command - server must close the VTP connection also if filter stream is broken diff --git a/client/device.c b/client/device.c index 7f39bbe..2935db2 100644 --- a/client/device.c +++ b/client/device.c @@ -324,3 +324,18 @@ void cStreamdevDevice::UpdatePriority(void) { m_Device->Unlock(); } } + +int cStreamdevDevice::SignalStrength(void) const { + int strength = -1; + if (ClientSocket.DataSocket(siLive) != NULL) + ClientSocket.GetSignal(&strength, NULL); + return strength; +} + +int cStreamdevDevice::SignalQuality(void) const { + int quality = -1; + if (ClientSocket.DataSocket(siLive) != NULL) + ClientSocket.GetSignal(NULL, &quality); + return quality; +} + diff --git a/client/device.h b/client/device.h index 5eb9e53..186ae89 100644 --- a/client/device.h +++ b/client/device.h @@ -59,6 +59,8 @@ public: virtual int NumProvidedSystems(void) const; #endif virtual bool IsTunedToTransponder(const cChannel *Channel); + virtual int SignalStrength(void) const; + virtual int SignalQuality(void) const; static void UpdatePriority(void); static bool Init(void); diff --git a/client/socket.c b/client/socket.c index 3e6dec8..2d5103b 100644 --- a/client/socket.c +++ b/client/socket.c @@ -21,6 +21,9 @@ cClientSocket::cClientSocket(void) { memset(m_DataSockets, 0, sizeof(cTBSocket*) * si_Count); m_Prio = false; + m_LastSignalUpdate = 0; + m_LastSignalStrength = -1; + m_LastSignalQuality = -1; Reset(); } @@ -255,6 +258,8 @@ bool cClientSocket::SetChannelDevice(const cChannel *Channel) { RemoteIp().c_str(), RemotePort(), Channel->Name()); return false; } + + m_LastSignalUpdate = 0; return true; } @@ -273,6 +278,27 @@ bool cClientSocket::SetPriority(int Priority) { return true; } +bool cClientSocket::GetSignal(int *SignalStrength, int *SignalQuality) { + if (!CheckConnection()) return -1; + + CMD_LOCK; + + if (m_LastSignalUpdate != time(NULL)) { + std::string buffer; + if (!Command("SGNL") || !Expect(220, &buffer) + || sscanf(buffer.c_str(), "%*d %*d %d:%d", &m_LastSignalStrength, &m_LastSignalQuality) != 2) { + m_LastSignalStrength = -1; + m_LastSignalQuality = -1; + } + m_LastSignalUpdate = time(NULL); + } + if (SignalStrength) + *SignalStrength = m_LastSignalStrength; + if (SignalQuality) + *SignalQuality = m_LastSignalQuality; + return 0; +} + bool cClientSocket::SetPid(int Pid, bool On) { if (!CheckConnection()) return false; diff --git a/client/socket.h b/client/socket.h index 1197678..42d7574 100644 --- a/client/socket.h +++ b/client/socket.h @@ -22,6 +22,9 @@ private: char m_Buffer[BUFSIZ + 1]; // various uses bool m_Prio; // server supports command PRIO + time_t m_LastSignalUpdate; + int m_LastSignalStrength; + int m_LastSignalQuality; protected: /* Send Command, and return true if the command results in Expected. Returns false on failure, setting errno appropriately if it has been @@ -50,6 +53,7 @@ public: bool SetPriority(int Priority); bool SetPid(int Pid, bool On); bool SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On); + bool GetSignal(int *SignalStrength, int *SignalQuality); bool CloseDvr(void); bool SuspendServer(void); bool Quit(void); diff --git a/server/connectionVTP.c b/server/connectionVTP.c index 2719fb4..64b5f37 100644 --- a/server/connectionVTP.c +++ b/server/connectionVTP.c @@ -840,6 +840,7 @@ bool cConnectionVTP::Command(char *Cmd) else if (strcasecmp(Cmd, "TUNE") == 0) return CmdTUNE(param); else if (strcasecmp(Cmd, "PLAY") == 0) return CmdPLAY(param); else if (strcasecmp(Cmd, "PRIO") == 0) return CmdPRIO(param); + else if (strcasecmp(Cmd, "SGNL") == 0) return CmdSGNL(param); else if (strcasecmp(Cmd, "ADDP") == 0) return CmdADDP(param); else if (strcasecmp(Cmd, "DELP") == 0) return CmdDELP(param); else if (strcasecmp(Cmd, "ADDF") == 0) return CmdADDF(param); @@ -1155,6 +1156,18 @@ bool cConnectionVTP::CmdPRIO(char *Opts) return Respond(550, "Priority not applicable"); } +bool cConnectionVTP::CmdSGNL(char *Opts) +{ + if (m_LiveStreamer) { + int devnum = -1; + int signal = -1; + int quality = -1; + m_LiveStreamer->GetSignal(&devnum, &signal, &quality); + return Respond(220, "%d %d:%d", devnum, signal, quality); + } + return Respond(550, "Signal not applicable"); +} + bool cConnectionVTP::CmdADDP(char *Opts) { int pid; diff --git a/server/connectionVTP.h b/server/connectionVTP.h index ee842fe..2d683f3 100644 --- a/server/connectionVTP.h +++ b/server/connectionVTP.h @@ -65,6 +65,7 @@ public: bool CmdTUNE(char *Opts); bool CmdPLAY(char *Opts); bool CmdPRIO(char *Opts); + bool CmdSGNL(char *Opts); bool CmdADDP(char *Opts); bool CmdDELP(char *Opts); bool CmdADDF(char *Opts); diff --git a/server/livestreamer.c b/server/livestreamer.c index f17025d..144f353 100644 --- a/server/livestreamer.c +++ b/server/livestreamer.c @@ -440,6 +440,17 @@ void cStreamdevLiveStreamer::SetPriority(int Priority) StartReceiver(); } +void cStreamdevLiveStreamer::GetSignal(int *DevNum, int *Strength, int *Quality) const +{ + if (m_Device) { + *DevNum = m_Device->DeviceNumber() + 1; +#if APIVERSNUM >= 10719 + *Strength = m_Device->SignalStrength(); + *Quality = m_Device->SignalQuality(); +#endif + } +} + void cStreamdevLiveStreamer::StartReceiver(void) { if (m_NumPids > 0) { diff --git a/server/livestreamer.h b/server/livestreamer.h index 71feb4c..6203966 100644 --- a/server/livestreamer.h +++ b/server/livestreamer.h @@ -39,6 +39,7 @@ public: bool SetPids(int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL); bool SetChannel(const cChannel *Channel, eStreamType StreamType, const int* Apid = NULL, const int* Dpid = NULL); void SetPriority(int Priority); + void GetSignal(int *DevNum, int *Strength, int *Quality) const; virtual int Put(const uchar *Data, int Count); virtual uchar *Get(int &Count);