Implemented setup options for SVDRP peering

This commit is contained in:
Klaus Schmidinger 2015-09-08 11:08:06 +02:00
parent 3284e941c6
commit 4e3325b7f7
13 changed files with 180 additions and 46 deletions

View File

@ -8596,7 +8596,7 @@ Video Disk Recorder Revision History
- Bumped all version numbers to 2.2.0.
- Official release.
2015-09-06: Version 2.3.1
2015-09-08: Version 2.3.1
- The new function cOsd::MaxPixmapSize() can be called to determine the maximum size
a cPixmap may have on the current OSD. The 'osddemo' example has been modified
@ -8791,3 +8791,7 @@ Video Disk Recorder Revision History
gaps in the sequence, in case timers have been deleted.
- The Timers menu now displays the name of the remote VDR in front of the timer's
file name, if this is a remote timer.
- The new options "Setup/Miscellaneous/SVDRP peering", ".../SVDRP host name" and
".../SVDRP default host" can be used to configure automatic peering between VDRs
in the same network. Peering is disabled by default and can be enabled by setting
"SVDRP peering" to "yes".

9
MANUAL
View File

@ -1071,6 +1071,15 @@ Version 2.2
connection after which the connection is automatically
closed. Default is 300, a value of 0 means no timeout.
SVDRP peering = no Activates automatic connections between VDRs in the same
network.
SVDRP host name The name of this VDR, which is used when connecting VDRs
via SVDRP. By default, the machine's host name is used.
SVDRP default host The name of the VDR to be used by default when creating a
new timer.
Zap timeout = 3 The time (in seconds) until a channel counts as "previous"
for switching with '0'

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.c 4.1 2015/04/18 13:09:31 kls Exp $
* $Id: config.c 4.2 2015/09/06 13:17:19 kls Exp $
*/
#include "config.h"
@ -412,6 +412,9 @@ cSetup::cSetup(void)
EPGBugfixLevel = 3;
EPGLinger = 0;
SVDRPTimeout = 300;
SVDRPPeering = 0;
strn0cpy(SVDRPHostName, GetHostName(), sizeof(SVDRPHostName));
strcpy(SVDRPDefaultHost, "");
ZapTimeout = 3;
ChannelEntryTimeout = 1000;
RcRepeatDelay = 300;
@ -635,6 +638,9 @@ bool cSetup::Parse(const char *Name, const char *Value)
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
else if (!strcasecmp(Name, "EPGLinger")) EPGLinger = atoi(Value);
else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value);
else if (!strcasecmp(Name, "SVDRPPeering")) SVDRPPeering = atoi(Value);
else if (!strcasecmp(Name, "SVDRPHostName")) strn0cpy(SVDRPHostName, Value, sizeof(SVDRPHostName));
else if (!strcasecmp(Name, "SVDRPdefaultHost")) strn0cpy(SVDRPDefaultHost, Value, sizeof(SVDRPDefaultHost));
else if (!strcasecmp(Name, "ZapTimeout")) ZapTimeout = atoi(Value);
else if (!strcasecmp(Name, "ChannelEntryTimeout")) ChannelEntryTimeout= atoi(Value);
else if (!strcasecmp(Name, "RcRepeatDelay")) RcRepeatDelay = atoi(Value);
@ -762,6 +768,8 @@ bool cSetup::Save(void)
Store("EPGBugfixLevel", EPGBugfixLevel);
Store("EPGLinger", EPGLinger);
Store("SVDRPTimeout", SVDRPTimeout);
Store("SVDRPPeering", SVDRPPeering);
Store("SVDRPDefaultHost", SVDRPDefaultHost);
Store("ZapTimeout", ZapTimeout);
Store("ChannelEntryTimeout",ChannelEntryTimeout);
Store("RcRepeatDelay", RcRepeatDelay);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.h 4.3 2015/08/09 09:17:46 kls Exp $
* $Id: config.h 4.4 2015/09/06 09:50:13 kls Exp $
*/
#ifndef __CONFIG_H
@ -288,6 +288,9 @@ public:
int EPGBugfixLevel;
int EPGLinger;
int SVDRPTimeout;
int SVDRPPeering;
char SVDRPHostName[HOST_NAME_MAX];
char SVDRPDefaultHost[HOST_NAME_MAX];
int ZapTimeout;
int ChannelEntryTimeout;
int RcRepeatDelay;

