mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented SVDRP peering
This commit is contained in:
parent
2b9e988dd5
commit
c3b0347556
24
HISTORY
24
HISTORY
@ -8652,8 +8652,22 @@ Video Disk Recorder Revision History
|
|||||||
"Setup/Miscellaneous/SVDRP timeout (s)").
|
"Setup/Miscellaneous/SVDRP timeout (s)").
|
||||||
- The SVDRP log messages have been unified and now always contain the IP and port
|
- The SVDRP log messages have been unified and now always contain the IP and port
|
||||||
number of the remote host.
|
number of the remote host.
|
||||||
- SVDRP connections are now handled in a separate thread, which makes them more
|
- SVDRP connections are now handled in a separate "SVDRP server handler" thread,
|
||||||
responsive. Note that there is only one thread that handles all concurrent SVDRP
|
which makes them more responsive. Note that there is only one thread that handles
|
||||||
connections. That way each SVDRP command is guaranteed to be processed separately,
|
all concurrent SVDRP connections. That way each SVDRP command is guaranteed to be
|
||||||
without interfering with any other SVDRP commands that might be issued at the same
|
processed separately, without interfering with any other SVDRP commands that might
|
||||||
time.
|
be issued at the same time. Plugins that implement SVDRP commands may need to take
|
||||||
|
care of proper locking if the commands access global data.
|
||||||
|
- VDR now sends out a broadcast to port 6419/udp, which was assigned to 'svdrp-disc'
|
||||||
|
by the IANA. VDRs listening on that port will automatically initiate an SVDRP
|
||||||
|
connection to the broadcasting VDR, and in turn send out a broadcast to make
|
||||||
|
other VDRs connect to them. That way all VDRs within the local network will
|
||||||
|
have permanent "peer-to-peer" SVDRP connections between each other. The
|
||||||
|
configuration in the svdrphosts.conf file is taken into account when considering
|
||||||
|
whether or not to respond to an SVDRP discover broadcast.
|
||||||
|
- The new SVDRP command PING is used by automatically established peer-to-peer
|
||||||
|
connections to keep them alive.
|
||||||
|
- The new function GetSVDRPServerNames() can be used to get a list of all VDRs
|
||||||
|
this VDR is connected to via SVDRP.
|
||||||
|
- The new class cSVDRPCommand can be used to execute an SVDRP command on one of
|
||||||
|
the servers this VDR is connected to, and retrieve the result.
|
||||||
|
18
PLUGINS.html
18
PLUGINS.html
@ -38,7 +38,7 @@ Copyright © 2015 Klaus Schmidinger<br>
|
|||||||
<a href="http://www.tvdr.de">www.tvdr.de</a>
|
<a href="http://www.tvdr.de">www.tvdr.de</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<modified>Important modifications introduced since version 2.0 are marked like this.</modified>
|
<modified>Important modifications introduced since version 2.2 are marked like this.</modified>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
VDR provides an easy to use plugin interface that allows additional functionality
|
VDR provides an easy to use plugin interface that allows additional functionality
|
||||||
@ -99,12 +99,12 @@ structures and allows it to hook itself into specific areas to perform special a
|
|||||||
<li><a href="#Skins">Skins</a>
|
<li><a href="#Skins">Skins</a>
|
||||||
<li><a href="#Themes">Themes</a>
|
<li><a href="#Themes">Themes</a>
|
||||||
<li><a href="#Devices">Devices</a>
|
<li><a href="#Devices">Devices</a>
|
||||||
<li><modified><a href="#Positioners">Positioners</a></modified>
|
<li><a href="#Positioners">Positioners</a>
|
||||||
<li><a href="#Audio">Audio</a>
|
<li><a href="#Audio">Audio</a>
|
||||||
<li><a href="#Remote Control">Remote Control</a>
|
<li><a href="#Remote Control">Remote Control</a>
|
||||||
<li><a href="#Conditional Access">Conditional Access</a>
|
<li><a href="#Conditional Access">Conditional Access</a>
|
||||||
<li><a href="#Electronic Program Guide">Electronic Program Guide</a>
|
<li><a href="#Electronic Program Guide">Electronic Program Guide</a>
|
||||||
<li><modified><a href="#The video directory">The video directory</a></modified>
|
<li><a href="#The video directory">The video directory</a>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -1161,6 +1161,12 @@ The returned string may consist of several lines, separated by the newline chara
|
|||||||
('<tt>\n</tt>'). Each of these lines will be preceded with the <tt>ReplyCode</tt>
|
('<tt>\n</tt>'). Each of these lines will be preceded with the <tt>ReplyCode</tt>
|
||||||
when presenting them to the caller, and the continuation character ('<tt>-</tt>')
|
when presenting them to the caller, and the continuation character ('<tt>-</tt>')
|
||||||
will be set for all but the last one.
|
will be set for all but the last one.
|
||||||
|
<p>
|
||||||
|
<modified>
|
||||||
|
<b>The SVDRP functions are called from the separate "SVDRP server handler" thread.
|
||||||
|
Therefore the plugin needs to take care of proper locking if it accesses any
|
||||||
|
global data.</b>
|
||||||
|
</modified>
|
||||||
|
|
||||||
<hr><h2><a name="Loading plugins into VDR">Loading plugins into VDR</a></h2>
|
<hr><h2><a name="Loading plugins into VDR">Loading plugins into VDR</a></h2>
|
||||||
|
|
||||||
@ -1877,7 +1883,7 @@ virtual bool SetPlayMode(ePlayMode PlayMode);
|
|||||||
virtual int64_t GetSTC(void);
|
virtual int64_t GetSTC(void);
|
||||||
virtual bool IsPlayingVideo(void) const;
|
virtual bool IsPlayingVideo(void) const;
|
||||||
virtual bool HasIBPTrickSpeed(void);
|
virtual bool HasIBPTrickSpeed(void);
|
||||||
virtual void TrickSpeed(int Speed<modified>, bool Forward</modified>);
|
virtual void TrickSpeed(int Speed, bool Forward);
|
||||||
virtual void Clear(void);
|
virtual void Clear(void);
|
||||||
virtual void Play(void);
|
virtual void Play(void);
|
||||||
virtual void Freeze(void);
|
virtual void Freeze(void);
|
||||||
@ -2026,7 +2032,6 @@ new cMyDeviceHook;
|
|||||||
|
|
||||||
and shall not delete this object. It will be automatically deleted when the program ends.
|
and shall not delete this object. It will be automatically deleted when the program ends.
|
||||||
|
|
||||||
<div class="modified">
|
|
||||||
<hr><h2><a name="Positioners">Positioners</a></h2>
|
<hr><h2><a name="Positioners">Positioners</a></h2>
|
||||||
|
|
||||||
<div class="blurb">Now you see me - now you don't!</div><p>
|
<div class="blurb">Now you see me - now you don't!</div><p>
|
||||||
@ -2065,7 +2070,6 @@ You should create your derived positioner object in the
|
|||||||
Note that the object has to be created on the heap (using <tt>new</tt>),
|
Note that the object has to be created on the heap (using <tt>new</tt>),
|
||||||
and you shall not delete it at any point (it will be deleted automatically
|
and you shall not delete it at any point (it will be deleted automatically
|
||||||
when the program ends).
|
when the program ends).
|
||||||
</div modified>
|
|
||||||
|
|
||||||
<hr><h2><a name="Audio">Audio</a></h2>
|
<hr><h2><a name="Audio">Audio</a></h2>
|
||||||
|
|
||||||
@ -2301,7 +2305,6 @@ to signal VDR that no other EPG handlers shall be queried after this one.
|
|||||||
<p>
|
<p>
|
||||||
See <tt>VDR/epg.h</tt> for details.
|
See <tt>VDR/epg.h</tt> for details.
|
||||||
|
|
||||||
<div class="modified">
|
|
||||||
<hr><h2><a name="The video directory">The video directory</a></h2>
|
<hr><h2><a name="The video directory">The video directory</a></h2>
|
||||||
|
|
||||||
<div class="blurb">Bits and pieces...</div><p>
|
<div class="blurb">Bits and pieces...</div><p>
|
||||||
@ -2335,7 +2338,6 @@ You should create your derived video directory object in the
|
|||||||
Note that the object has to be created on the heap (using <tt>new</tt>),
|
Note that the object has to be created on the heap (using <tt>new</tt>),
|
||||||
and you shall not delete it at any point (it will be deleted automatically
|
and you shall not delete it at any point (it will be deleted automatically
|
||||||
when the program ends).
|
when the program ends).
|
||||||
</div modified>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
46
svdrp.h
46
svdrp.h
@ -4,14 +4,56 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.h 4.1 2015/04/29 13:10:06 kls Exp $
|
* $Id: svdrp.h 4.2 2015/05/22 13:44:43 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __SVDRP_H
|
#ifndef __SVDRP_H
|
||||||
#define __SVDRP_H
|
#define __SVDRP_H
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
class cSVDRPCommand {
|
||||||
|
protected:
|
||||||
|
cString serverName;
|
||||||
|
cString command;
|
||||||
|
cStringList response;
|
||||||
|
public:
|
||||||
|
cSVDRPCommand(const char *ServerName, const char *Command);
|
||||||
|
///< Sets up an SVDRP Command to be executed on the VDR with the given
|
||||||
|
///< ServerName. A list of all available servers can be retrieved by
|
||||||
|
///< calling GetSVDRPServerNames().
|
||||||
|
///< Command is one SVDRP command, followed by optional parameters,
|
||||||
|
///< just as it can be given in a normal SVDRP connection. It doesn't
|
||||||
|
///< need to be terminated with a newline.
|
||||||
|
virtual ~cSVDRPCommand();
|
||||||
|
bool Execute(void);
|
||||||
|
///< Sends the Command given in the constructor to the remote VDR
|
||||||
|
///< and collects all of the response strings.
|
||||||
|
///< Returns true if the data exchange was successful. Whether or
|
||||||
|
///< not the actual SVDRP command was successful depends on the
|
||||||
|
///< resulting strings from the remote VDR, which can be accessed
|
||||||
|
///< by calling Response(). Execute() can be called any number of
|
||||||
|
///< times. The list of response strings will be cleared before
|
||||||
|
///< the command is actually executed.
|
||||||
|
const cStringList *Response(void) const { return &response; }
|
||||||
|
///< Returns the list of strings the remote VDR has sent in response
|
||||||
|
///< to the command. The response strings are exactly as received,
|
||||||
|
///< with the leading three digit reply code and possible continuation
|
||||||
|
///< line indicator ('-') in place.
|
||||||
|
const char *Response(int Index) { return (Index > 0 && Index < response.Size()) ? response[Index] : NULL; }
|
||||||
|
///< This is a convenience function for accessing the response strings.
|
||||||
|
///< Returns the string at the given Index, or NULL if Index is out
|
||||||
|
///< of range.
|
||||||
|
};
|
||||||
|
|
||||||
void SetSVDRPGrabImageDir(const char *GrabImageDir);
|
void SetSVDRPGrabImageDir(const char *GrabImageDir);
|
||||||
void StartSVDRPHandler(int Port);
|
void StartSVDRPHandler(int TcpPort, int UdpPort);
|
||||||
void StopSVDRPHandler(void);
|
void StopSVDRPHandler(void);
|
||||||
|
void SendSVDRPDiscover(const char *Address = NULL);
|
||||||
|
bool GetSVDRPServerNames(cStringList *ServerNames);
|
||||||
|
///< Gets a list of all available VDRs this VDR is connected to via SVDRP,
|
||||||
|
///< and stores it in the given ServerNames list. The list is cleared
|
||||||
|
///< before getting the server names.
|
||||||
|
///< Returns true if the resulting list is not empty.
|
||||||
|
|
||||||
#endif //__SVDRP_H
|
#endif //__SVDRP_H
|
||||||
|
48
tools.c
48
tools.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.c 3.4 2015/02/07 16:07:22 kls Exp $
|
* $Id: tools.c 4.1 2015/05/11 14:15:15 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
@ -274,6 +274,28 @@ cString strescape(const char *s, const char *chars)
|
|||||||
return cString(s, t != NULL);
|
return cString(s, t != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cString strgetval(const char *s, const char *name, char d)
|
||||||
|
{
|
||||||
|
if (s && name) {
|
||||||
|
int l = strlen(name);
|
||||||
|
const char *t = s;
|
||||||
|
while (const char *p = strstr(t, name)) {
|
||||||
|
t = skipspace(p + l);
|
||||||
|
if (p == s || *(p - 1) <= ' ') {
|
||||||
|
if (*t == d) {
|
||||||
|
t = skipspace(t + 1);
|
||||||
|
const char *v = t;
|
||||||
|
while (*t > ' ')
|
||||||
|
t++;
|
||||||
|
return cString(v, t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bool startswith(const char *s, const char *p)
|
bool startswith(const char *s, const char *p)
|
||||||
{
|
{
|
||||||
while (*p) {
|
while (*p) {
|
||||||
@ -1061,6 +1083,17 @@ cString &cString::operator=(const char *String)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cString &cString::Append(const char *String)
|
||||||
|
{
|
||||||
|
int l1 = strlen(s);
|
||||||
|
int l2 = strlen(String);
|
||||||
|
char *p = (char *)realloc(s, l1 + l2 + 1);
|
||||||
|
if (p != s)
|
||||||
|
strcpy(p, s);
|
||||||
|
strcpy(p + l1, String);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
cString &cString::Truncate(int Index)
|
cString &cString::Truncate(int Index)
|
||||||
{
|
{
|
||||||
int l = strlen(s);
|
int l = strlen(s);
|
||||||
@ -1440,6 +1473,19 @@ bool cPoller::Add(int FileHandle, bool Out)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cPoller::Del(int FileHandle, bool Out)
|
||||||
|
{
|
||||||
|
if (FileHandle >= 0) {
|
||||||
|
for (int i = 0; i < numFileHandles; i++) {
|
||||||
|
if (pfd[i].fd == FileHandle && pfd[i].events == (Out ? POLLOUT : POLLIN)) {
|
||||||
|
if (i < numFileHandles - 1)
|
||||||
|
memmove(&pfd[i], &pfd[i + 1], (numFileHandles - i - 1) * sizeof(pollfd));
|
||||||
|
numFileHandles--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool cPoller::Poll(int TimeoutMs)
|
bool cPoller::Poll(int TimeoutMs)
|
||||||
{
|
{
|
||||||
if (numFileHandles) {
|
if (numFileHandles) {
|
||||||
|
14
tools.h
14
tools.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.h 3.7 2015/02/07 16:07:22 kls Exp $
|
* $Id: tools.h 4.1 2015/05/21 14:37:00 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -178,6 +178,7 @@ public:
|
|||||||
const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.)
|
const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.)
|
||||||
cString &operator=(const cString &String);
|
cString &operator=(const cString &String);
|
||||||
cString &operator=(const char *String);
|
cString &operator=(const char *String);
|
||||||
|
cString &Append(const char *String);
|
||||||
cString &Truncate(int Index); ///< Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
|
cString &Truncate(int Index); ///< Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
|
||||||
cString &CompactChars(char c); ///< Compact any sequence of characters 'c' to a single character, and strip all of them from the beginning and end of this string.
|
cString &CompactChars(char c); ///< Compact any sequence of characters 'c' to a single character, and strip all of them from the beginning and end of this string.
|
||||||
static cString sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
static cString sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||||
@ -209,6 +210,14 @@ char *stripspace(char *s);
|
|||||||
char *compactspace(char *s);
|
char *compactspace(char *s);
|
||||||
char *compactchars(char *s, char c); ///< removes all occurrences of 'c' from the beginning an end of 's' and replaces sequences of multiple 'c's with a single 'c'.
|
char *compactchars(char *s, char c); ///< removes all occurrences of 'c' from the beginning an end of 's' and replaces sequences of multiple 'c's with a single 'c'.
|
||||||
cString strescape(const char *s, const char *chars);
|
cString strescape(const char *s, const char *chars);
|
||||||
|
cString strgetval(const char *s, const char *name, char d = '=');
|
||||||
|
///< Returns the value part of a 'name=value' pair in s.
|
||||||
|
///< name must either be at the beginning of s, or has to be preceded by white space.
|
||||||
|
///< There may be any number of white space around the '=' sign. The value is
|
||||||
|
///< everyting up to (and excluding) the next white space, or the end of s.
|
||||||
|
///< If an other delimiter shall be used (like, e.g., ':'), it can be given
|
||||||
|
///< as the third parameter.
|
||||||
|
///< If name occurs more than once in s, only the first occurrence is taken.
|
||||||
bool startswith(const char *s, const char *p);
|
bool startswith(const char *s, const char *p);
|
||||||
bool endswith(const char *s, const char *p);
|
bool endswith(const char *s, const char *p);
|
||||||
bool isempty(const char *s);
|
bool isempty(const char *s);
|
||||||
@ -356,12 +365,13 @@ public:
|
|||||||
|
|
||||||
class cPoller {
|
class cPoller {
|
||||||
private:
|
private:
|
||||||
enum { MaxPollFiles = 16 };
|
enum { MaxPollFiles = 64 };
|
||||||
pollfd pfd[MaxPollFiles];
|
pollfd pfd[MaxPollFiles];
|
||||||
int numFileHandles;
|
int numFileHandles;
|
||||||
public:
|
public:
|
||||||
cPoller(int FileHandle = -1, bool Out = false);
|
cPoller(int FileHandle = -1, bool Out = false);
|
||||||
bool Add(int FileHandle, bool Out);
|
bool Add(int FileHandle, bool Out);
|
||||||
|
void Del(int FileHandle, bool Out);
|
||||||
bool Poll(int TimeoutMs = 0);
|
bool Poll(int TimeoutMs = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
4
vdr.c
4
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.tvdr.de
|
* The project's page is at http://www.tvdr.de
|
||||||
*
|
*
|
||||||
* $Id: vdr.c 4.3 2015/04/29 09:18:54 kls Exp $
|
* $Id: vdr.c 4.4 2015/05/21 13:58:33 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -916,7 +916,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// SVDRP:
|
// SVDRP:
|
||||||
|
|
||||||
StartSVDRPHandler(SVDRPport);
|
StartSVDRPHandler(SVDRPport, DEFAULTSVDRPPORT);
|
||||||
|
|
||||||
// Main program loop:
|
// Main program loop:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user