summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY6
-rw-r--r--config.h10
-rw-r--r--menu.c62
-rw-r--r--timers.c68
-rw-r--r--timers.h18
5 files changed, 105 insertions, 59 deletions
diff --git a/HISTORY b/HISTORY
index 74d22fb8..b142d45c 100644
--- a/HISTORY
+++ b/HISTORY
@@ -8924,3 +8924,9 @@ Video Disk Recorder Revision History
reading thread, without additional locking.
- Now stopping any ongoing recordings before stopping the plugins, to avoid
a crash when stopping VDR while recording.
+
+2017-03-30: Version 2.3.4
+
+- The functionality of HandleRemoteModifications(), which synchronizes changes to
+ timers between peer VDR machines, has been moved to timers.[ch] and renamed to
+ HandleRemoteTimerModifications(). It now also handles deleting remote timers.
diff --git a/config.h b/config.h
index 4bfdba56..e9a9f11d 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 4.7 2016/12/27 11:45:25 kls Exp $
+ * $Id: config.h 4.8 2017/03/30 13:42:15 kls Exp $
*/
#ifndef __CONFIG_H
@@ -22,13 +22,13 @@
// VDR's own version number:
-#define VDRVERSION "2.3.3"
-#define VDRVERSNUM 20303 // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION "2.3.4"
+#define VDRVERSNUM 20304 // Version * 10000 + Major * 100 + Minor
// The plugin API's version number:
-#define APIVERSION "2.3.3"
-#define APIVERSNUM 20303 // Version * 10000 + Major * 100 + Minor
+#define APIVERSION "2.3.4"
+#define APIVERSNUM 20304 // Version * 10000 + Major * 100 + Minor
// When loading plugins, VDR searches them by their APIVERSION, which
// may be smaller than VDRVERSION in case there have been no changes to
diff --git a/menu.c b/menu.c
index 685e94f6..b53678a9 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 4.22 2017/03/18 14:27:50 kls Exp $
+ * $Id: menu.c 4.23 2017/03/30 15:15:03 kls Exp $
*/
#include "menu.h"
@@ -1071,52 +1071,10 @@ static bool RemoteTimerError(const cTimer *Timer)
static bool HandleRemoteModifications(cTimer *NewTimer, cTimer *OldTimer = NULL)
{
- cStringList Response;
- if (!OldTimer || OldTimer->Local() || !OldTimer->Id()) {
- if (NewTimer->Local()) { // timer stays local, nothing to do
- if (OldTimer && OldTimer->Id())
- isyslog("modified timer %s", *NewTimer->ToDescr());
- else
- isyslog("added timer %s", *NewTimer->ToDescr());
- }
- else { // timer is new, or moved from local to remote
- if (!ExecSVDRPCommand(NewTimer->Remote(), cString::sprintf("NEWT %s", *NewTimer->ToText(true)), &Response) || SVDRPCode(Response[0]) != 250)
- return RemoteTimerError(NewTimer);
- int RemoteId = atoi(SVDRPValue(Response[0]));
- if (RemoteId <= 0)
- return RemoteTimerError(NewTimer);
- NewTimer->SetId(RemoteId);
- if (OldTimer && OldTimer->Id()) {
- if (OldTimer->Recording())
- cRecordControls::Stop(OldTimer);
- isyslog("moved timer %d to %s", OldTimer->Id(), *NewTimer->ToDescr());
- }
- else
- isyslog("added timer %s", *NewTimer->ToDescr());
- }
- }
- else if (NewTimer->Local()) { // timer is moved from remote to local
- if (!ExecSVDRPCommand(OldTimer->Remote(), cString::sprintf("DELT %d", OldTimer->Id()), &Response) || SVDRPCode(Response[0]) != 250)
- return RemoteTimerError(OldTimer);
- NewTimer->SetId(cTimers::NewTimerId());
- NewTimer->ClrFlags(tfRecording); // in case it was recording on the remote machine
- isyslog("moved timer %d@%s to %s", OldTimer->Id(), OldTimer->Remote(), *NewTimer->ToDescr());
- }
- else if (strcmp(OldTimer->Remote(), NewTimer->Remote()) == 0) { // timer stays remote on same machine
- if (!ExecSVDRPCommand(OldTimer->Remote(), cString::sprintf("MODT %d %s", OldTimer->Id(), *NewTimer->ToText(true)), &Response) || SVDRPCode(Response[0]) != 250)
- return RemoteTimerError(NewTimer);
- isyslog("modified timer %s", *NewTimer->ToDescr());
- }
- else { // timer is moved from one remote machine to an other
- if (!ExecSVDRPCommand(NewTimer->Remote(), cString::sprintf("NEWT %s", *NewTimer->ToText(true)), &Response) || SVDRPCode(Response[0]) != 250)
- return RemoteTimerError(NewTimer);
- int RemoteId = atoi(SVDRPValue(Response[0]));
- if (RemoteId <= 0)
- return RemoteTimerError(NewTimer);
- NewTimer->SetId(RemoteId);
- if (!ExecSVDRPCommand(OldTimer->Remote(), cString::sprintf("DELT %d", OldTimer->Id()), &Response) || SVDRPCode(Response[0]) != 250)
- return RemoteTimerError(OldTimer);
- isyslog("moved timer %d@%s to %s", OldTimer->Id(), OldTimer->Remote(), *NewTimer->ToDescr());
+ cString ErrorMessage;
+ if (!HandleRemoteTimerModifications(NewTimer, OldTimer, &ErrorMessage)) {
+ Skins.Message(mtError, ErrorMessage);
+ return false;
}
return true;
}
@@ -1157,6 +1115,8 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key)
else {
if (!HandleRemoteModifications(&data, timer))
return osContinue;
+ if (timer->Local() && timer->Recording() && data.Remote())
+ cRecordControls::Stop(timer);
*timer = data;
}
LOCK_SCHEDULES_READ;
@@ -1387,15 +1347,13 @@ eOSState cMenuTimers::Delete(void)
Timer = NULL;
}
if (Timer) {
- if (Timer->Remote()) {
- cStringList Response;
- if (!ExecSVDRPCommand(Timer->Remote(), cString::sprintf("DELT %d", Timer->Id()), &Response) || SVDRPCode(Response[0]) != 250)
- RemoteTimerError(Timer);
+ if (!HandleRemoteModifications(NULL, Timer)) {
+ timersStateKey.Remove();
+ return osContinue;
}
Timers->Del(Timer);
cOsdMenu::Del(Current());
Display();
- isyslog("deleted timer %s", *Timer->ToDescr());
}
}
}
diff --git a/timers.c b/timers.c
index 5bc11036..917be80c 100644
--- a/timers.c
+++ b/timers.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.c 4.7 2016/12/23 09:48:39 kls Exp $
+ * $Id: timers.c 4.8 2017/03/30 15:08:11 kls Exp $
*/
#include "timers.h"
@@ -955,6 +955,72 @@ void cTimers::TriggerRemoteTimerPoll(const char *ServerName)
}
}
+static bool RemoteTimerError(const cTimer *Timer, cString *Msg)
+{
+ if (Msg)
+ *Msg = cString::sprintf("%s %d@%s!", tr("Error while accessing remote timer"), Timer->Id(), Timer->Remote());
+ return false; // convenience return code
+}
+
+bool HandleRemoteTimerModifications(cTimer *NewTimer, cTimer *OldTimer, cString *Msg)
+{
+ cStringList Response;
+ if (!NewTimer) {
+ if (OldTimer) { // timer shall be deleted from remote machine
+ if (OldTimer->Remote() && OldTimer->Id()) {
+ if (!ExecSVDRPCommand(OldTimer->Remote(), cString::sprintf("DELT %d", OldTimer->Id()), &Response) || SVDRPCode(Response[0]) != 250)
+ return RemoteTimerError(OldTimer, Msg);
+ }
+ isyslog("deleted timer %s", *OldTimer->ToDescr());
+ }
+ }
+ else if (!OldTimer || OldTimer->Local() || !OldTimer->Id()) {
+ if (NewTimer->Local()) { // timer stays local, nothing to do
+ if (OldTimer && OldTimer->Id())
+ isyslog("modified timer %s", *NewTimer->ToDescr());
+ else
+ isyslog("added timer %s", *NewTimer->ToDescr());
+ }
+ else { // timer is new, or moved from local to remote
+ if (!ExecSVDRPCommand(NewTimer->Remote(), cString::sprintf("NEWT %s", *NewTimer->ToText(true)), &Response) || SVDRPCode(Response[0]) != 250)
+ return RemoteTimerError(NewTimer, Msg);
+ int RemoteId = atoi(SVDRPValue(Response[0]));
+ if (RemoteId <= 0)
+ return RemoteTimerError(NewTimer, Msg);
+ NewTimer->SetId(RemoteId);
+ if (OldTimer && OldTimer->Id()) {
+ isyslog("moved timer %d to %s", OldTimer->Id(), *NewTimer->ToDescr());
+ }
+ else
+ isyslog("added timer %s", *NewTimer->ToDescr());
+ }
+ }
+ else if (NewTimer->Local()) { // timer is moved from remote to local
+ if (!ExecSVDRPCommand(OldTimer->Remote(), cString::sprintf("DELT %d", OldTimer->Id()), &Response) || SVDRPCode(Response[0]) != 250)
+ return RemoteTimerError(OldTimer, Msg);
+ NewTimer->SetId(cTimers::NewTimerId());
+ NewTimer->ClrFlags(tfRecording); // in case it was recording on the remote machine
+ isyslog("moved timer %d@%s to %s", OldTimer->Id(), OldTimer->Remote(), *NewTimer->ToDescr());
+ }
+ else if (strcmp(OldTimer->Remote(), NewTimer->Remote()) == 0) { // timer stays remote on same machine
+ if (!ExecSVDRPCommand(OldTimer->Remote(), cString::sprintf("MODT %d %s", OldTimer->Id(), *NewTimer->ToText(true)), &Response) || SVDRPCode(Response[0]) != 250)
+ return RemoteTimerError(NewTimer, Msg);
+ isyslog("modified timer %s", *NewTimer->ToDescr());
+ }
+ else { // timer is moved from one remote machine to an other
+ if (!ExecSVDRPCommand(NewTimer->Remote(), cString::sprintf("NEWT %s", *NewTimer->ToText(true)), &Response) || SVDRPCode(Response[0]) != 250)
+ return RemoteTimerError(NewTimer, Msg);
+ int RemoteId = atoi(SVDRPValue(Response[0]));
+ if (RemoteId <= 0)
+ return RemoteTimerError(NewTimer, Msg);
+ NewTimer->SetId(RemoteId);
+ if (!ExecSVDRPCommand(OldTimer->Remote(), cString::sprintf("DELT %d", OldTimer->Id()), &Response) || SVDRPCode(Response[0]) != 250)
+ return RemoteTimerError(OldTimer, Msg);
+ isyslog("moved timer %d@%s to %s", OldTimer->Id(), OldTimer->Remote(), *NewTimer->ToDescr());
+ }
+ return true;
+}
+
// --- cSortedTimers ---------------------------------------------------------
static int CompareTimers(const void *a, const void *b)
diff --git a/timers.h b/timers.h
index 7ee116c8..1bffa84f 100644
--- a/timers.h
+++ b/timers.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.h 4.6 2016/12/23 09:49:31 kls Exp $
+ * $Id: timers.h 4.7 2017/03/30 15:22:36 kls Exp $
*/
#ifndef __TIMERS_H
@@ -200,6 +200,22 @@ public:
///< known remote machines.
};
+bool HandleRemoteTimerModifications(cTimer *NewTimer, cTimer *OldTimer = NULL, cString *Msg = NULL);
+ ///< Performs any operations necessary to synchronize changes to a timer
+ ///< between peer VDR machines. OldTimer must point to the old version
+ ///< of the timer, while NewTimer points to the new version. If either
+ ///< of the two is a remote timer, the necessary SVDRP commands are executed
+ ///< to reflect the changes on the remote machine(s). If NewTimer is NULL,
+ ///< OldTimer will be removed from the remote machine (if applicable).
+ ///< If OldTimer is NULL, NewTimer will be added to the remote machine (if
+ ///< applicable). If anything goes wrong, an error message is generated in the
+ ///< optional Msg string, which should be presented to the user.
+ ///< Any necessary local operations (like adding/deleting the timer to the
+ ///< local list of timers etc.) must be done before and/or after the call to this
+ ///< function. Proper log messages will be generated by this function, even
+ ///< if no remote operations are required.
+ ///< Returns true if successful.
+
// Provide lock controlled access to the list:
DEF_LIST_LOCK(Timers);