mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Moved handling remote timers into cSVDRPClientHandler::ProcessConnections()
This commit is contained in:
parent
bbbc36a1e6
commit
6600478675
3
HISTORY
3
HISTORY
@ -9162,7 +9162,7 @@ Video Disk Recorder Revision History
|
|||||||
a subdirectory.
|
a subdirectory.
|
||||||
- SVDRP peering can now be limited to the default SVDRP host (see MANUAL for details).
|
- SVDRP peering can now be limited to the default SVDRP host (see MANUAL for details).
|
||||||
|
|
||||||
2018-02-20: Version 2.3.9
|
2018-02-25: Version 2.3.9
|
||||||
|
|
||||||
- Updated the Italian OSD texts (thanks to Diego Pierotto).
|
- Updated the Italian OSD texts (thanks to Diego Pierotto).
|
||||||
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
|
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
|
||||||
@ -9283,3 +9283,4 @@ Video Disk Recorder Revision History
|
|||||||
SVDRP command CONN instead of using the UDP port with the server's address.
|
SVDRP command CONN instead of using the UDP port with the server's address.
|
||||||
This change requires that all VDRs that shall take part in a peer-to-peer network need
|
This change requires that all VDRs that shall take part in a peer-to-peer network need
|
||||||
to be updated to this version.
|
to be updated to this version.
|
||||||
|
- Moved handling remote timers into cSVDRPClientHandler::ProcessConnections().
|
||||||
|
4
menu.c
4
menu.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: menu.c 4.61 2018/02/13 09:25:43 kls Exp $
|
* $Id: menu.c 4.62 2018/02/25 13:07:09 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -4184,7 +4184,7 @@ eOSState cMenuSetupMisc::ProcessKey(eKeys Key)
|
|||||||
else {
|
else {
|
||||||
LOCK_TIMERS_WRITE;
|
LOCK_TIMERS_WRITE;
|
||||||
Timers->SetExplicitModify();
|
Timers->SetExplicitModify();
|
||||||
if (Timers->DelRemoteTimers())
|
if (Timers->StoreRemoteTimers(NULL, NULL))
|
||||||
Timers->SetModified();
|
Timers->SetModified();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
72
svdrp.c
72
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* graphical interface that sits on top of an SVDRP connection.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.c 4.27 2018/02/20 13:28:04 kls Exp $
|
* $Id: svdrp.c 4.28 2018/02/25 13:26:17 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "svdrp.h"
|
#include "svdrp.h"
|
||||||
@ -317,6 +317,7 @@ private:
|
|||||||
cFile file;
|
cFile file;
|
||||||
int fetchFlags;
|
int fetchFlags;
|
||||||
bool connected;
|
bool connected;
|
||||||
|
bool Send(const char *Command);
|
||||||
void Close(void);
|
void Close(void);
|
||||||
public:
|
public:
|
||||||
cSVDRPClient(const char *Address, int Port, const char *ServerName, int Timeout);
|
cSVDRPClient(const char *Address, int Port, const char *ServerName, int Timeout);
|
||||||
@ -324,12 +325,12 @@ public:
|
|||||||
const char *ServerName(void) const { return serverName; }
|
const char *ServerName(void) const { return serverName; }
|
||||||
const char *Connection(void) const { return serverIpAddress.Connection(); }
|
const char *Connection(void) const { return serverIpAddress.Connection(); }
|
||||||
bool HasAddress(const char *Address, int Port) const;
|
bool HasAddress(const char *Address, int Port) const;
|
||||||
bool Send(const char *Command);
|
|
||||||
bool Process(cStringList *Response = NULL);
|
bool Process(cStringList *Response = NULL);
|
||||||
bool Execute(const char *Command, cStringList *Response = NULL);
|
bool Execute(const char *Command, cStringList *Response = NULL);
|
||||||
bool Connected(void) const { return connected; }
|
bool Connected(void) const { return connected; }
|
||||||
void SetFetchFlag(eSvdrpFetchFlags Flag);
|
void SetFetchFlag(eSvdrpFetchFlags Flag);
|
||||||
bool HasFetchFlag(eSvdrpFetchFlags Flag);
|
bool HasFetchFlag(eSvdrpFetchFlags Flag);
|
||||||
|
bool GetRemoteTimers(cStringList &Response);
|
||||||
};
|
};
|
||||||
|
|
||||||
static cPoller SVDRPClientPoller;
|
static cPoller SVDRPClientPoller;
|
||||||
@ -365,9 +366,6 @@ void cSVDRPClient::Close(void)
|
|||||||
SVDRPClientPoller.Del(file, false);
|
SVDRPClientPoller.Del(file, false);
|
||||||
file.Close();
|
file.Close();
|
||||||
socket.Close();
|
socket.Close();
|
||||||
LOCK_TIMERS_WRITE;
|
|
||||||
if (Timers)
|
|
||||||
Timers->DelRemoteTimers(serverName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,6 +481,14 @@ bool cSVDRPClient::HasFetchFlag(eSvdrpFetchFlags Flag)
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cSVDRPClient::GetRemoteTimers(cStringList &Response)
|
||||||
|
{
|
||||||
|
if (HasFetchFlag(sffTimers))
|
||||||
|
return Execute("LSTT ID", &Response);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- cSVDRPServerParams ----------------------------------------------------
|
// --- cSVDRPServerParams ----------------------------------------------------
|
||||||
|
|
||||||
class cSVDRPServerParams {
|
class cSVDRPServerParams {
|
||||||
@ -554,20 +560,21 @@ private:
|
|||||||
cMutex mutex;
|
cMutex mutex;
|
||||||
int tcpPort;
|
int tcpPort;
|
||||||
cSocket udpSocket;
|
cSocket udpSocket;
|
||||||
|
cStateKey timersStateKey;
|
||||||
cVector<cSVDRPClient *> clientConnections;
|
cVector<cSVDRPClient *> clientConnections;
|
||||||
|
void SendDiscover(void);
|
||||||
void HandleClientConnection(void);
|
void HandleClientConnection(void);
|
||||||
void ProcessConnections(void);
|
void ProcessConnections(void);
|
||||||
|
cSVDRPClient *GetClientForServer(const char *ServerName);
|
||||||
protected:
|
protected:
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
public:
|
public:
|
||||||
cSVDRPClientHandler(int TcpPort, int UdpPort);
|
cSVDRPClientHandler(int TcpPort, int UdpPort);
|
||||||
virtual ~cSVDRPClientHandler();
|
virtual ~cSVDRPClientHandler();
|
||||||
void SendDiscover(void);
|
|
||||||
void AddClient(cSVDRPServerParams &ServerParams, const char *IpAddress);
|
void AddClient(cSVDRPServerParams &ServerParams, const char *IpAddress);
|
||||||
bool Execute(const char *ServerName, const char *Command, cStringList *Response = NULL);
|
bool Execute(const char *ServerName, const char *Command, cStringList *Response = NULL);
|
||||||
bool GetServerNames(cStringList *ServerNames, eSvdrpFetchFlags FetchFlags = sffNone);
|
bool GetServerNames(cStringList *ServerNames, eSvdrpFetchFlags FetchFlags = sffNone);
|
||||||
bool TriggerFetchingTimers(const char *ServerName);
|
bool TriggerFetchingTimers(const char *ServerName);
|
||||||
cSVDRPClient *GetClientForServer(const char *ServerName);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static cSVDRPClientHandler *SVDRPClientHandler = NULL;
|
static cSVDRPClientHandler *SVDRPClientHandler = NULL;
|
||||||
@ -575,6 +582,7 @@ static cSVDRPClientHandler *SVDRPClientHandler = NULL;
|
|||||||
cSVDRPClientHandler::cSVDRPClientHandler(int TcpPort, int UdpPort)
|
cSVDRPClientHandler::cSVDRPClientHandler(int TcpPort, int UdpPort)
|
||||||
:cThread("SVDRP client handler", true)
|
:cThread("SVDRP client handler", true)
|
||||||
,udpSocket(UdpPort, false)
|
,udpSocket(UdpPort, false)
|
||||||
|
,timersStateKey(true)
|
||||||
{
|
{
|
||||||
tcpPort = TcpPort;
|
tcpPort = TcpPort;
|
||||||
}
|
}
|
||||||
@ -588,7 +596,6 @@ cSVDRPClientHandler::~cSVDRPClientHandler()
|
|||||||
|
|
||||||
cSVDRPClient *cSVDRPClientHandler::GetClientForServer(const char *ServerName)
|
cSVDRPClient *cSVDRPClientHandler::GetClientForServer(const char *ServerName)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutex);
|
|
||||||
for (int i = 0; i < clientConnections.Size(); i++) {
|
for (int i = 0; i < clientConnections.Size(); i++) {
|
||||||
if (strcmp(clientConnections[i]->ServerName(), ServerName) == 0)
|
if (strcmp(clientConnections[i]->ServerName(), ServerName) == 0)
|
||||||
return clientConnections[i];
|
return clientConnections[i];
|
||||||
@ -598,17 +605,36 @@ cSVDRPClient *cSVDRPClientHandler::GetClientForServer(const char *ServerName)
|
|||||||
|
|
||||||
void cSVDRPClientHandler::SendDiscover(void)
|
void cSVDRPClientHandler::SendDiscover(void)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutex);
|
|
||||||
cString Dgram = cString::sprintf("SVDRP:discover name:%s port:%d vdrversion:%d apiversion:%d timeout:%d%s", Setup.SVDRPHostName, tcpPort, VDRVERSNUM, APIVERSNUM, Setup.SVDRPTimeout, (Setup.SVDRPPeering == spmOnly && *Setup.SVDRPDefaultHost) ? *cString::sprintf(" host:%s", Setup.SVDRPDefaultHost) : "");
|
cString Dgram = cString::sprintf("SVDRP:discover name:%s port:%d vdrversion:%d apiversion:%d timeout:%d%s", Setup.SVDRPHostName, tcpPort, VDRVERSNUM, APIVERSNUM, Setup.SVDRPTimeout, (Setup.SVDRPPeering == spmOnly && *Setup.SVDRPDefaultHost) ? *cString::sprintf(" host:%s", Setup.SVDRPDefaultHost) : "");
|
||||||
udpSocket.SendDgram(Dgram, udpSocket.Port());
|
udpSocket.SendDgram(Dgram, udpSocket.Port());
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRPClientHandler::ProcessConnections(void)
|
void cSVDRPClientHandler::ProcessConnections(void)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutex);
|
cString PollTimersCmd;
|
||||||
|
if (cTimers::GetTimersRead(timersStateKey)) {
|
||||||
|
PollTimersCmd = cString::sprintf("POLL %s TIMERS", Setup.SVDRPHostName);
|
||||||
|
timersStateKey.Remove();
|
||||||
|
}
|
||||||
for (int i = 0; i < clientConnections.Size(); i++) {
|
for (int i = 0; i < clientConnections.Size(); i++) {
|
||||||
if (!clientConnections[i]->Process()) {
|
cSVDRPClient *Client = clientConnections[i];
|
||||||
delete clientConnections[i];
|
if (Client->Process()) {
|
||||||
|
cStringList RemoteTimers;
|
||||||
|
if (Client->GetRemoteTimers(RemoteTimers)) {
|
||||||
|
cTimers *Timers = cTimers::GetTimersWrite(timersStateKey);
|
||||||
|
bool TimersModified = Timers->StoreRemoteTimers(Client->ServerName(), &RemoteTimers);
|
||||||
|
timersStateKey.Remove(TimersModified);
|
||||||
|
}
|
||||||
|
if (*PollTimersCmd) {
|
||||||
|
if (!Client->Execute(PollTimersCmd))
|
||||||
|
esyslog("ERROR: can't send '%s' to '%s'", *PollTimersCmd, Client->ServerName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cTimers *Timers = cTimers::GetTimersWrite(timersStateKey);
|
||||||
|
bool TimersModified = Timers->StoreRemoteTimers(Client->ServerName(), NULL);
|
||||||
|
timersStateKey.Remove(TimersModified);
|
||||||
|
delete Client;
|
||||||
clientConnections.Remove(i);
|
clientConnections.Remove(i);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@ -617,11 +643,10 @@ void cSVDRPClientHandler::ProcessConnections(void)
|
|||||||
|
|
||||||
void cSVDRPClientHandler::AddClient(cSVDRPServerParams &ServerParams, const char *IpAddress)
|
void cSVDRPClientHandler::AddClient(cSVDRPServerParams &ServerParams, const char *IpAddress)
|
||||||
{
|
{
|
||||||
|
cMutexLock MutexLock(&mutex);
|
||||||
for (int i = 0; i < clientConnections.Size(); i++) {
|
for (int i = 0; i < clientConnections.Size(); i++) {
|
||||||
if (clientConnections[i]->HasAddress(IpAddress, ServerParams.Port())) {
|
if (clientConnections[i]->HasAddress(IpAddress, ServerParams.Port()))
|
||||||
dsyslog("SVDRP %s < %s connection to '%s' already exists", Setup.SVDRPHostName, clientConnections[i]->Connection(), clientConnections[i]->ServerName());
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (Setup.SVDRPPeering == spmOnly && strcmp(ServerParams.Name(), Setup.SVDRPDefaultHost) != 0)
|
if (Setup.SVDRPPeering == spmOnly && strcmp(ServerParams.Name(), Setup.SVDRPDefaultHost) != 0)
|
||||||
return; // we only want to peer with the default host, but this isn't the default host
|
return; // we only want to peer with the default host, but this isn't the default host
|
||||||
@ -1294,8 +1319,7 @@ void cSVDRPServer::CmdCONN(const char *Option)
|
|||||||
if (ServerParams.Ok()) {
|
if (ServerParams.Ok()) {
|
||||||
clientName = ServerParams.Name();
|
clientName = ServerParams.Name();
|
||||||
Reply(250, "OK"); // must finish this transaction before creating the new client
|
Reply(250, "OK"); // must finish this transaction before creating the new client
|
||||||
if (!SVDRPClientHandler->GetClientForServer(ServerParams.Name()))
|
SVDRPClientHandler->AddClient(ServerParams, clientIpAddress.Address());
|
||||||
SVDRPClientHandler->AddClient(ServerParams, clientIpAddress.Address());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Reply(501, "Error in server parameters: %s", ServerParams.Error());
|
Reply(501, "Error in server parameters: %s", ServerParams.Error());
|
||||||
@ -2601,7 +2625,6 @@ void SetSVDRPGrabImageDir(const char *GrabImageDir)
|
|||||||
|
|
||||||
class cSVDRPServerHandler : public cThread {
|
class cSVDRPServerHandler : public cThread {
|
||||||
private:
|
private:
|
||||||
cMutex mutex;
|
|
||||||
bool ready;
|
bool ready;
|
||||||
cSocket tcpSocket;
|
cSocket tcpSocket;
|
||||||
cVector<cSVDRPServer *> serverConnections;
|
cVector<cSVDRPServer *> serverConnections;
|
||||||
@ -2613,7 +2636,6 @@ public:
|
|||||||
cSVDRPServerHandler(int TcpPort);
|
cSVDRPServerHandler(int TcpPort);
|
||||||
virtual ~cSVDRPServerHandler();
|
virtual ~cSVDRPServerHandler();
|
||||||
void WaitUntilReady(void);
|
void WaitUntilReady(void);
|
||||||
cSVDRPServer *GetServerForClient(const char *ClientName);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static cSVDRPServerHandler *SVDRPServerHandler = NULL;
|
static cSVDRPServerHandler *SVDRPServerHandler = NULL;
|
||||||
@ -2641,7 +2663,6 @@ void cSVDRPServerHandler::WaitUntilReady(void)
|
|||||||
|
|
||||||
void cSVDRPServerHandler::ProcessConnections(void)
|
void cSVDRPServerHandler::ProcessConnections(void)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutex);
|
|
||||||
for (int i = 0; i < serverConnections.Size(); i++) {
|
for (int i = 0; i < serverConnections.Size(); i++) {
|
||||||
if (!serverConnections[i]->Process()) {
|
if (!serverConnections[i]->Process()) {
|
||||||
delete serverConnections[i];
|
delete serverConnections[i];
|
||||||
@ -2665,7 +2686,6 @@ void cSVDRPServerHandler::Action(void)
|
|||||||
ready = true;
|
ready = true;
|
||||||
while (Running()) {
|
while (Running()) {
|
||||||
SVDRPServerPoller.Poll(1000);
|
SVDRPServerPoller.Poll(1000);
|
||||||
cMutexLock MutexLock(&mutex);
|
|
||||||
HandleServerConnection();
|
HandleServerConnection();
|
||||||
ProcessConnections();
|
ProcessConnections();
|
||||||
}
|
}
|
||||||
@ -2674,16 +2694,6 @@ void cSVDRPServerHandler::Action(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cSVDRPServer *cSVDRPServerHandler::GetServerForClient(const char *ClientName)
|
|
||||||
{
|
|
||||||
cMutexLock MutexLock(&mutex);
|
|
||||||
for (int i = 0; i < serverConnections.Size(); i++) {
|
|
||||||
if (serverConnections[i]->ClientName() && strcmp(serverConnections[i]->ClientName(), ClientName) == 0)
|
|
||||||
return serverConnections[i];
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- SVDRP Handler ---------------------------------------------------------
|
// --- SVDRP Handler ---------------------------------------------------------
|
||||||
|
|
||||||
static cMutex SVDRPHandlerMutex;
|
static cMutex SVDRPHandlerMutex;
|
||||||
|
94
timers.c
94
timers.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: timers.c 4.14 2017/11/12 13:01:22 kls Exp $
|
* $Id: timers.c 4.15 2018/02/25 13:05:03 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
@ -898,78 +898,48 @@ bool cTimers::DeleteExpired(void)
|
|||||||
return TimersModified;
|
return TimersModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cTimers::GetRemoteTimers(const char *ServerName)
|
bool cTimers::StoreRemoteTimers(const char *ServerName, const cStringList *RemoteTimers)
|
||||||
{
|
{
|
||||||
|
//TODO handle only new/deleted/modified timers?
|
||||||
bool Result = false;
|
bool Result = false;
|
||||||
if (ServerName) {
|
// Delete old remote timers:
|
||||||
Result = DelRemoteTimers(ServerName);
|
|
||||||
cStringList Response;
|
|
||||||
if (ExecSVDRPCommand(ServerName, "LSTT ID", &Response)) {
|
|
||||||
for (int i = 0; i < Response.Size(); i++) {
|
|
||||||
const char *s = Response[i];
|
|
||||||
int Code = SVDRPCode(s);
|
|
||||||
if (Code == 250) {
|
|
||||||
if (const char *v = SVDRPValue(s)) {
|
|
||||||
int Id = atoi(v);
|
|
||||||
while (*v && *v != ' ')
|
|
||||||
v++; // skip id
|
|
||||||
cTimer *Timer = new cTimer;
|
|
||||||
if (Timer->Parse(v)) {
|
|
||||||
Timer->SetRemote(ServerName);
|
|
||||||
Timer->SetId(Id);
|
|
||||||
Add(Timer);
|
|
||||||
Result = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
esyslog("ERROR: %s: error in timer settings: %s", ServerName, v);
|
|
||||||
delete Timer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Code != 550)
|
|
||||||
esyslog("ERROR: %s: %s", ServerName, s);
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cStringList ServerNames;
|
|
||||||
if (GetSVDRPServerNames(&ServerNames, sffTimers)) {
|
|
||||||
for (int i = 0; i < ServerNames.Size(); i++)
|
|
||||||
Result |= GetRemoteTimers(ServerNames[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cTimers::DelRemoteTimers(const char *ServerName)
|
|
||||||
{
|
|
||||||
bool Deleted = false;
|
|
||||||
cTimer *Timer = First();
|
cTimer *Timer = First();
|
||||||
while (Timer) {
|
while (Timer) {
|
||||||
cTimer *t = Next(Timer);
|
cTimer *t = Next(Timer);
|
||||||
if (Timer->Remote() && (!ServerName || strcmp(Timer->Remote(), ServerName) == 0)) {
|
if (Timer->Remote() && (!ServerName || strcmp(Timer->Remote(), ServerName) == 0)) {
|
||||||
Del(Timer);
|
Del(Timer);
|
||||||
Deleted = true;
|
Result = true;
|
||||||
}
|
}
|
||||||
Timer = t;
|
Timer = t;
|
||||||
}
|
}
|
||||||
return Deleted;
|
// Add new remote timers:
|
||||||
}
|
if (ServerName && RemoteTimers) {
|
||||||
|
for (int i = 0; i < RemoteTimers->Size(); i++) {
|
||||||
void cTimers::TriggerRemoteTimerPoll(const char *ServerName)
|
const char *s = (*RemoteTimers)[i];
|
||||||
{
|
int Code = SVDRPCode(s);
|
||||||
if (ServerName) {
|
if (Code == 250) {
|
||||||
if (!ExecSVDRPCommand(ServerName, cString::sprintf("POLL %s TIMERS", Setup.SVDRPHostName)))
|
if (const char *v = SVDRPValue(s)) {
|
||||||
esyslog("ERROR: can't send 'POLL %s TIMERS' to '%s'", Setup.SVDRPHostName, ServerName);
|
int Id = atoi(v);
|
||||||
}
|
while (*v && *v != ' ')
|
||||||
else {
|
v++; // skip id
|
||||||
cStringList ServerNames;
|
cTimer *Timer = new cTimer;
|
||||||
if (GetSVDRPServerNames(&ServerNames)) {
|
if (Timer->Parse(v)) {
|
||||||
for (int i = 0; i < ServerNames.Size(); i++)
|
Timer->SetRemote(ServerName);
|
||||||
TriggerRemoteTimerPoll(ServerNames[i]);
|
Timer->SetId(Id);
|
||||||
}
|
Add(Timer);
|
||||||
|
Result = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
esyslog("ERROR: %s: error in timer settings: %s", ServerName, v);
|
||||||
|
delete Timer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Code != 550)
|
||||||
|
esyslog("ERROR: %s: %s", ServerName, s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool RemoteTimerError(const cTimer *Timer, cString *Msg)
|
static bool RemoteTimerError(const cTimer *Timer, cString *Msg)
|
||||||
|
21
timers.h
21
timers.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: timers.h 4.9 2017/10/31 09:47:14 kls Exp $
|
* $Id: timers.h 4.10 2018/02/25 12:54:55 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TIMERS_H
|
#ifndef __TIMERS_H
|
||||||
@ -185,21 +185,12 @@ public:
|
|||||||
void Add(cTimer *Timer, cTimer *After = NULL);
|
void Add(cTimer *Timer, cTimer *After = NULL);
|
||||||
void Ins(cTimer *Timer, cTimer *Before = NULL);
|
void Ins(cTimer *Timer, cTimer *Before = NULL);
|
||||||
void Del(cTimer *Timer, bool DeleteObject = true);
|
void Del(cTimer *Timer, bool DeleteObject = true);
|
||||||
bool GetRemoteTimers(const char *ServerName = NULL);
|
bool StoreRemoteTimers(const char *ServerName = NULL, const cStringList *RemoteTimers = NULL);
|
||||||
///< Gets the timers from the given remote machine and adds them to this
|
///< Stores the given list of RemoteTimers, which come from the VDR ServerName, in
|
||||||
///< list. If no ServerName is given, all timers from all known remote
|
///< this list. If no ServerName is given, all remote timers from all peer machines
|
||||||
///< machines will be fetched. This function calls DelRemoteTimers() with
|
///< will be removed from this list. If no RemoteTimers are given, only the remote
|
||||||
///< the given ServerName first.
|
///< timers from ServerName will be removed from this list.
|
||||||
///< Returns true if any remote timers have been added or deleted
|
///< Returns true if any remote timers have been added or deleted
|
||||||
bool DelRemoteTimers(const char *ServerName = NULL);
|
|
||||||
///< Deletes all timers of the given remote machine from this list (leaves
|
|
||||||
///< them untouched on the remote machine). If no ServerName is given, the
|
|
||||||
///< timers of all remote machines will be deleted from the list.
|
|
||||||
///< Returns true if any remote timers have been deleted.
|
|
||||||
void TriggerRemoteTimerPoll(const char *ServerName = NULL);
|
|
||||||
///< Sends an SVDRP POLL command to the given remote machine.
|
|
||||||
///< If no ServerName is given, the POLL command will be sent to all
|
|
||||||
///< known remote machines.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool HandleRemoteTimerModifications(cTimer *NewTimer, cTimer *OldTimer = NULL, cString *Msg = NULL);
|
bool HandleRemoteTimerModifications(cTimer *NewTimer, cTimer *OldTimer = NULL, cString *Msg = NULL);
|
||||||
|
21
vdr.c
21
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.21 2017/11/09 16:15:34 kls Exp $
|
* $Id: vdr.c 4.22 2018/02/25 13:07:09 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -1081,25 +1081,18 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
// Timers and Recordings:
|
// Timers and Recordings:
|
||||||
bool TimersModified = false;
|
bool TimersModified = false;
|
||||||
bool TriggerRemoteTimerPoll = false;
|
|
||||||
static cStateKey TimersStateKey(true);
|
static cStateKey TimersStateKey(true);
|
||||||
if (cTimers::GetTimersRead(TimersStateKey)) {
|
if (cTimers::GetTimersRead(TimersStateKey))
|
||||||
TriggerRemoteTimerPoll = true;
|
|
||||||
TimersStateKey.Remove();
|
TimersStateKey.Remove();
|
||||||
}
|
|
||||||
cTimers *Timers = cTimers::GetTimersWrite(TimersStateKey);
|
cTimers *Timers = cTimers::GetTimersWrite(TimersStateKey);
|
||||||
// Get remote timers:
|
|
||||||
TimersModified |= Timers->GetRemoteTimers();
|
|
||||||
// Assign events to timers:
|
// Assign events to timers:
|
||||||
static cStateKey SchedulesStateKey;
|
static cStateKey SchedulesStateKey;
|
||||||
if (const cSchedules *Schedules = cSchedules::GetSchedulesRead(SchedulesStateKey))
|
if (const cSchedules *Schedules = cSchedules::GetSchedulesRead(SchedulesStateKey))
|
||||||
TimersModified |= Timers->SetEvents(Schedules);
|
TimersModified |= Timers->SetEvents(Schedules);
|
||||||
// Must do all following calls with the exact same time!
|
// Must do all following calls with the exact same time!
|
||||||
// Process ongoing recordings:
|
// Process ongoing recordings:
|
||||||
if (cRecordControls::Process(Timers, Now)) {
|
if (cRecordControls::Process(Timers, Now))
|
||||||
TimersModified = true;
|
TimersModified = true;
|
||||||
TriggerRemoteTimerPoll = true;
|
|
||||||
}
|
|
||||||
// Must keep the lock on the schedules until after processing the record
|
// Must keep the lock on the schedules until after processing the record
|
||||||
// controls, in order to avoid short interrupts in case the current event
|
// controls, in order to avoid short interrupts in case the current event
|
||||||
// is replaced by a new one (which some broadcasters do, instead of just
|
// is replaced by a new one (which some broadcasters do, instead of just
|
||||||
@ -1113,7 +1106,6 @@ int main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
LastTimerChannel = Timer->Channel()->Number();
|
LastTimerChannel = Timer->Channel()->Number();
|
||||||
TimersModified = true;
|
TimersModified = true;
|
||||||
TriggerRemoteTimerPoll = true;
|
|
||||||
}
|
}
|
||||||
// Make sure timers "see" their channel early enough:
|
// Make sure timers "see" their channel early enough:
|
||||||
static time_t LastTimerCheck = 0;
|
static time_t LastTimerCheck = 0;
|
||||||
@ -1168,13 +1160,8 @@ int main(int argc, char *argv[])
|
|||||||
LastTimerCheck = Now;
|
LastTimerCheck = Now;
|
||||||
}
|
}
|
||||||
// Delete expired timers:
|
// Delete expired timers:
|
||||||
if (Timers->DeleteExpired()) {
|
if (Timers->DeleteExpired())
|
||||||
TimersModified = true;
|
TimersModified = true;
|
||||||
TriggerRemoteTimerPoll = true;
|
|
||||||
}
|
|
||||||
// Trigger remote timer polls:
|
|
||||||
if (TriggerRemoteTimerPoll)
|
|
||||||
Timers->TriggerRemoteTimerPoll();
|
|
||||||
// Make sure there is enough free disk space for ongoing recordings:
|
// Make sure there is enough free disk space for ongoing recordings:
|
||||||
AssertFreeDiskSpace(Timers->GetMaxPriority());
|
AssertFreeDiskSpace(Timers->GetMaxPriority());
|
||||||
TimersStateKey.Remove(TimersModified);
|
TimersStateKey.Remove(TimersModified);
|
||||||
|
Loading…
Reference in New Issue
Block a user