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)").
|
||||
- The SVDRP log messages have been unified and now always contain the IP and port
|
||||
number of the remote host.
|
||||
- SVDRP connections are now handled in a separate thread, which makes them more
|
||||
responsive. Note that there is only one thread that handles all concurrent SVDRP
|
||||
connections. That way each SVDRP command is guaranteed to be processed separately,
|
||||
without interfering with any other SVDRP commands that might be issued at the same
|
||||
time.
|
||||
- SVDRP connections are now handled in a separate "SVDRP server handler" thread,
|
||||
which makes them more responsive. Note that there is only one thread that handles
|
||||
all concurrent SVDRP connections. That way each SVDRP command is guaranteed to be
|
||||
processed separately, without interfering with any other SVDRP commands that might
|
||||
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>
|
||||
</div>
|
||||
<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>
|
||||
<p>
|
||||
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="#Themes">Themes</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="#Remote Control">Remote Control</a>
|
||||
<li><a href="#Conditional Access">Conditional Access</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>
|
||||
|
||||
@ -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>
|
||||
when presenting them to the caller, and the continuation character ('<tt>-</tt>')
|
||||
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>
|
||||
|
||||
@ -1877,7 +1883,7 @@ virtual bool SetPlayMode(ePlayMode PlayMode);
|
||||
virtual int64_t GetSTC(void);
|
||||
virtual bool IsPlayingVideo(void) const;
|
||||
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 Play(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.
|
||||
|
||||
<div class="modified">
|
||||
<hr><h2><a name="Positioners">Positioners</a></h2>
|
||||
|
||||
<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>),
|
||||
and you shall not delete it at any point (it will be deleted automatically
|
||||
when the program ends).
|
||||
</div modified>
|
||||
|
||||
<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>
|
||||
See <tt>VDR/epg.h</tt> for details.
|
||||
|
||||
<div class="modified">
|
||||
<hr><h2><a name="The video directory">The video directory</a></h2>
|
||||
|
||||
<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>),
|
||||
and you shall not delete it at any point (it will be deleted automatically
|
||||
when the program ends).
|
||||
</div modified>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
46
svdrp.h
46
svdrp.h
@ -4,14 +4,56 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* 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
|
||||
#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 StartSVDRPHandler(int Port);
|
||||
void StartSVDRPHandler(int TcpPort, int UdpPort);
|
||||
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
|
||||
|
48
tools.c
48
tools.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* 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"
|
||||
@ -274,6 +274,28 @@ cString strescape(const char *s, const char *chars)
|
||||
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)
|
||||
{
|
||||
while (*p) {
|
||||
@ -1061,6 +1083,17 @@ cString &cString::operator=(const char *String)
|
||||
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)
|
||||
{
|
||||
int l = strlen(s);
|
||||
@ -1440,6 +1473,19 @@ bool cPoller::Add(int FileHandle, bool Out)
|
||||
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)
|
||||
{
|
||||
if (numFileHandles) {
|
||||
|
14
tools.h
14
tools.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* 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
|
||||
@ -178,6 +178,7 @@ public:
|
||||
const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.)
|
||||
cString &operator=(const cString &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 &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)));
|
||||
@ -209,6 +210,14 @@ char *stripspace(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'.
|
||||
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 endswith(const char *s, const char *p);
|
||||
bool isempty(const char *s);
|
||||
@ -356,12 +365,13 @@ public:
|
||||
|
||||
class cPoller {
|
||||
private:
|
||||
enum { MaxPollFiles = 16 };
|
||||
enum { MaxPollFiles = 64 };
|
||||
pollfd pfd[MaxPollFiles];
|
||||
int numFileHandles;
|
||||
public:
|
||||
cPoller(int FileHandle = -1, bool Out = false);
|
||||
bool Add(int FileHandle, bool Out);
|
||||
void Del(int FileHandle, bool Out);
|
||||
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
|
||||
*
|
||||
* $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>
|
||||
@ -916,7 +916,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
// SVDRP:
|
||||
|
||||
StartSVDRPHandler(SVDRPport);
|
||||
StartSVDRPHandler(SVDRPport, DEFAULTSVDRPPORT);
|
||||
|
||||
// Main program loop:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user