Streamdev-server compatibility with VDR 2.3.1 (fixes #2249)

This commit is contained in:
Frank Schmirler
2016-03-21 00:28:02 +01:00
parent d66c635a80
commit 674bb5b331
18 changed files with 538 additions and 4 deletions

View File

@@ -105,7 +105,11 @@ cComponentIGMP::~cComponentIGMP(void)
{
}
#if APIVERSNUM >= 20300
cMulticastGroup* cComponentIGMP::FindGroup(in_addr_t Group)
#else
cMulticastGroup* cComponentIGMP::FindGroup(in_addr_t Group) const
#endif
{
cMulticastGroup *group = m_Groups.First();
while (group && group->group != Group)
@@ -117,7 +121,12 @@ bool cComponentIGMP::Initialize(void)
{
if (cServerComponent::Initialize() && IGMPMembership(IGMP_ALL_ROUTER))
{
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
for (const cChannel *channel = Channels->First(); channel; channel = Channels->Next(channel))
#else
for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel))
#endif
{
if (channel->GroupSep())
continue;
@@ -146,7 +155,12 @@ void cComponentIGMP::Destruct(void)
Cancel(-1);
m_CondWait.Signal();
Cancel(2);
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
for (const cChannel *channel = Channels->First(); channel; channel = Channels->Next(channel))
#else
for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel))
#endif
{
if (channel->GroupSep())
continue;
@@ -432,9 +446,18 @@ cServerConnection* cComponentIGMP::IGMPStartMulticast(cMulticastGroup* Group)
in_addr_t g = ntohl(Group->group);
if (g > MULTICAST_PRIV_MIN && g <= MULTICAST_PRIV_MAX) {
cThreadLock lock;
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(g - MULTICAST_PRIV_MIN);
#else
cChannel *channel = Channels.GetByNumber(g - MULTICAST_PRIV_MIN);
#endif
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#if APIVERSNUM >= 20300
const cServerConnection *s = clients.First();
#else
cServerConnection *s = clients.First();
#endif
while (s) {
if (s->RemoteIpAddr() == Group->group)
break;
@@ -453,7 +476,11 @@ cServerConnection* cComponentIGMP::IGMPStartMulticast(cMulticastGroup* Group)
void cComponentIGMP::IGMPStopMulticast(cMulticastGroup* Group)
{
cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) {
if (s->RemoteIpAddr() == Group->group)
s->Close();

View File

@@ -9,6 +9,7 @@
#include <time.h>
#include <vdr/thread.h>
#include "server/component.h"
#include "../common.h"
class cMulticastGroup;
@@ -23,7 +24,11 @@ private:
bool m_Querier;
cCondWait m_CondWait;
#if APIVERSNUM >= 20300
cMulticastGroup* FindGroup(in_addr_t Group);
#else
cMulticastGroup* FindGroup(in_addr_t Group) const;
#endif
/* Add or remove local host to multicast group */
bool IGMPMembership(in_addr_t Group, bool Add = true);

View File

@@ -46,14 +46,29 @@ const cChannel* cServerConnection::ChannelFromString(const char *String, int *Ap
int temp = strtol(String, NULL, 10);
if (temp == 0)
temp = cDevice::CurrentChannel();
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (temp >= 1 && temp <= Channels->MaxNumber())
channel = Channels->GetByNumber(temp);
#else
if (temp >= 1 && temp <= Channels.MaxNumber())
channel = Channels.GetByNumber(temp);
#endif
} else {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
channel = Channels->GetByChannelID(tChannelID::FromString(string));
#else
channel = Channels.GetByChannelID(tChannelID::FromString(string));
#endif
if (channel == NULL) {
int i = 1;
#if APIVERSNUM >= 20300
while ((channel = Channels->GetByNumber(i, 1)) != NULL) {
#else
while ((channel = Channels.GetByNumber(i, 1)) != NULL) {
#endif
if (String == channel->Name())
break;

View File

@@ -523,8 +523,13 @@ RecPlayer* cConnectionHTTP::RecPlayerFromString(const char *FileBase, const char
ino_t inode = (ino_t) strtoull(p + 1, &p, 0);
if (*p == 0 && inode > 0) {
struct stat st;
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
for (const cRecording *rec = Recordings->First(); rec; rec = Recordings->Next(rec)) {
#else
cThreadLock RecordingsLock(&Recordings);
for (cRecording *rec = Recordings.First(); rec; rec = Recordings.Next(rec)) {
#endif
if (stat(rec->FileName(), &st) == 0 && st.st_dev == (dev_t) l && st.st_ino == inode)
recPlayer = new RecPlayer(rec->FileName());
}
@@ -532,8 +537,13 @@ RecPlayer* cConnectionHTTP::RecPlayerFromString(const char *FileBase, const char
}
else if (*p == 0) {
// get recording by index
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
const cRecording *rec = Recordings->Get((int) l - 1);
#else
cThreadLock RecordingsLock(&Recordings);
cRecording *rec = Recordings.Get((int) l - 1);
#endif
if (rec)
recPlayer = new RecPlayer(rec->FileName());
}

View File

@@ -21,7 +21,11 @@ cConnectionIGMP::~cConnectionIGMP()
{
}
#if APIVERSNUM >= 20300
bool cConnectionIGMP::SetChannel(const cChannel *Channel, in_addr_t Dst)
#else
bool cConnectionIGMP::SetChannel(cChannel *Channel, in_addr_t Dst)
#endif
{
if (Channel) {
m_Channel = Channel;

View File

@@ -19,13 +19,21 @@ class cConnectionIGMP: public cServerConnection {
private:
int m_ClientPort;
eStreamType m_StreamType;
#if APIVERSNUM >= 20300
const cChannel *m_Channel;
#else
cChannel *m_Channel;
#endif
public:
cConnectionIGMP(const char* Name, int ClientPort, eStreamType StreamType);
virtual ~cConnectionIGMP();
#if APIVERSNUM >= 20300
bool SetChannel(const cChannel *Channel, in_addr_t Dst);
#else
bool SetChannel(cChannel *Channel, in_addr_t Dst);
#endif
virtual void Welcome(void);
virtual cString ToText(char Delimiter = ' ') const;

View File

@@ -58,8 +58,10 @@ public:
cLSTEHandler::cLSTEHandler(cConnectionVTP *Client, const char *Option):
m_Client(Client),
#if APIVERSNUM < 20300
m_SchedulesLock(new cSchedulesLock(false, 500)),
m_Schedules(cSchedules::Schedules(*m_SchedulesLock)),
#endif
m_Schedule(NULL),
m_Event(NULL),
m_Errno(0),
@@ -131,11 +133,20 @@ cLSTEHandler::cLSTEHandler(cConnectionVTP *Client, const char *Option):
break;
}
} else if (!m_Schedule) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
const cChannel* Channel = NULL;
if (isnumber(p))
Channel = Channels->GetByNumber(strtol(Option, NULL, 10));
else
Channel = Channels->GetByChannelID(tChannelID::FromString(
#else
cChannel* Channel = NULL;
if (isnumber(p))
Channel = Channels.GetByNumber(strtol(Option, NULL, 10));
else
Channel = Channels.GetByChannelID(tChannelID::FromString(
#endif
Option));
if (Channel) {
m_Schedule = m_Schedules->GetSchedule(Channel->GetChannelID());
@@ -215,7 +226,12 @@ bool cLSTEHandler::Next(bool &Last)
switch (m_State) {
case Channel:
if (m_Schedule != NULL) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByChannelID(m_Schedule->ChannelID(),
#else
cChannel *channel = Channels.GetByChannelID(m_Schedule->ChannelID(),
#endif
true);
if (channel != NULL) {
m_State = Event;
@@ -371,12 +387,21 @@ cLSTCHandler::cLSTCHandler(cConnectionVTP *Client, const char *Option):
m_Errno(0),
m_Traverse(false)
{
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (!Channels) {
#else
if (!Channels.Lock(false, 500)) {
#endif
m_Errno = 451;
m_Error = "Channels are being modified - try again";
} else if (*Option) {
if (isnumber(Option)) {
#if APIVERSNUM >= 20300
m_Channel = Channels->GetByNumber(strtol(Option, NULL, 10));
#else
m_Channel = Channels.GetByNumber(strtol(Option, NULL, 10));
#endif
if (m_Channel == NULL) {
m_Errno = 501;
m_Error = cString::sprintf("Channel \"%s\" not defined", Option);
@@ -386,21 +411,35 @@ cLSTCHandler::cLSTCHandler(cConnectionVTP *Client, const char *Option):
int i = 1;
m_Traverse = true;
m_Option = strdup(Option);
#if APIVERSNUM >= 20300
while (i <= Channels->MaxNumber()) {
m_Channel = Channels->GetByNumber(i, 1);
#else
while (i <= Channels.MaxNumber()) {
m_Channel = Channels.GetByNumber(i, 1);
#endif
if (strcasestr(m_Channel->Name(), Option) != NULL)
break;
i = m_Channel->Number() + 1;
}
#if APIVERSNUM >= 20300
if (i > Channels->MaxNumber()) {
#else
if (i > Channels.MaxNumber()) {
#endif
m_Errno = 501;
m_Error = cString::sprintf("Channel \"%s\" not defined", Option);
return;
}
}
#if APIVERSNUM >= 20300
} else if (Channels->MaxNumber() >= 1) {
m_Channel = Channels->GetByNumber(1, 1);
#else
} else if (Channels.MaxNumber() >= 1) {
m_Channel = Channels.GetByNumber(1, 1);
#endif
m_Traverse = true;
} else {
m_Errno = 550;
@@ -410,7 +449,9 @@ cLSTCHandler::cLSTCHandler(cConnectionVTP *Client, const char *Option):
cLSTCHandler::~cLSTCHandler()
{
#if APIVERSNUM < 20300
Channels.Unlock();
#endif
if (m_Option != NULL)
free(m_Option);
}
@@ -435,8 +476,14 @@ bool cLSTCHandler::Next(bool &Last)
Last = true;
if (m_Traverse) {
int i = m_Channel->Number() + 1;
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
while (i <= Channels->MaxNumber()) {
m_Channel = Channels->GetByNumber(i, 1);
#else
while (i <= Channels.MaxNumber()) {
m_Channel = Channels.GetByNumber(i, 1);
#endif
if (m_Channel != NULL) {
if (m_Option == NULL || strcasestr(m_Channel->Name(),
m_Option) != NULL)
@@ -448,7 +495,11 @@ bool cLSTCHandler::Next(bool &Last)
}
}
#if APIVERSNUM >= 20300
if (i < Channels->MaxNumber() + 1)
#else
if (i < Channels.MaxNumber() + 1)
#endif
Last = false;
}
@@ -461,7 +512,11 @@ class cLSTTHandler
{
private:
cConnectionVTP *m_Client;
#if APIVERSNUM >= 20300
const cTimer *m_Timer;
#else
cTimer *m_Timer;
#endif
int m_Index;
int m_Errno;
cString m_Error;
@@ -479,9 +534,16 @@ cLSTTHandler::cLSTTHandler(cConnectionVTP *Client, const char *Option):
m_Errno(0),
m_Traverse(false)
{
#if APIVERSNUM >= 20300
LOCK_TIMERS_READ;
#endif
if (*Option) {
if (isnumber(Option)) {
#if APIVERSNUM >= 20300
m_Timer = Timers->Get(strtol(Option, NULL, 10) - 1);
#else
m_Timer = Timers.Get(strtol(Option, NULL, 10) - 1);
#endif
if (m_Timer == NULL) {
m_Errno = 501;
m_Error = cString::sprintf("Timer \"%s\" not defined", Option);
@@ -490,10 +552,18 @@ cLSTTHandler::cLSTTHandler(cConnectionVTP *Client, const char *Option):
m_Errno = 501;
m_Error = cString::sprintf("Error in timer number \"%s\"", Option);
}
#if APIVERSNUM >= 20300
} else if (Timers->Count()) {
#else
} else if (Timers.Count()) {
#endif
m_Traverse = true;
m_Index = 0;
#if APIVERSNUM >= 20300
m_Timer = Timers->Get(m_Index);
#else
m_Timer = Timers.Get(m_Index);
#endif
if (m_Timer == NULL) {
m_Errno = 501;
m_Error = cString::sprintf("Timer \"%d\" not found", m_Index + 1);
@@ -519,7 +589,12 @@ bool cLSTTHandler::Next(bool &Last)
bool result;
char *buffer;
#if APIVERSNUM >= 20300
LOCK_TIMERS_READ;
Last = !m_Traverse || m_Index >= Timers->Count() - 1;
#else
Last = !m_Traverse || m_Index >= Timers.Count() - 1;
#endif
buffer = strdup(*m_Timer->ToText());
buffer[strlen(buffer) - 1] = '\0'; // strip \n
result = m_Client->Respond(Last ? 250 : -250, "%d %s", m_Timer->Index() + 1,
@@ -527,7 +602,11 @@ bool cLSTTHandler::Next(bool &Last)
free(buffer);
if (m_Traverse && !Last) {
#if APIVERSNUM >= 20300
m_Timer = Timers->Get(++m_Index);
#else
m_Timer = Timers.Get(++m_Index);
#endif
if (m_Timer == NULL) {
m_Errno = 501;
m_Error = cString::sprintf("Timer \"%d\" not found", m_Index + 1);
@@ -544,7 +623,11 @@ private:
enum eStates { Recording, Event, Title, Subtitle, Description, Components, Vps,
EndRecording };
cConnectionVTP *m_Client;
#if APIVERSNUM >= 20300
const cRecording *m_Recording;
#else
cRecording *m_Recording;
#endif
const cEvent *m_Event;
int m_Index;
int m_Errno;
@@ -570,9 +653,16 @@ cLSTRHandler::cLSTRHandler(cConnectionVTP *Client, const char *Option):
m_State(Recording),
m_CurrentComponent(0)
{
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
#endif
if (*Option) {
if (isnumber(Option)) {
#if APIVERSNUM >= 20300
m_Recording = Recordings->Get(strtol(Option, NULL, 10) - 1);
#else
m_Recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
#endif
m_Event = m_Recording->Info()->GetEvent();
m_Info = true;
if (m_Recording == NULL) {
@@ -585,10 +675,18 @@ cLSTRHandler::cLSTRHandler(cConnectionVTP *Client, const char *Option):
m_Error = cString::sprintf("Error in Recording number \"%s\"", Option);
}
}
#if APIVERSNUM >= 20300
else if (Recordings->Count()) {
#else
else if (Recordings.Count()) {
#endif
m_Traverse = true;
m_Index = 0;
#if APIVERSNUM >= 20300
m_Recording = Recordings->Get(m_Index);
#else
m_Recording = Recordings.Get(m_Index);
#endif
if (m_Recording == NULL) {
m_Errno = 501;
m_Error = cString::sprintf("Recording \"%d\" not found", m_Index + 1);
@@ -691,11 +789,20 @@ bool cLSTRHandler::Next(bool &Last)
}
else {
bool result;
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
Last = !m_Traverse || m_Index >= Recordings->Count() - 1;
#else
Last = !m_Traverse || m_Index >= Recordings.Count() - 1;
#endif
result = m_Client->Respond(Last ? 250 : -250, "%d %s", m_Recording->Index() + 1, m_Recording->Title(' ', true));
if (m_Traverse && !Last) {
#if APIVERSNUM >= 20300
m_Recording = Recordings->Get(++m_Index);
#else
m_Recording = Recordings.Get(++m_Index);
#endif
if (m_Recording == NULL) {
m_Errno = 501;
m_Error = cString::sprintf("Recording \"%d\" not found", m_Index + 1);
@@ -1145,7 +1252,12 @@ bool cConnectionVTP::CmdPLAY(char *Opts)
{
if (*Opts) {
if (isnumber(Opts)) {
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
const cRecording *recording = Recordings->Get(strtol(Opts, NULL, 10) - 1);
#else
cRecording *recording = Recordings.Get(strtol(Opts, NULL, 10) - 1);
#endif
if (recording) {
if (m_RecPlayer) {
delete m_RecPlayer;
@@ -1391,10 +1503,17 @@ bool cConnectionVTP::CmdSTAT(const char *Option)
Reply(250, "VDR: %s | Streamdev: %s", VDRVERSION, VERSION);
}
else if (strcasecmp(Option, "RECORDS") == 0) {
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_WRITE;
Recordings->Sort();
if (Recordings) {
cRecording *recording = Recordings->Last();
#else
bool recordings = Recordings.Load();
Recordings.Sort();
if (recordings) {
cRecording *recording = Recordings.Last();
#endif
Reply(250, "%d", recording->Index() + 1);
}
else {
@@ -1402,10 +1521,20 @@ bool cConnectionVTP::CmdSTAT(const char *Option)
}
}
else if (strcasecmp(Option, "CHANNELS") == 0) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
Reply(250, "%d", Channels->MaxNumber());
#else
Reply(250, "%d", Channels.MaxNumber());
#endif
}
else if (strcasecmp(Option, "TIMERS") == 0) {
#if APIVERSNUM >= 20300
LOCK_TIMERS_READ;
Reply(250, "%d", Timers->Count());
#else
Reply(250, "%d", Timers.Count());
#endif
}
else if (strcasecmp(Option, "CHARSET") == 0) {
Reply(250, "%s", cCharSetConv::SystemCharacterTable());
@@ -1433,7 +1562,12 @@ bool cConnectionVTP::CmdMODT(const char *Option)
int n = strtol(Option, &tail, 10);
if (tail && tail != Option) {
tail = skipspace(tail);
#if APIVERSNUM >= 20300
LOCK_TIMERS_WRITE;
cTimer *timer = Timers->Get(n - 1);
#else
cTimer *timer = Timers.Get(n - 1);
#endif
if (timer) {
cTimer t = *timer;
if (strcasecmp(tail, "ON") == 0)
@@ -1445,7 +1579,11 @@ bool cConnectionVTP::CmdMODT(const char *Option)
EXIT_WRAPPER();
}
*timer = t;
#if APIVERSNUM >= 20300
Timers->SetModified();
#else
Timers.SetModified();
#endif
isyslog("timer %s modified (%s)", *timer->ToDescr(),
timer->HasFlags(tfActive) ? "active" : "inactive");
Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
@@ -1464,10 +1602,18 @@ bool cConnectionVTP::CmdNEWT(const char *Option)
if (*Option) {
cTimer *timer = new cTimer;
if (timer->Parse(Option)) {
#if APIVERSNUM >= 20300
LOCK_TIMERS_WRITE;
cTimer *t = Timers->GetTimer(timer);
if (!t) {
Timers->Add(timer);
Timers->SetModified();
#else
cTimer *t = Timers.GetTimer(timer);
if (!t) {
Timers.Add(timer);
Timers.SetModified();
#endif
isyslog("timer %s added", *timer->ToDescr());
Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
EXIT_WRAPPER();
@@ -1512,21 +1658,39 @@ bool cConnectionVTP::CmdDELT(const char *Option)
}
}
#if APIVERSNUM >= 20300
LOCK_TIMERS_WRITE;
cTimer *Timer = Timers->Get(number);
if (Timer) {
if (Timer->Recording()) {
if (force) {
if (!Timer->Remote()) {
Timer->Skip();
cRecordControls::Process(Timers, time(NULL));
}
#else
cTimer *timer = Timers.Get(number);
if (timer) {
if (timer->Recording()) {
if (force) {
timer->Skip();
cRecordControls::Process(time(NULL));
#endif
}
else {
Reply(550, "Timer \"%i\" is recording", number);
EXIT_WRAPPER();
}
}
#if APIVERSNUM >= 20300
isyslog("deleting timer %s", *Timer->ToDescr());
Timers->Del(Timer);
Timers->SetModified();
#else
isyslog("deleting timer %s", *timer->ToDescr());
Timers.Del(timer);
Timers.SetModified();
#endif
Reply(250, "Timer \"%i\" deleted", number);
} else
Reply(501, "Timer \"%i\" not defined", number);
@@ -1538,7 +1702,12 @@ bool cConnectionVTP::CmdDELT(const char *Option)
bool cConnectionVTP::CmdNEXT(const char *Option)
{
INIT_WRAPPER();
#if APIVERSNUM >= 20300
LOCK_TIMERS_READ;
const cTimer *t = Timers->GetNextActiveTimer();
#else
cTimer *t = Timers.GetNextActiveTimer();
#endif
if (t) {
time_t Start = t->StartTime();
int Number = t->Index() + 1;
@@ -1562,12 +1731,23 @@ bool cConnectionVTP::CmdNEWC(const char *Option)
if (*Option) {
cChannel ch;
if (ch.Parse(Option)) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_WRITE;
if (Channels->HasUniqueChannelID(&ch)) {
#else
if (Channels.HasUniqueChannelID(&ch)) {
#endif
cChannel *channel = new cChannel;
*channel = ch;
#if APIVERSNUM >= 20300
Channels->Add(channel);
Channels->ReNumber();
Channels->SetModified();
#else
Channels.Add(channel);
Channels.ReNumber();
Channels.SetModified(true);
#endif
isyslog("new channel %d %s", channel->Number(), *channel->ToText());
Reply(250, "%d %s", channel->Number(), *channel->ToText());
}
@@ -1593,15 +1773,28 @@ bool cConnectionVTP::CmdMODC(const char *Option)
int n = strtol(Option, &tail, 10);
if (tail && tail != Option) {
tail = skipspace(tail);
#if APIVERSNUM >= 20300
LOCK_CHANNELS_WRITE;
Channels->SetExplicitModify();
cChannel *channel = Channels->GetByNumber(n);
#else
if (!Channels.BeingEdited()) {
cChannel *channel = Channels.GetByNumber(n);
#endif
if (channel) {
cChannel ch;
if (ch.Parse(tail)) {
#if APIVERSNUM >= 20300
if (Channels->HasUniqueChannelID(&ch, channel)) {
*channel = ch;
Channels->ReNumber();
Channels->SetModified();
#else
if (Channels.HasUniqueChannelID(&ch, channel)) {
*channel = ch;
Channels.ReNumber();
Channels.SetModified(true);
#endif
isyslog("modifed channel %d %s", channel->Number(), *channel->ToText());
Reply(250, "%d %s", channel->Number(), *channel->ToText());
}
@@ -1616,10 +1809,12 @@ bool cConnectionVTP::CmdMODC(const char *Option)
else {
Reply(501, "Channel \"%d\" not defined", n);
}
#if APIVERSNUM < 20300
}
else {
Reply(550, "Channels are being edited - try again later");
}
#endif
}
else {
Reply(501, "Error in channel number");
@@ -1635,7 +1830,14 @@ bool cConnectionVTP::CmdMOVC(const char *Option)
{
INIT_WRAPPER();
if (*Option) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_WRITE;
Channels->SetExplicitModify();
// LOCK_TIMERS_WRITE;
// Timers->SetExplicitModify();
#else
if (!Channels.BeingEdited() && !Timers.BeingEdited()) {
#endif
char *tail;
int From = strtol(Option, &tail, 10);
if (tail && tail != Option) {
@@ -1643,20 +1845,37 @@ bool cConnectionVTP::CmdMOVC(const char *Option)
if (tail && tail != Option) {
int To = strtol(tail, NULL, 10);
int CurrentChannelNr = cDevice::CurrentChannel();
#if APIVERSNUM >= 20300
cChannel *CurrentChannel = Channels->GetByNumber(CurrentChannelNr);
cChannel *FromChannel = Channels->GetByNumber(From);
if (FromChannel) {
cChannel *ToChannel = Channels->GetByNumber(To);
#else
cChannel *CurrentChannel = Channels.GetByNumber(CurrentChannelNr);
cChannel *FromChannel = Channels.GetByNumber(From);
if (FromChannel) {
cChannel *ToChannel = Channels.GetByNumber(To);
#endif
if (ToChannel) {
int FromNumber = FromChannel->Number();
int ToNumber = ToChannel->Number();
if (FromNumber != ToNumber) {
#if APIVERSNUM >= 20300
Channels->Move(FromChannel, ToChannel);
Channels->ReNumber();
Channels->SetModified();
#else
Channels.Move(FromChannel, ToChannel);
Channels.ReNumber();
Channels.SetModified(true);
#endif
if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) {
if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) {
#if APIVERSNUM >= 20300
Channels->SwitchTo(CurrentChannel->Number());
#else
Channels.SwitchTo(CurrentChannel->Number());
#endif
}
else {
cDevice::SetCurrentChannel(CurrentChannel);
@@ -1684,10 +1903,12 @@ bool cConnectionVTP::CmdMOVC(const char *Option)
else {
Reply(501, "Error in channel number");
}
#if APIVERSNUM < 20300
}
else {
Reply(550, "Channels or timers are being edited - try again later");
}
#endif
}
else {
Reply(501, "Missing channel number");
@@ -1700,31 +1921,63 @@ bool cConnectionVTP::CmdDELC(const char *Option)
INIT_WRAPPER();
if (*Option) {
if (isnumber(Option)) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_WRITE;
Channels->SetExplicitModify();
cChannel *channel = Channels->GetByNumber(strtol(Option, NULL, 10));
#else
if (!Channels.BeingEdited()) {
cChannel *channel = Channels.GetByNumber(strtol(Option, NULL, 10));
#endif
if (channel) {
#if APIVERSNUM >= 20300
LOCK_TIMERS_READ;
for (const cTimer *timer = Timers->First(); timer; timer = Timers->Next(timer)) {
#else
for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) {
#endif
if (timer->Channel() == channel) {
Reply(550, "Channel \"%s\" is in use by timer %d", Option, timer->Index() + 1);
return false;
}
}
int CurrentChannelNr = cDevice::CurrentChannel();
#if APIVERSNUM >= 20300
cChannel *CurrentChannel = Channels->GetByNumber(CurrentChannelNr);
#else
cChannel *CurrentChannel = Channels.GetByNumber(CurrentChannelNr);
#endif
if (CurrentChannel && channel == CurrentChannel) {
#if APIVERSNUM >= 20300
int n = Channels->GetNextNormal(CurrentChannel->Index());
if (n < 0)
n = Channels->GetPrevNormal(CurrentChannel->Index());
CurrentChannel = Channels->Get(n);
#else
int n = Channels.GetNextNormal(CurrentChannel->Index());
if (n < 0)
n = Channels.GetPrevNormal(CurrentChannel->Index());
CurrentChannel = Channels.Get(n);
#endif
CurrentChannelNr = 0; // triggers channel switch below
}
#if APIVERSNUM >= 20300
Channels->Del(channel);
Channels->ReNumber();
Channels->SetModified();
#else
Channels.Del(channel);
Channels.ReNumber();
Channels.SetModified(true);
#endif
isyslog("channel %s deleted", Option);
if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) {
if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring())
#if APIVERSNUM >= 20300
Channels->SwitchTo(CurrentChannel->Number());
#else
Channels.SwitchTo(CurrentChannel->Number());
#endif
else
cDevice::SetCurrentChannel(CurrentChannel);
}
@@ -1733,9 +1986,11 @@ bool cConnectionVTP::CmdDELC(const char *Option)
else
Reply(501, "Channel \"%s\" not defined", Option);
}
#if APIVERSNUM < 20300
else
Reply(550, "Channels are being edited - try again later");
}
#endif
else
Reply(501, "Error in channel number \"%s\"", Option);
}
@@ -1750,13 +2005,22 @@ bool cConnectionVTP::CmdDELR(const char *Option)
INIT_WRAPPER();
if (*Option) {
if (isnumber(Option)) {
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_WRITE;
cRecording *recording = Recordings->Get(strtol(Option, NULL, 10) - 1);
#else
cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
#endif
if (recording) {
cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
if (!rc) {
if (recording->Delete()) {
Reply(250, "Recording \"%s\" deleted", Option);
#if APIVERSNUM >= 20300
Recordings->DelByName(recording->FileName());
#else
::Recordings.DelByName(recording->FileName());
#endif
}
else
Reply(554, "Error while deleting recording!");
@@ -1765,7 +2029,11 @@ bool cConnectionVTP::CmdDELR(const char *Option)
Reply(550, "Recording \"%s\" is in use by timer %d", Option, rc->Timer()->Index() + 1);
}
else
#if APIVERSNUM >= 20300
Reply(550, "Recording \"%s\" not found%s", Option, Recordings->Count() ? "" : " (use LSTR before deleting)");
#else
Reply(550, "Recording \"%s\" not found%s", Option, Recordings.Count() ? "" : " (use LSTR before deleting)");
#endif
}
else
Reply(501, "Error in recording number \"%s\"", Option);

View File

@@ -31,7 +31,11 @@ private:
cStreamdevLiveStreamer *m_Streamer;
protected:
#if APIVERSNUM >= 20300
virtual void Receive(const uchar *Data, int Length);
#else
virtual void Receive(uchar *Data, int Length);
#endif
public:
cStreamdevLiveReceiver(cStreamdevLiveStreamer *Streamer, const cChannel *Channel, int Priority, const int *Pids);
@@ -53,7 +57,11 @@ cStreamdevLiveReceiver::~cStreamdevLiveReceiver()
Detach();
}
#if APIVERSNUM >= 20300
void cStreamdevLiveReceiver::Receive(const uchar *Data, int Length) {
#else
void cStreamdevLiveReceiver::Receive(uchar *Data, int Length) {
#endif
m_Streamer->Receive(Data, Length);
}
@@ -250,7 +258,12 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i
SI::PAT::Association assoc;
for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) {
if (!assoc.isNITPid()) {
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
const cChannel *Channel = Channels->GetByServiceID(Source(), Transponder(), assoc.getServiceId());
#else
const cChannel *Channel = Channels.GetByServiceID(Source(), Transponder(), assoc.getServiceId());
#endif
if (Channel && (Channel == m_Channel)) {
int prevPmtPid = pmtPid;
if (0 != (pmtPid = assoc.getPid())) {
@@ -547,7 +560,11 @@ bool cStreamdevLiveStreamer::SetChannel(eStreamType StreamType, const int* Apid,
}
}
#if APIVERSNUM >= 20300
void cStreamdevLiveStreamer::Receive(const uchar *Data, int Length)
#else
void cStreamdevLiveStreamer::Receive(uchar *Data, int Length)
#endif
{
int p = m_ReceiveBuffer->PutTS(Data, Length);
if (p != Length)
@@ -688,9 +705,16 @@ void cStreamdevLiveStreamer::MainThreadHook()
}
if (m_SwitchLive) {
// switched away live TV. Try previous channel on other device first
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (!Channels->SwitchTo(cDevice::CurrentChannel())) {
// switch to streamdev channel otherwise
Channels->SwitchTo(m_Channel->Number());
#else
if (!Channels.SwitchTo(cDevice::CurrentChannel())) {
// switch to streamdev channel otherwise
Channels.SwitchTo(m_Channel->Number());
#endif
Skins.Message(mtInfo, tr("Streaming active"));
}
if (m_Device)

View File

@@ -64,7 +64,11 @@ public:
void GetSignal(int *DevNum, int *Strength, int *Quality) const;
virtual cString ToText() const;
#if APIVERSNUM >= 20300
void Receive(const uchar *Data, int Length);
#else
void Receive(uchar *Data, int Length);
#endif
virtual bool IsReceiving(void) const;
virtual void Attach(void);

View File

@@ -13,7 +13,11 @@
cStreamdevServerMenu::cStreamdevServerMenu(): cOsdMenu(tr("Streamdev Connections"), 4, 20) {
cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
for (cServerConnection *s = clients.First(); s; s = clients.Next(s))
Add(new cOsdItem(s->ToText('\t')));
SetHelpKeys();
@@ -31,7 +35,11 @@ eOSState cStreamdevServerMenu::Disconnect() {
cOsdItem *item = Get(Current());
if (item) {
cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
const char *text = item->Text();
for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) {
if (!strcmp(text, s->ToText('\t'))) {

View File

@@ -6,10 +6,19 @@
#include "server/menuHTTP.h"
//**************************** cRecordingIterator **************
#if APIVERSNUM >= 20300
cRecordingsIterator::cRecordingsIterator(eStreamType StreamType)
#else
cRecordingsIterator::cRecordingsIterator(eStreamType StreamType): RecordingsLock(&Recordings)
#endif
{
streamType = StreamType;
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
first = NextSuitable(Recordings->First());
#else
first = NextSuitable(Recordings.First());
#endif
current = NULL;
}
@@ -20,20 +29,32 @@ const cRecording* cRecordingsIterator::NextSuitable(const cRecording *Recording)
bool isPes = Recording->IsPesRecording();
if (!isPes || (isPes && streamType == stPES))
break;
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
Recording = Recordings->Next(Recording);
#else
Recording = Recordings.Next(Recording);
#endif
}
return Recording;
}
bool cRecordingsIterator::Next()
{
#if APIVERSNUM >= 20300
LOCK_RECORDINGS_READ;
#endif
if (first)
{
current = first;
first = NULL;
}
else
#if APIVERSNUM >= 20300
current = NextSuitable(Recordings->Next(current));
#else
current = NextSuitable(Recordings.Next(current));
#endif
return current;
}
@@ -71,9 +92,16 @@ const cString cChannelIterator::ItemId() const
if (current->GroupSep())
{
int index = 0;
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
for (int curr = Channels->GetNextGroup(-1); curr >= 0; curr = Channels->GetNextGroup(curr))
{
if (Channels->Get(curr) == current)
#else
for (int curr = Channels.GetNextGroup(-1); curr >= 0; curr = Channels.GetNextGroup(curr))
{
if (Channels.Get(curr) == current)
#endif
return itoa(index);
index++;
}
@@ -89,47 +117,111 @@ const cString cChannelIterator::ItemId() const
const cChannel* cChannelIterator::GetGroup(const char* GroupId)
{
int group = -1;
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
#endif
if (GroupId)
{
int Index = atoi(GroupId);
#if APIVERSNUM >= 20300
group = Channels->GetNextGroup(-1);
while (Index-- && group >= 0)
group = Channels->GetNextGroup(group);
}
return group >= 0 ? Channels->Get(group) : NULL;
#else
group = Channels.GetNextGroup(-1);
while (Index-- && group >= 0)
group = Channels.GetNextGroup(group);
}
return group >= 0 ? Channels.Get(group) : NULL;
#endif
}
const cChannel* cChannelIterator::FirstChannel()
{
const cChannel *Channel;
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
Channel = Channels->First();
#else
Channel = Channels.First();
#endif
return Channel;
}
const cChannel* cChannelIterator::NextNormal()
{
const cChannel *Channel;
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
Channel = Channels->Get(Channels->GetNextNormal(-1));
#else
Channel = Channels.Get(Channels.GetNextNormal(-1));
#endif
return Channel;
}
const cChannel* cChannelIterator::NextGroup()
{
const cChannel *Channel;
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
Channel = Channels->Get(Channels->GetNextGroup(-1));
#else
Channel = Channels.Get(Channels.GetNextGroup(-1));
#endif
return Channel;
}
//**************************** cListAll **************
cListAll::cListAll(): cChannelIterator(Channels.First())
cListAll::cListAll(): cChannelIterator(FirstChannel())
{}
const cChannel* cListAll::NextChannel(const cChannel *Channel)
{
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = SkipFakeGroups(Channels->Next(Channel));
#else
if (Channel)
Channel = SkipFakeGroups(Channels.Next(Channel));
#endif
return Channel;
}
//**************************** cListChannels **************
cListChannels::cListChannels(): cChannelIterator(Channels.Get(Channels.GetNextNormal(-1)))
cListChannels::cListChannels(): cChannelIterator(NextNormal())
{}
const cChannel* cListChannels::NextChannel(const cChannel *Channel)
{
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = Channels->Get(Channels->GetNextNormal(Channel->Index()));
#else
if (Channel)
Channel = Channels.Get(Channels.GetNextNormal(Channel->Index()));
#endif
return Channel;
}
// ********************* cListGroups ****************
cListGroups::cListGroups(): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1)))
cListGroups::cListGroups(): cChannelIterator(NextGroup())
{}
const cChannel* cListGroups::NextChannel(const cChannel *Channel)
{
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = Channels->Get(Channels->GetNextGroup(Channel->Index()));
#else
if (Channel)
Channel = Channels.Get(Channels.GetNextGroup(Channel->Index()));
#endif
return Channel;
}
//
@@ -139,8 +231,14 @@ cListGroup::cListGroup(const char *GroupId): cChannelIterator(GetNextChannelInGr
const cChannel* cListGroup::GetNextChannelInGroup(const cChannel *Channel)
{
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = SkipFakeGroups(Channels->Next(Channel));
#else
if (Channel)
Channel = SkipFakeGroups(Channels.Next(Channel));
#endif
return Channel && !Channel->GroupSep() ? Channel : NULL;
}
@@ -150,25 +248,42 @@ const cChannel* cListGroup::NextChannel(const cChannel *Channel)
}
//
// ********************* cListTree ****************
cListTree::cListTree(const char *SelectedGroupId): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1)))
cListTree::cListTree(const char *SelectedGroupId): cChannelIterator(NextGroup())
{
selectedGroup = GetGroup(SelectedGroupId);
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
currentGroup = Channels->Get(Channels->GetNextGroup(-1));
#else
currentGroup = Channels.Get(Channels.GetNextGroup(-1));
#endif
}
const cChannel* cListTree::NextChannel(const cChannel *Channel)
{
if (currentGroup == selectedGroup)
{
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = SkipFakeGroups(Channels->Next(Channel));
#else
if (Channel)
Channel = SkipFakeGroups(Channels.Next(Channel));
#endif
if (Channel && Channel->GroupSep())
currentGroup = Channel;
}
else
{
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
if (Channel)
Channel = Channels->Get(Channels->GetNextGroup(Channel->Index()));
#else
if (Channel)
Channel = Channels.Get(Channels.GetNextGroup(Channel->Index()));
#endif
currentGroup = Channel;
}
return Channel;

View File

@@ -48,6 +48,9 @@ class cChannelIterator: public cItemIterator
const cChannel *first;
const cChannel *current;
protected:
virtual const cChannel* FirstChannel();
virtual const cChannel* NextNormal();
virtual const cChannel* NextGroup();
virtual const cChannel* NextChannel(const cChannel *Channel) = 0;
static inline const cChannel* SkipFakeGroups(const cChannel *Channel);
// Helper which returns the group by its index
@@ -208,8 +211,15 @@ class cRssMenuList: public cMenuList
inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group)
{
#if APIVERSNUM >= 20300
LOCK_CHANNELS_READ;
#endif
while (Group && Group->GroupSep() && !*Group->Name())
#if APIVERSNUM >= 20300
Group = Channels->Next(Group);
#else
Group = Channels.Next(Group);
#endif
return Group;
}

View File

@@ -177,7 +177,11 @@ void cStreamdevServer::Action(void)
}
}
#if APIVERSNUM >= 20300
cList<cServerConnection>& cStreamdevServer::Clients(cThreadLock& Lock)
#else
const cList<cServerConnection>& cStreamdevServer::Clients(cThreadLock& Lock)
#endif
{
Lock.Lock(m_Instance);
return m_Clients;

View File

@@ -37,7 +37,11 @@ public:
static void Destruct(void);
static bool Active(void);
#if APIVERSNUM >= 20300
static cList<cServerConnection>& Clients(cThreadLock& Lock);
#else
static const cList<cServerConnection>& Clients(cThreadLock& Lock);
#endif
};
inline bool cStreamdevServer::Active(void)

View File

@@ -21,7 +21,11 @@
cList<cMainThreadHookSubscriber> cMainThreadHookSubscriber::m_Subscribers;
cMutex cMainThreadHookSubscriber::m_Mutex;
#if APIVERSNUM >= 20300
cList<cMainThreadHookSubscriber>& cMainThreadHookSubscriber::Subscribers(cMutexLock& Lock)
#else
const cList<cMainThreadHookSubscriber>& cMainThreadHookSubscriber::Subscribers(cMutexLock& Lock)
#endif
{
Lock.Lock(&m_Mutex);
return m_Subscribers;
@@ -163,7 +167,11 @@ void cPluginStreamdevServer::MainThreadHook(void)
}
cMutexLock lock;
#if APIVERSNUM >= 20300
cList<cMainThreadHookSubscriber>& subs = cMainThreadHookSubscriber::Subscribers(lock);
#else
const cList<cMainThreadHookSubscriber>& subs = cMainThreadHookSubscriber::Subscribers(lock);
#endif
for (cMainThreadHookSubscriber *s = subs.First(); s; s = subs.Next(s))
s->MainThreadHook();
}
@@ -199,7 +207,11 @@ cString cPluginStreamdevServer::SVDRPCommand(const char *Command, const char *Op
{
reply = "";
cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
cServerConnection *s = clients.First();
if (!s)
{
@@ -223,7 +235,11 @@ cString cPluginStreamdevServer::SVDRPCommand(const char *Command, const char *Op
} else
{
cThreadLock lock;
#if APIVERSNUM >= 20300
cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#else
const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
#endif
cServerConnection *s = clients.First();
for (; s && s != client; s = clients.Next(s));

View File

@@ -15,7 +15,11 @@ private:
static cList<cMainThreadHookSubscriber> m_Subscribers;
static cMutex m_Mutex;
public:
#if APIVERSNUM >= 20300
static cList<cMainThreadHookSubscriber>& Subscribers(cMutexLock& Lock);
#else
static const cList<cMainThreadHookSubscriber>& Subscribers(cMutexLock& Lock);
#endif
virtual void MainThreadHook() = 0;