49
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 4.4 2015/09/06 09:28:24 kls Exp $
* $Id: menu.c 4.5 2015/09/08 11:02:52 kls Exp $
*/
#include "menu.h"
@ -27,6 +27,7 @@
#include "sourceparams.h"
#include "sources.h"
#include "status.h"
#include "svdrp.h"
#include "themes.h"
#include "timers.h"
#include "transfer.h"
@ -3897,17 +3898,36 @@ void cMenuSetupReplay::Store(void)
// --- cMenuSetupMisc --------------------------------------------------------
class cMenuSetupMisc : public cMenuSetupBase {
private:
cStringList svdrpServerNames;
void Set(void);
public:
cMenuSetupMisc(void);
virtual eOSState ProcessKey(eKeys Key);
};
cMenuSetupMisc::cMenuSetupMisc(void)
{
SetMenuCategory(mcSetupMisc);
SetSection(tr("Miscellaneous"));
Set();
}
void cMenuSetupMisc::Set(void)
{
int current = Current();
Clear();
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. event timeout (min)"), &data.MinEventTimeout));
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. user inactivity (min)"), &data.MinUserInactivity));
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"), &data.SVDRPTimeout));
Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$SVDRP peering"), &data.SVDRPPeering));
if (data.SVDRPPeering) {
Add(new cMenuEditStrItem( tr("Setup.Miscellaneous$SVDRP host name"), data.SVDRPHostName, sizeof(data.SVDRPHostName)));
if (GetSVDRPServerNames(&svdrpServerNames)) {
svdrpServerNames.Sort(true);
Add(new cMenuEditStrlItem(tr("Setup.Miscellaneous$SVDRP default host"), data.SVDRPDefaultHost, sizeof(data.SVDRPDefaultHost), &svdrpServerNames));
}
}
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Zap timeout (s)"), &data.ZapTimeout));
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Channel entry timeout (ms)"), &data.ChannelEntryTimeout, 0));
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Remote control repeat delay (ms)"), &data.RcRepeatDelay, 0));
@ -3919,6 +3939,33 @@ cMenuSetupMisc::cMenuSetupMisc(void)
Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Channels wrap"), &data.ChannelsWrap));
Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Show channel names with source"), &data.ShowChannelNamesWithSource));
Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Emergency exit"), &data.EmergencyExit));
SetCurrent(Get(current));
Display();
}
eOSState cMenuSetupMisc::ProcessKey(eKeys Key)
{
bool OldSVDRPPeering = data.SVDRPPeering;
bool ModifiedSVDRPSettings = false;
if (Key == kOk)
ModifiedSVDRPSettings = data.SVDRPPeering != Setup.SVDRPPeering | strcmp(data.SVDRPHostName, Setup.SVDRPHostName);
eOSState state = cMenuSetupBase::ProcessKey(Key);
if (data.SVDRPPeering != OldSVDRPPeering)
Set();
if (ModifiedSVDRPSettings) {
StopSVDRPClientHandler();
StopSVDRPServerHandler();
StartSVDRPServerHandler();
if (data.SVDRPPeering)
StartSVDRPClientHandler();
else {
LOCK_TIMERS_WRITE;
Timers->SetExplicitModify();
if (Timers->DelRemoteTimers())
Timers->SetModified();
}
}
return state;
}
// --- cMenuSetupPluginItem --------------------------------------------------

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menuitems.c 4.1 2015/07/18 10:38:31 kls Exp $
* $Id: menuitems.c 4.2 2015/09/08 10:25:23 kls Exp $
*/
#include "menuitems.h"
@ -774,6 +774,26 @@ void cMenuEditStraItem::Set(void)
SetValue(strings[*value]);
}
// --- cMenuEditStrlItem -----------------------------------------------------
cMenuEditStrlItem::cMenuEditStrlItem(const char *Name, char *Value, int Length, const cStringList *Strings)
:cMenuEditIntItem(Name, &index, 0, Strings->Size() - 1)
{
strings = Strings;
value = Value;
length = Length;
index = strings->Find(value);
if (index < 0)
index = 0;
Set();
}
void cMenuEditStrlItem::Set(void)
{
strn0cpy(value, strings->At(index), length);
SetValue(value);
}
// --- cMenuEditChanItem -----------------------------------------------------
cMenuEditChanItem::cMenuEditChanItem(const char *Name, int *Value, const char *NoneString)

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menuitems.h 3.1 2013/05/24 10:19:55 kls Exp $
* $Id: menuitems.h 4.1 2015/09/06 10:38:37 kls Exp $
*/
#ifndef __MENUITEMS_H
@ -146,6 +146,18 @@ public:
cMenuEditStraItem(const char *Name, int *Value, int NumStrings, const char * const *Strings);
};
class cMenuEditStrlItem : public cMenuEditIntItem {
private:
const cStringList *strings;
int index;
char *value;
int length;
protected:
virtual void Set(void);
public:
cMenuEditStrlItem(const char *Name, char *Value, int Length, const cStringList *Strings);
};
class cMenuEditChanItem : public cMenuEditIntItem {
protected:
const char *noneString;

65
svdrp.c
View File

@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
* $Id: svdrp.c 4.5 2015/09/06 09:25:16 kls Exp $
* $Id: svdrp.c 4.6 2015/09/08 11:08:06 kls Exp $
*/
#include "svdrp.h"
@ -45,17 +45,8 @@ static bool DumpSVDRPDataTransfer = false;
#define dbgsvdrp(a...) if (DumpSVDRPDataTransfer) fprintf(stderr, a)
const char *SVDRPHostName(void)
{
static char buffer[HOST_NAME_MAX] = "";
if (!*buffer) {
if (gethostname(buffer, sizeof(buffer)) < 0) {
LOG_ERROR;
strcpy(buffer, "vdr");
}
}
return buffer;
}
static int SVDRPTcpPort = 0;
static int SVDRPUdpPort = 0;
// --- cIpAddress ------------------------------------------------------------
@ -375,7 +366,6 @@ cSVDRPClient::cSVDRPClient(const char *Address, int Port, const char *ServerName
if (file.Open(socket.Socket())) {
SVDRPClientPoller.Add(file, false);
dsyslog("SVDRP > %s client created for '%s'", ipAddress.Connection(), *serverName);
SendSVDRPDiscover(Address);
return;
}
}
@ -510,8 +500,8 @@ bool cSVDRPClient::HasFetchFlag(eSvdrpFetchFlags Flag)
class cSVDRPClientHandler : public cThread {
private:
cMutex mutex;
cSocket udpSocket;
int tcpPort;
cSocket udpSocket;
cVector<cSVDRPClient *> clientConnections;
void HandleClientConnection(void);
void ProcessConnections(void);
@ -519,7 +509,7 @@ private:
protected:
virtual void Action(void);
public:
cSVDRPClientHandler(int UdpPort, int TcpPort);
cSVDRPClientHandler(int TcpPort, int UdpPort);
virtual ~cSVDRPClientHandler();
void SendDiscover(const char *Address = NULL);
bool Execute(const char *ServerName, const char *Command, cStringList *Response);
@ -529,7 +519,7 @@ public:
static cSVDRPClientHandler *SVDRPClientHandler = NULL;
cSVDRPClientHandler::cSVDRPClientHandler(int UdpPort, int TcpPort)
cSVDRPClientHandler::cSVDRPClientHandler(int TcpPort, int UdpPort)
:cThread("SVDRP client handler", true)
,udpSocket(UdpPort, false)
{
@ -555,7 +545,7 @@ cSVDRPClient *cSVDRPClientHandler::GetClientForServer(const char *ServerName)
void cSVDRPClientHandler::SendDiscover(const char *Address)
{
cMutexLock MutexLock(&mutex);
cString Dgram = cString::sprintf("SVDRP:discover name:%s port:%d vdrversion:%d apiversion:%d timeout:%d", SVDRPHostName(), tcpPort, VDRVERSNUM, APIVERSNUM, Setup.SVDRPTimeout);
cString Dgram = cString::sprintf("SVDRP:discover name:%s port:%d vdrversion:%d apiversion:%d timeout:%d", Setup.SVDRPHostName, tcpPort, VDRVERSNUM, APIVERSNUM, Setup.SVDRPTimeout);
udpSocket.SendDgram(Dgram, udpSocket.Port(), Address);
}
@ -589,8 +579,11 @@ void cSVDRPClientHandler::HandleClientConnection(void)
cString t = strgetval(NewDiscover, "timeout", ':');
if (*t) {
int Timeout = atoi(t);
if (Timeout > 10) // don't let it get too small
clientConnections.Append(new cSVDRPClient(udpSocket.LastIpAddress()->Address(), Port, ServerName, Timeout));
if (Timeout > 10) { // don't let it get too small
const char *Address = udpSocket.LastIpAddress()->Address();
clientConnections.Append(new cSVDRPClient(Address, Port, ServerName, Timeout));
SendDiscover(Address);
}
else
esyslog("SVDRP < %s ERROR: invalid timeout (%d)", udpSocket.LastIpAddress()->Connection(), Timeout);
}
@ -999,7 +992,7 @@ cSVDRPServer::cSVDRPServer(int Socket, const char *Connection)
lastActivity = time(NULL);
if (file.Open(socket)) {
time_t now = time(NULL);
Reply(220, "%s SVDRP VideoDiskRecorder %s; %s; %s", SVDRPHostName(), VDRVERSION, *TimeToString(now), cCharSetConv::SystemCharacterTable() ? cCharSetConv::SystemCharacterTable() : "UTF-8");
Reply(220, "%s SVDRP VideoDiskRecorder %s; %s; %s", Setup.SVDRPHostName, VDRVERSION, *TimeToString(now), cCharSetConv::SystemCharacterTable() ? cCharSetConv::SystemCharacterTable() : "UTF-8");
SVDRPServerPoller.Add(file, false);
}
dsyslog("SVDRP < %s server created", *connection);
@ -1016,7 +1009,7 @@ void cSVDRPServer::Close(bool SendReply, bool Timeout)
{
if (file.IsOpen()) {
if (SendReply) {
Reply(221, "%s closing connection%s", SVDRPHostName(), Timeout ? " (timeout)" : "");
Reply(221, "%s closing connection%s", Setup.SVDRPHostName, Timeout ? " (timeout)" : "");
}
isyslog("SVDRP < %s connection closed", *connection);
SVDRPServerPoller.Del(file, false);
@ -2044,7 +2037,7 @@ void cSVDRPServer::CmdNEXT(const char *Option)
void cSVDRPServer::CmdPING(const char *Option)
{
Reply(250, "%s is alive", SVDRPHostName());
Reply(250, "%s is alive", Setup.SVDRPHostName);
}
void cSVDRPServer::CmdPLAY(const char *Option)
@ -2434,6 +2427,12 @@ bool cSVDRPServer::Process(void)
return file.IsOpen();
}
void SetSVDRPPorts(int TcpPort, int UdpPort)
{
SVDRPTcpPort = TcpPort;
SVDRPUdpPort = UdpPort;
}
void SetSVDRPGrabImageDir(const char *GrabImageDir)
{
grabImageDir = GrabImageDir;
@ -2519,25 +2518,35 @@ void cSVDRPServerHandler::Action(void)
static cMutex SVDRPHandlerMutex;
void StartSVDRPHandler(int TcpPort, int UdpPort)
void StartSVDRPServerHandler(void)
{
cMutexLock MutexLock(&SVDRPHandlerMutex);
if (TcpPort && !SVDRPServerHandler) {
SVDRPServerHandler = new cSVDRPServerHandler(TcpPort);
if (SVDRPTcpPort && !SVDRPServerHandler) {
SVDRPServerHandler = new cSVDRPServerHandler(SVDRPTcpPort);
SVDRPServerHandler->Start();
SVDRPServerHandler->WaitUntilReady();
}
if (UdpPort && !SVDRPClientHandler) {
SVDRPClientHandler = new cSVDRPClientHandler(UdpPort, TcpPort);
}
void StartSVDRPClientHandler(void)
{
cMutexLock MutexLock(&SVDRPHandlerMutex);
if (SVDRPTcpPort && SVDRPUdpPort && !SVDRPClientHandler) {
SVDRPClientHandler = new cSVDRPClientHandler(SVDRPTcpPort, SVDRPUdpPort);
SVDRPClientHandler->Start();
}
}
void StopSVDRPHandler(void)
void StopSVDRPServerHandler(void)
{
cMutexLock MutexLock(&SVDRPHandlerMutex);
delete SVDRPServerHandler;
SVDRPServerHandler = NULL;
}
void StopSVDRPClientHandler(void)
{
cMutexLock MutexLock(&SVDRPHandlerMutex);
delete SVDRPClientHandler;
SVDRPClientHandler = NULL;
}

10
svdrp.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: svdrp.h 4.3 2015/09/01 10:34:09 kls Exp $
* $Id: svdrp.h 4.4 2015/09/06 12:39:24 kls Exp $
*/
#ifndef __SVDRP_H
@ -57,10 +57,12 @@ enum eSvdrpFetchFlags {
sffTimers = 0b0001,
};
const char *SVDRPHostName(void);
void SetSVDRPPorts(int TcpPort, int UdpPort);
void SetSVDRPGrabImageDir(const char *GrabImageDir);
void StartSVDRPHandler(int TcpPort, int UdpPort);
void StopSVDRPHandler(void);
void StartSVDRPServerHandler(void);
void StartSVDRPClientHandler(void);
void StopSVDRPServerHandler(void);
void StopSVDRPClientHandler(void);
void SendSVDRPDiscover(const char *Address = NULL);
bool GetSVDRPServerNames(cStringList *ServerNames, eSvdrpFetchFlags FetchFlag = sffNone);
///< Gets a list of all available VDRs this VDR is connected to via SVDRP,

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: timers.c 4.2 2015/09/05 14:42:50 kls Exp $
* $Id: timers.c 4.3 2015/09/08 10:01:02 kls Exp $
*/
#include "timers.h"
@ -939,9 +939,9 @@ bool cTimers::DelRemoteTimers(const char *ServerName)
void cTimers::TriggerRemoteTimerPoll(const char *ServerName)
{
if (ServerName) {
cSVDRPCommand Cmd(ServerName, cString::sprintf("POLL %s TIMERS", SVDRPHostName()));
cSVDRPCommand Cmd(ServerName, cString::sprintf("POLL %s TIMERS", Setup.SVDRPHostName));
if (!Cmd.Execute())
esyslog("ERROR: can't send 'POLL %s TIMERS' to '%s'", SVDRPHostName(), ServerName);
esyslog("ERROR: can't send 'POLL %s TIMERS' to '%s'", Setup.SVDRPHostName, ServerName);
}
else {
cStringList ServerNames;

16
tools.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.c 4.2 2015/08/29 12:11:20 kls Exp $
* $Id: tools.c 4.3 2015/09/06 10:47:05 kls Exp $
*/
#include "tools.h"
@ -1322,6 +1322,20 @@ uchar *RgbToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality)
return jcd.mem;
}
// --- GetHostName -----------------------------------------------------------
const char *GetHostName(void)
{
static char buffer[HOST_NAME_MAX] = "";
if (!*buffer) {
if (gethostname(buffer, sizeof(buffer)) < 0) {
LOG_ERROR;
strcpy(buffer, "vdr");
}
}
return buffer;
}
// --- cBase64Encoder --------------------------------------------------------
const char *cBase64Encoder::b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.h 4.2 2015/08/29 11:45:51 kls Exp $
* $Id: tools.h 4.3 2015/09/06 10:45:54 kls Exp $
*/
#ifndef __TOOLS_H
@ -293,6 +293,8 @@ uchar *RgbToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality = 100
///< resulting image, where 100 is "best". The caller takes ownership of
///< the result and has to delete it once it is no longer needed.
///< The result may be NULL in case of an error.
const char *GetHostName(void);
///< Gets the host name of this machine.
class cBase64Encoder {
private:

10
vdr.c
View File

@ -22,7 +22,7 @@
*
* The project's page is at http://www.tvdr.de
*
* $Id: vdr.c 4.5 2015/09/01 10:33:04 kls Exp $
* $Id: vdr.c 4.6 2015/09/08 10:00:46 kls Exp $
*/
#include <getopt.h>
@ -919,7 +919,10 @@ int main(int argc, char *argv[])
// SVDRP:
StartSVDRPHandler(SVDRPport, DEFAULTSVDRPPORT);
SetSVDRPPorts(SVDRPport, DEFAULTSVDRPPORT);
StartSVDRPServerHandler();
if (Setup.SVDRPPeering)
StartSVDRPClientHandler();
// Main program loop:
@ -1524,7 +1527,8 @@ Exit:
signal(SIGPIPE, SIG_DFL);
signal(SIGALRM, SIG_DFL);
StopSVDRPHandler();
StopSVDRPClientHandler();
StopSVDRPServerHandler();
PluginManager.StopPlugins();
cRecordControls::Shutdown();
RecordingsHandler.DelAll();