mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 11:37:42 +00:00
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
8184a785b7 | ||
|
1b4094696a | ||
|
4139e87f4a | ||
|
7196c9403b | ||
|
e1c896c1a6 | ||
|
6b63ad145f | ||
|
84dfc6701e | ||
|
653d9d659b | ||
|
26cd34f965 | ||
|
df258d127f | ||
|
3e4b1c0383 | ||
|
73ed299ed9 | ||
|
37e151b3e3 | ||
|
b1aad3fb80 | ||
|
a87dfc43f7 | ||
|
26be862d89 | ||
|
ab2a47e3e7 | ||
|
3d1efe7a80 | ||
|
c9898bfbfd |
12
HISTORY
12
HISTORY
@@ -108,3 +108,15 @@ VDR Plugin 'satip' Revision History
|
||||
- Updated Spanish and Catalan translations (Thanks to
|
||||
Gabriel Bonich).
|
||||
- Updated German translations (Thanks to Frank Neumann).
|
||||
|
||||
|
||||
===================================
|
||||
VDR Plugin 'satip' Revision History
|
||||
===================================
|
||||
|
||||
2015-02-19: Version 2.2.0
|
||||
|
||||
- Updated for vdr-2.2.0.
|
||||
- Fixed memory deallocation errors.
|
||||
- Cleaned up all scan-build warnings.
|
||||
- Refactored the frontend handling.
|
||||
|
8
README
8
README
@@ -26,10 +26,6 @@ Requirements:
|
||||
- Glibc >= 2.12 - the GNU C library (recvmmsg)
|
||||
http://www.gnu.org/software/libc/
|
||||
|
||||
- VDR >= 2.1.4 for scrambled channels
|
||||
|
||||
- VDR >= 2.1.7 for external CI
|
||||
|
||||
Description:
|
||||
|
||||
This plugin integrates SAT>IP network devices seamlessly into VDR.
|
||||
@@ -136,8 +132,8 @@ Notes:
|
||||
your setup doesn't have firewalled the UDP port 1900.
|
||||
|
||||
- Stream decryption requires a separate CAM plugin that works without
|
||||
direct access to any DVB card devices. The integrated CAM slot in
|
||||
Octopus Net devices isn't supported.
|
||||
direct access to any DVB card devices. Also the integrated CAM slots
|
||||
in Octopus Net devices are supported.
|
||||
|
||||
- Tracing can be set on/off dynamically via command-line switch or
|
||||
SVDRP command.
|
||||
|
14
device.c
14
device.c
@@ -328,20 +328,19 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
|
||||
return false;
|
||||
}
|
||||
cString address;
|
||||
cSatipServer *server = cSatipDiscover::GetInstance()->GetServer(channelP->Source(), channelP->Transponder(), dtp.System());
|
||||
cSatipServer *server = cSatipDiscover::GetInstance()->AssignServer(deviceIndexM, channelP->Source(), channelP->Transponder(), dtp.System());
|
||||
if (!server) {
|
||||
debug9("%s No suitable server found [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||
return false;
|
||||
}
|
||||
cSatipDiscover::GetInstance()->SetTransponder(server, channelP->Transponder());
|
||||
if (pTunerM && pTunerM->SetSource(server, *params, deviceIndexM)) {
|
||||
if (pTunerM && pTunerM->SetSource(server, channelP->Transponder(), *params, deviceIndexM)) {
|
||||
channelM = *channelP;
|
||||
deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (pTunerM) {
|
||||
pTunerM->SetSource(NULL, NULL, deviceIndexM);
|
||||
pTunerM->SetSource(NULL, 0, NULL, deviceIndexM);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -434,10 +433,7 @@ int cSatipDevice::GetId(void)
|
||||
|
||||
int cSatipDevice::GetPmtPid(void)
|
||||
{
|
||||
int pid = 0;
|
||||
#if defined(APIVERSNUM) && APIVERSNUM >= 20107
|
||||
pid = channelM.Ca() ? ::GetPmtPid(channelM.Source(), channelM.Transponder(), channelM.Sid()) : 0;
|
||||
#endif
|
||||
int pid = channelM.Ca() ? ::GetPmtPid(channelM.Source(), channelM.Transponder(), channelM.Sid()) : 0;
|
||||
debug11("%s pmtpid=%d source=%c transponder=%d sid=%d name=%s [device %u]", __PRETTY_FUNCTION__, pid, cSource::ToChar(channelM.Source()), channelM.Transponder(), channelM.Sid(), channelM.Name(), deviceIndexM);
|
||||
return pid;
|
||||
}
|
||||
@@ -506,7 +502,6 @@ bool cSatipDevice::GetTSPacket(uchar *&dataP)
|
||||
{
|
||||
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||
if (tsBufferM) {
|
||||
#if defined(APIVERSNUM) && APIVERSNUM >= 20104
|
||||
if (cCamSlot *cs = CamSlot()) {
|
||||
if (cs->WantsTsData()) {
|
||||
int available;
|
||||
@@ -518,7 +513,6 @@ bool cSatipDevice::GetTSPacket(uchar *&dataP)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
dataP = GetData();
|
||||
return true;
|
||||
}
|
||||
|
52
discover.c
52
discover.c
@@ -233,7 +233,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char
|
||||
{
|
||||
debug1("%s (%s, %s, %s)", __PRETTY_FUNCTION__, addrP, modelP, descP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
if (SatipConfig.GetUseSingleModelServers()) {
|
||||
if (SatipConfig.GetUseSingleModelServers() && modelP && !isempty(modelP)) {
|
||||
int n = 0;
|
||||
char *s, *p = strdup(modelP);
|
||||
char *r = strtok_r(p, ",", &s);
|
||||
@@ -242,7 +242,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char
|
||||
cString desc = cString::sprintf("%s #%d", !isempty(descP) ? descP : "MyBrokenHardware", n++);
|
||||
cSatipServer *tmp = new cSatipServer(addrP, r, desc);
|
||||
if (!serversM.Update(tmp)) {
|
||||
info("Adding server '%s|%s|%s'", tmp->Address(), tmp->Model(), tmp->Description());
|
||||
info("Adding server '%s|%s|%s' CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
|
||||
serversM.Add(tmp);
|
||||
}
|
||||
else
|
||||
@@ -254,7 +254,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char
|
||||
else {
|
||||
cSatipServer *tmp = new cSatipServer(addrP, modelP, descP);
|
||||
if (!serversM.Update(tmp)) {
|
||||
info("Adding server '%s|%s|%s'", tmp->Address(), tmp->Model(), tmp->Description());
|
||||
info("Adding server '%s|%s|%s' CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
|
||||
serversM.Add(tmp);
|
||||
}
|
||||
else
|
||||
@@ -269,11 +269,18 @@ int cSatipDiscover::GetServerCount(void)
|
||||
return serversM.Count();
|
||||
}
|
||||
|
||||
cSatipServer *cSatipDiscover::GetServer(int sourceP, int transponderP, int systemP)
|
||||
cSatipServer *cSatipDiscover::AssignServer(int deviceIdP, int sourceP, int transponderP, int systemP)
|
||||
{
|
||||
debug16("%s (%d, %d, %d)", __PRETTY_FUNCTION__, sourceP, transponderP, systemP);
|
||||
debug16("%s (%d, %d, %d, %d)", __PRETTY_FUNCTION__, deviceIdP, sourceP, transponderP, systemP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
return serversM.Find(sourceP, transponderP, systemP);
|
||||
return serversM.Assign(deviceIdP, sourceP, transponderP, systemP);
|
||||
}
|
||||
|
||||
cSatipServer *cSatipDiscover::GetServer(int sourceP)
|
||||
{
|
||||
debug16("%s (%d)", __PRETTY_FUNCTION__, sourceP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
return serversM.Find(sourceP);
|
||||
}
|
||||
|
||||
cSatipServer *cSatipDiscover::GetServer(cSatipServer *serverP)
|
||||
@@ -304,18 +311,39 @@ cString cSatipDiscover::GetServerList(void)
|
||||
return serversM.List();
|
||||
}
|
||||
|
||||
void cSatipDiscover::SetTransponder(cSatipServer *serverP, int transponderP)
|
||||
void cSatipDiscover::AttachServer(cSatipServer *serverP, int deviceIdP, int transponderP)
|
||||
{
|
||||
debug16("%s (, %d)", __PRETTY_FUNCTION__, transponderP);
|
||||
debug16("%s (, %d, %d)", __PRETTY_FUNCTION__, deviceIdP, transponderP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
serversM.SetTransponder(serverP, transponderP);
|
||||
serversM.Attach(serverP, deviceIdP, transponderP);
|
||||
}
|
||||
|
||||
void cSatipDiscover::UseServer(cSatipServer *serverP, bool onOffP)
|
||||
void cSatipDiscover::DetachServer(cSatipServer *serverP, int deviceIdP, int transponderP)
|
||||
{
|
||||
debug16("%s (, %d)", __PRETTY_FUNCTION__, onOffP);
|
||||
debug16("%s (, %d, %d)", __PRETTY_FUNCTION__, deviceIdP, transponderP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
serversM.Use(serverP, onOffP);
|
||||
serversM.Detach(serverP, deviceIdP, transponderP);
|
||||
}
|
||||
|
||||
bool cSatipDiscover::IsServerQuirk(cSatipServer *serverP, int quirkP)
|
||||
{
|
||||
debug16("%s (, %d)", __PRETTY_FUNCTION__, quirkP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
return serversM.IsQuirk(serverP, quirkP);
|
||||
}
|
||||
|
||||
bool cSatipDiscover::HasServerCI(cSatipServer *serverP)
|
||||
{
|
||||
debug16("%s", __PRETTY_FUNCTION__);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
return serversM.HasCI(serverP);
|
||||
}
|
||||
|
||||
cString cSatipDiscover::GetServerAddress(cSatipServer *serverP)
|
||||
{
|
||||
debug16("%s", __PRETTY_FUNCTION__);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
return serversM.GetAddress(serverP);
|
||||
}
|
||||
|
||||
int cSatipDiscover::NumProvidedSystems(void)
|
||||
|
10
discover.h
10
discover.h
@@ -74,12 +74,16 @@ public:
|
||||
virtual ~cSatipDiscover();
|
||||
void TriggerScan(void) { probeIntervalM.Set(0); }
|
||||
int GetServerCount(void);
|
||||
cSatipServer *GetServer(int sourceP, int transponderP = 0, int systemP = -1);
|
||||
cSatipServer *AssignServer(int deviceIdP, int sourceP, int transponderP, int systemP);
|
||||
cSatipServer *GetServer(int sourceP);
|
||||
cSatipServer *GetServer(cSatipServer *serverP);
|
||||
cSatipServers *GetServers(void);
|
||||
cString GetServerString(cSatipServer *serverP);
|
||||
void SetTransponder(cSatipServer *serverP, int transponderP);
|
||||
void UseServer(cSatipServer *serverP, bool onOffP);
|
||||
void AttachServer(cSatipServer *serverP, int deviceIdP, int transponderP);
|
||||
void DetachServer(cSatipServer *serverP, int deviceIdP, int transponderP);
|
||||
bool IsServerQuirk(cSatipServer *serverP, int quirkP);
|
||||
bool HasServerCI(cSatipServer *serverP);
|
||||
cString GetServerAddress(cSatipServer *serverP);
|
||||
cString GetServerList(void);
|
||||
int NumProvidedSystems(void);
|
||||
|
||||
|
@@ -35,6 +35,7 @@ cSatipMsearch::cSatipMsearch(cSatipDiscoverIf &discoverP)
|
||||
|
||||
cSatipMsearch::~cSatipMsearch()
|
||||
{
|
||||
FREE_POINTER(bufferM);
|
||||
}
|
||||
|
||||
void cSatipMsearch::Probe(void)
|
||||
@@ -93,8 +94,6 @@ void cSatipMsearch::Process(void)
|
||||
r = strtok_r(NULL, "\r\n", &s);
|
||||
}
|
||||
}
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
error("Error %d reading in %s", errno, *ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
8
param.c
8
param.c
@@ -147,15 +147,9 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
|
||||
cDvbTransponderParameters dtp(channelP->Parameters());
|
||||
int DataSlice = 0;
|
||||
int C2TuningFrequencyType = 0;
|
||||
#if defined(APIVERSNUM) && APIVERSNUM < 20106
|
||||
int Pilot = PILOT_AUTO;
|
||||
int T2SystemId = 0;
|
||||
int SisoMiso = 0;
|
||||
#else
|
||||
int Pilot = dtp.Pilot();
|
||||
int T2SystemId = dtp.T2SystemId();
|
||||
int SisoMiso = dtp.SisoMiso();
|
||||
#endif
|
||||
float freq = channelP->Frequency();
|
||||
char type = cSource::ToChar(channelP->Source());
|
||||
cSource *source = Sources.Get(channelP->Source());
|
||||
@@ -192,7 +186,7 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
|
||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesTerrestrial);
|
||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Transmission(), SatipTransmissionValues);
|
||||
if ((channelP->Rid() % 100) > 0)
|
||||
q += snprintf(q, STBUFLEFT, "&fe=%d", channelP->Rid() % 100);
|
||||
snprintf(q, STBUFLEFT, "&fe=%d", channelP->Rid() % 100);
|
||||
#undef ST
|
||||
return buffer;
|
||||
}
|
||||
|
@@ -5,10 +5,10 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 1.0.2\n"
|
||||
"Project-Id-Version: vdr-satip 2.2.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
|
||||
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
|
||||
"POT-Creation-Date: 2015-02-19 02:19+0200\n"
|
||||
"PO-Revision-Date: 2015-02-19 02:19+0200\n"
|
||||
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
||||
"Language-Team: Catalan <vdr@linuxtv.org>\n"
|
||||
"Language: ca\n"
|
||||
|
@@ -5,10 +5,10 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 1.0.2\n"
|
||||
"Project-Id-Version: vdr-satip 2.2.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
|
||||
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
|
||||
"POT-Creation-Date: 2015-02-19 02:19+0200\n"
|
||||
"PO-Revision-Date: 2015-02-19 02:19+0200\n"
|
||||
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
|
||||
"Language-Team: German <vdr@linuxtv.org>\n"
|
||||
"Language: de\n"
|
||||
|
@@ -5,10 +5,10 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 1.0.2\n"
|
||||
"Project-Id-Version: vdr-satip 2.2.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
|
||||
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
|
||||
"POT-Creation-Date: 2015-02-19 02:19+0200\n"
|
||||
"PO-Revision-Date: 2015-02-19 02:19+0200\n"
|
||||
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
||||
"Language-Team: Spanish <vdr@linuxtv.org>\n"
|
||||
"Language: es\n"
|
||||
|
@@ -5,10 +5,10 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 1.0.2\n"
|
||||
"Project-Id-Version: vdr-satip 2.2.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
|
||||
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
|
||||
"POT-Creation-Date: 2015-02-19 02:19+0200\n"
|
||||
"PO-Revision-Date: 2015-02-19 02:19+0200\n"
|
||||
"Last-Translator: Rolf Ahrenberg\n"
|
||||
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
||||
"Language: fi\n"
|
||||
|
4
rtcp.c
4
rtcp.c
@@ -25,7 +25,7 @@ cSatipRtcp::cSatipRtcp(cSatipTunerIf &tunerP)
|
||||
cSatipRtcp::~cSatipRtcp()
|
||||
{
|
||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
||||
DELETE_POINTER(bufferM);
|
||||
FREE_POINTER(bufferM);
|
||||
}
|
||||
|
||||
int cSatipRtcp::GetFd(void)
|
||||
@@ -89,8 +89,6 @@ void cSatipRtcp::Process(void)
|
||||
if (offset >= 0)
|
||||
tunerM.ProcessApplicationData(bufferM + offset, length);
|
||||
}
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
error("Error %d reading in %s", errno, *ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
5
rtp.c
5
rtp.c
@@ -29,7 +29,7 @@ cSatipRtp::cSatipRtp(cSatipTunerIf &tunerP)
|
||||
cSatipRtp::~cSatipRtp()
|
||||
{
|
||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
||||
DELETE_POINTER(bufferM);
|
||||
FREE_POINTER(bufferM);
|
||||
}
|
||||
|
||||
int cSatipRtp::GetFd(void)
|
||||
@@ -136,9 +136,6 @@ void cSatipRtp::Process(void)
|
||||
}
|
||||
} while (count >= eRtpPacketReadCount);
|
||||
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
error("Error %d reading in %s [device %d]", errno, *ToString(), tunerM.GetId());
|
||||
|
||||
elapsed = processing.Elapsed();
|
||||
if (elapsed > 1)
|
||||
debug6("%s %d read(s) took %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, count, elapsed, tunerM.GetId());
|
||||
|
8
satip.c
8
satip.c
@@ -19,15 +19,15 @@
|
||||
#warning "CURL version >= 7.36.0 is recommended"
|
||||
#endif
|
||||
|
||||
#if defined(APIVERSNUM) && APIVERSNUM < 20000
|
||||
#error "VDR-2.0.0 API version or greater is required!"
|
||||
#if defined(APIVERSNUM) && APIVERSNUM < 20200
|
||||
#error "VDR-2.2.0 API version or greater is required!"
|
||||
#endif
|
||||
|
||||
#ifndef GITVERSION
|
||||
#define GITVERSION ""
|
||||
#endif
|
||||
|
||||
const char VERSION[] = "1.0.2" GITVERSION;
|
||||
const char VERSION[] = "2.2.0" GITVERSION;
|
||||
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
||||
|
||||
class cPluginSatip : public cPlugin {
|
||||
@@ -84,7 +84,7 @@ const char *cPluginSatip::CommandLineHelp(void)
|
||||
return " -d <num>, --devices=<number> set number of devices to be created\n"
|
||||
" -t <mode>, --trace=<mode> set the tracing mode\n"
|
||||
" -s <ipaddr>|<model>|<desc>, --server=<ipaddr1>|<model1>|<desc1>;<ipaddr2>|<model2>|<desc2>\n"
|
||||
" define hard-coded SAT>IP server(s)"
|
||||
" define hard-coded SAT>IP server(s)\n"
|
||||
" -S, --single set the single model server mode on\n"
|
||||
" -n, --noquirks disable all the server quirks\n";
|
||||
}
|
||||
|
342
server.c
342
server.c
@@ -12,73 +12,140 @@
|
||||
#include "log.h"
|
||||
#include "server.h"
|
||||
|
||||
// --- cSatipFrontend ---------------------------------------------------------
|
||||
|
||||
cSatipFrontend::cSatipFrontend(const int indexP, const char *descriptionP)
|
||||
: indexM(indexP),
|
||||
transponderM(0),
|
||||
deviceIdM(-1),
|
||||
descriptionM(descriptionP)
|
||||
{
|
||||
}
|
||||
|
||||
cSatipFrontend::~cSatipFrontend()
|
||||
{
|
||||
}
|
||||
|
||||
// --- cSatipFrontends --------------------------------------------------------
|
||||
|
||||
bool cSatipFrontends::Matches(int deviceIdP, int transponderP)
|
||||
{
|
||||
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||
if (f->Attached() && (f->DeviceId() == deviceIdP) && (f->Transponder() == transponderP))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cSatipFrontends::Assign(int deviceIdP, int transponderP)
|
||||
{
|
||||
cSatipFrontend *tmp = NULL;
|
||||
// Prefer any unused one
|
||||
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||
if (!f->Attached() || (f->DeviceId() == deviceIdP)) {
|
||||
tmp = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tmp) {
|
||||
tmp->SetTransponder(transponderP);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cSatipFrontends::Attach(int deviceIdP, int transponderP)
|
||||
{
|
||||
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||
if (f->Transponder() == transponderP) {
|
||||
f->Attach(deviceIdP);
|
||||
debug9("%s (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cSatipFrontends::Detach(int deviceIdP, int transponderP)
|
||||
{
|
||||
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||
if (f->Transponder() == transponderP) {
|
||||
f->Detach(deviceIdP);
|
||||
debug9("%s (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- cSatipServer -----------------------------------------------------------
|
||||
|
||||
cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char *descriptionP)
|
||||
: addressM((addressP && *addressP) ? addressP : "0.0.0.0"),
|
||||
modelM((modelP && *modelP) ? modelP : "DVBS-1"),
|
||||
descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"),
|
||||
modelTypeM(eSatipModelTypeNone),
|
||||
quirksM(""),
|
||||
quirkM(eSatipQuirkNone),
|
||||
useCountM(0),
|
||||
transponderM(0),
|
||||
hasCiM(false),
|
||||
createdM(time(NULL)),
|
||||
lastSeenM(0)
|
||||
{
|
||||
memset(modelCountM, 0, sizeof(modelCountM));
|
||||
if (!SatipConfig.GetDisableServerQuirks()) {
|
||||
debug3("%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM);
|
||||
// These devices contain a session id bug:
|
||||
// Inverto Airscreen Server IDL 400 ?
|
||||
// Elgato EyeTV Netstream 4Sat ?
|
||||
if (strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400
|
||||
strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1
|
||||
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
||||
)
|
||||
) {
|
||||
quirkM |= eSatipQuirkSessionId;
|
||||
quirksM = cString::sprintf("%s%sSessionId", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||
}
|
||||
// These devices contain a play (add/delpids) parameter bug:
|
||||
if (strstr(*descriptionM, "fritzdvbc")) // Fritz!WLAN Repeater DVB-C
|
||||
if (strstr(*descriptionM, "fritzdvbc") // Fritz!WLAN Repeater DVB-C
|
||||
) {
|
||||
quirkM |= eSatipQuirkPlayPids;
|
||||
quirksM = cString::sprintf("%s%sPlayPids", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||
}
|
||||
// These devices contain a frontend locking bug:
|
||||
if (strstr(*descriptionM, "fritzdvbc")) // Fritz!WLAN Repeater DVB-C
|
||||
if (strstr(*descriptionM, "fritzdvbc") // Fritz!WLAN Repeater DVB-C
|
||||
) {
|
||||
quirkM |= eSatipQuirkForceLock;
|
||||
if (quirkM != eSatipQuirkNone)
|
||||
info("Malfunctioning '%s' server detected! Please, fix the firmware.", *descriptionM);
|
||||
quirksM = cString::sprintf("%s%sForceLock", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||
}
|
||||
debug3("%s description=%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM, *quirksM);
|
||||
}
|
||||
// These devices support the X_PMT protocol extension
|
||||
if (strstr(*descriptionM, "OctopusNet")) // Digital Devices OctopusNet
|
||||
quirkM |= eSatipQuirkUseXCI;
|
||||
if (strstr(*descriptionM, "OctopusNet")) // Digital Devices OctopusNet
|
||||
hasCiM = true;
|
||||
char *s, *p = strdup(*modelM);
|
||||
char *r = strtok_r(p, ",", &s);
|
||||
while (r) {
|
||||
if (strstr(r, "DVBS2-")) {
|
||||
modelTypeM |= eSatipModelTypeDVBS2;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipModuleDVBS2] = atoi(++c);
|
||||
char *c;
|
||||
if (c = strstr(r, "DVBS2-")) {
|
||||
int count = atoi(c + 6);
|
||||
for (int i = 1; i <= count; ++i)
|
||||
frontendsM[eSatipFrontendDVBS2].Add(new cSatipFrontend(i, "DVB-S2"));
|
||||
}
|
||||
else if (strstr(r, "DVBT2-")) {
|
||||
modelTypeM |= eSatipModelTypeDVBT2;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipModuleDVBT2] = atoi(++c);
|
||||
modelTypeM |= eSatipModelTypeDVBT;
|
||||
modelCountM[eSatipModuleDVBT] = modelCountM[eSatipModuleDVBT2];
|
||||
else if (c = strstr(r, "DVBT-")) {
|
||||
int count = atoi(c + 5);
|
||||
for (int i = 1; i <= count; ++i)
|
||||
frontendsM[eSatipFrontendDVBT].Add(new cSatipFrontend(i, "DVB-T"));
|
||||
}
|
||||
else if (strstr(r, "DVBT-")) {
|
||||
modelTypeM |= eSatipModelTypeDVBT;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipModuleDVBT] = atoi(++c);
|
||||
else if (c = strstr(r, "DVBT2-")) {
|
||||
int count = atoi(c + 6);
|
||||
for (int i = 1; i <= count; ++i)
|
||||
frontendsM[eSatipFrontendDVBT2].Add(new cSatipFrontend(i, "DVB-T2"));
|
||||
}
|
||||
else if (strstr(r, "DVBC2-")) {
|
||||
modelTypeM |= eSatipModelTypeDVBC2;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipModuleDVBC2] = atoi(++c);
|
||||
modelTypeM |= eSatipModelTypeDVBC;
|
||||
modelCountM[eSatipModuleDVBC] = modelCountM[eSatipModuleDVBC2];
|
||||
else if (c = strstr(r, "DVBC-")) {
|
||||
int count = atoi(c + 5);
|
||||
for (int i = 1; i <= count; ++i)
|
||||
frontendsM[eSatipFrontendDVBC].Add(new cSatipFrontend(i, "DVB-C"));
|
||||
}
|
||||
else if (strstr(r, "DVBC-")) {
|
||||
modelTypeM |= eSatipModelTypeDVBC;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipModuleDVBC] = atoi(++c);
|
||||
else if (c = strstr(r, "DVBC2-")) {
|
||||
int count = atoi(c + 6);
|
||||
for (int i = 1; i <= count; ++i)
|
||||
frontendsM[eSatipFrontendDVBC2].Add(new cSatipFrontend(i, "DVB-C2"));
|
||||
}
|
||||
r = strtok_r(NULL, ",", &s);
|
||||
}
|
||||
@@ -101,12 +168,96 @@ int cSatipServer::Compare(const cListObject &listObjectP) const
|
||||
return result;
|
||||
}
|
||||
|
||||
void cSatipServer::Use(bool onOffP)
|
||||
bool cSatipServer::Assign(int deviceIdP, int sourceP, int systemP, int transponderP)
|
||||
{
|
||||
if (onOffP)
|
||||
++useCountM;
|
||||
else
|
||||
--useCountM;
|
||||
bool result = false;
|
||||
if (cSource::IsType(sourceP, 'S'))
|
||||
result = frontendsM[eSatipFrontendDVBS2].Assign(deviceIdP, transponderP);
|
||||
else if (cSource::IsType(sourceP, 'T')) {
|
||||
if (systemP)
|
||||
result = frontendsM[eSatipFrontendDVBT2].Assign(deviceIdP, transponderP);
|
||||
else
|
||||
result = frontendsM[eSatipFrontendDVBT].Assign(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBT2].Assign(deviceIdP, transponderP);
|
||||
}
|
||||
else if (cSource::IsType(sourceP, 'C')) {
|
||||
if (systemP)
|
||||
result = frontendsM[eSatipFrontendDVBC2].Assign(deviceIdP, transponderP);
|
||||
else
|
||||
result = frontendsM[eSatipFrontendDVBC].Assign(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Assign(deviceIdP, transponderP);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool cSatipServer::Matches(int sourceP)
|
||||
{
|
||||
if (cSource::IsType(sourceP, 'S'))
|
||||
return GetModulesDVBS2();
|
||||
else if (cSource::IsType(sourceP, 'T'))
|
||||
return GetModulesDVBT() || GetModulesDVBT2();
|
||||
else if (cSource::IsType(sourceP, 'C'))
|
||||
return GetModulesDVBC() || GetModulesDVBC2();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cSatipServer::Matches(int deviceIdP, int sourceP, int systemP, int transponderP)
|
||||
{
|
||||
bool result = false;
|
||||
if (cSource::IsType(sourceP, 'S'))
|
||||
result = frontendsM[eSatipFrontendDVBS2].Matches(deviceIdP, transponderP);
|
||||
else if (cSource::IsType(sourceP, 'T')) {
|
||||
if (systemP)
|
||||
result = frontendsM[eSatipFrontendDVBT2].Matches(deviceIdP, transponderP);
|
||||
else
|
||||
result = frontendsM[eSatipFrontendDVBT].Matches(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBT2].Matches(deviceIdP, transponderP);
|
||||
}
|
||||
else if (cSource::IsType(sourceP, 'C')) {
|
||||
if (systemP)
|
||||
result = frontendsM[eSatipFrontendDVBC2].Matches(deviceIdP, transponderP);
|
||||
else
|
||||
result = frontendsM[eSatipFrontendDVBC].Matches(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Matches(deviceIdP, transponderP);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void cSatipServer::Attach(int deviceIdP, int transponderP)
|
||||
{
|
||||
for (int i = 0; i < eSatipFrontendCount; ++i) {
|
||||
if (frontendsM[i].Attach(deviceIdP, transponderP))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cSatipServer::Detach(int deviceIdP, int transponderP)
|
||||
{
|
||||
for (int i = 0; i < eSatipFrontendCount; ++i) {
|
||||
if (frontendsM[i].Detach(deviceIdP, transponderP))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int cSatipServer::GetModulesDVBS2(void)
|
||||
{
|
||||
return frontendsM[eSatipFrontendDVBS2].Count();
|
||||
}
|
||||
|
||||
int cSatipServer::GetModulesDVBT(void)
|
||||
{
|
||||
return frontendsM[eSatipFrontendDVBT].Count();
|
||||
}
|
||||
|
||||
int cSatipServer::GetModulesDVBT2(void)
|
||||
{
|
||||
return frontendsM[eSatipFrontendDVBT2].Count();
|
||||
}
|
||||
|
||||
int cSatipServer::GetModulesDVBC(void)
|
||||
{
|
||||
return frontendsM[eSatipFrontendDVBC].Count();
|
||||
}
|
||||
|
||||
int cSatipServer::GetModulesDVBC2(void)
|
||||
{
|
||||
return frontendsM[eSatipFrontendDVBC2].Count();
|
||||
}
|
||||
|
||||
// --- cSatipServers ----------------------------------------------------------
|
||||
@@ -114,49 +265,32 @@ void cSatipServer::Use(bool onOffP)
|
||||
cSatipServer *cSatipServers::Find(cSatipServer *serverP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP)
|
||||
if (s->Compare(*serverP) == 0)
|
||||
return s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cSatipServer *cSatipServers::Find(int sourceP, int transponderP, int systemP)
|
||||
cSatipServer *cSatipServers::Find(int sourceP)
|
||||
{
|
||||
cSatipServer *result = NULL;
|
||||
int model = 0;
|
||||
if (cSource::IsType(sourceP, 'S'))
|
||||
model |= cSatipServer::eSatipModelTypeDVBS2;
|
||||
else if (cSource::IsType(sourceP, 'T')) {
|
||||
if (systemP < 0)
|
||||
model |= cSatipServer::eSatipModelTypeDVBT2 | cSatipServer::eSatipModelTypeDVBT;
|
||||
else
|
||||
model |= systemP ? cSatipServer::eSatipModelTypeDVBT2 : cSatipServer::eSatipModelTypeDVBT;
|
||||
}
|
||||
else if (cSource::IsType(sourceP, 'C'))
|
||||
model |= cSatipServer::eSatipModelTypeDVBC;
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s->Match(model) && s->Used() && (s->Transponder() == transponderP))
|
||||
if (s->Matches(sourceP))
|
||||
return s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cSatipServer *cSatipServers::Assign(int deviceIdP, int sourceP, int transponderP, int systemP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s->Matches(deviceIdP, sourceP, systemP, transponderP))
|
||||
return s;
|
||||
}
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s->Match(model)) {
|
||||
result = s;
|
||||
if (!s->Used()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void cSatipServers::SetTransponder(cSatipServer *serverP, int transponderP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP) {
|
||||
s->SetTransponder(transponderP);
|
||||
break;
|
||||
}
|
||||
if (s->Assign(deviceIdP, sourceP, systemP, transponderP))
|
||||
return s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cSatipServer *cSatipServers::Update(cSatipServer *serverP)
|
||||
@@ -170,16 +304,50 @@ cSatipServer *cSatipServers::Update(cSatipServer *serverP)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void cSatipServers::Use(cSatipServer *serverP, bool onOffP)
|
||||
void cSatipServers::Attach(cSatipServer *serverP, int deviceIdP, int transponderP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP) {
|
||||
s->Use(onOffP);
|
||||
s->Attach(deviceIdP, transponderP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cSatipServers::Detach(cSatipServer *serverP, int deviceIdP, int transponderP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP) {
|
||||
s->Detach(deviceIdP, transponderP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cSatipServers::IsQuirk(cSatipServer *serverP, int quirkP)
|
||||
{
|
||||
bool result = false;
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP) {
|
||||
result = s->Quirk(quirkP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool cSatipServers::HasCI(cSatipServer *serverP)
|
||||
{
|
||||
bool result = false;
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP) {
|
||||
result = s->HasCI();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void cSatipServers::Cleanup(uint64_t intervalMsP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
@@ -190,6 +358,18 @@ void cSatipServers::Cleanup(uint64_t intervalMsP)
|
||||
}
|
||||
}
|
||||
|
||||
cString cSatipServers::GetAddress(cSatipServer *serverP)
|
||||
{
|
||||
cString address = "";
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP) {
|
||||
address = s->Address();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
cString cSatipServers::GetString(cSatipServer *serverP)
|
||||
{
|
||||
cString list = "";
|
||||
@@ -215,13 +395,15 @@ int cSatipServers::NumProvidedSystems(void)
|
||||
int count = 0;
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
// DVB-S2: qpsk, 8psk, 16apsk, 32apsk
|
||||
count += s->Satellite() * 4;
|
||||
// DVB-T2: qpsk, qam16, qam64, qam256
|
||||
count += s->GetModulesDVBS2() * 4;
|
||||
// DVB-T: qpsk, qam16, qam64
|
||||
count += s->Terrestrial2() ? s->Terrestrial2() * 4 : s->Terrestrial() * 3;
|
||||
// DVB-C2: qam16, qam32, qam64, qam128, qam256
|
||||
count += s->GetModulesDVBT() * 3;
|
||||
// DVB-T2: qpsk, qam16, qam64, qam256
|
||||
count += s->GetModulesDVBT2() * 4;
|
||||
// DVB-C: qam64, qam128, qam256
|
||||
count += s->Cable2() ? s->Cable2() * 5 : s->Cable() * 3;
|
||||
count += s->GetModulesDVBC() * 3;
|
||||
// DVB-C2: qam16, qam32, qam64, qam128, qam256
|
||||
count += s->GetModulesDVBC2() * 5;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
113
server.h
113
server.h
@@ -8,26 +8,59 @@
|
||||
#ifndef __SATIP_SERVER_H
|
||||
#define __SATIP_SERVER_H
|
||||
|
||||
class cSatipServer;
|
||||
|
||||
// --- cSatipFrontend ---------------------------------------------------------
|
||||
|
||||
class cSatipFrontend : public cListObject {
|
||||
private:
|
||||
int indexM;
|
||||
int transponderM;
|
||||
int deviceIdM;
|
||||
cString descriptionM;
|
||||
|
||||
public:
|
||||
cSatipFrontend(const int indexP, const char *descriptionP);
|
||||
virtual ~cSatipFrontend();
|
||||
void Attach(int deviceIdP) { deviceIdM = deviceIdP; }
|
||||
void Detach(int deviceIdP) { if (deviceIdP == deviceIdM) deviceIdM = -1; }
|
||||
cString Description(void) { return descriptionM; }
|
||||
bool Attached(void) { return (deviceIdM >= 0); }
|
||||
int Index(void) { return indexM; }
|
||||
int Transponder(void) { return transponderM; }
|
||||
int DeviceId(void) { return deviceIdM; }
|
||||
void SetTransponder(int transponderP) { transponderM = transponderP; }
|
||||
};
|
||||
|
||||
// --- cSatipFrontends --------------------------------------------------------
|
||||
|
||||
class cSatipFrontends : public cList<cSatipFrontend> {
|
||||
public:
|
||||
bool Matches(int deviceIdP, int transponderP);
|
||||
bool Assign(int deviceIdP, int transponderP);
|
||||
bool Attach(int deviceIdP, int transponderP);
|
||||
bool Detach(int deviceIdP, int transponderP);
|
||||
};
|
||||
|
||||
// --- cSatipServer -----------------------------------------------------------
|
||||
|
||||
class cSatipServer : public cListObject {
|
||||
private:
|
||||
enum eSatipModule {
|
||||
eSatipModuleDVBS2 = 0,
|
||||
eSatipModuleDVBT,
|
||||
eSatipModuleDVBT2,
|
||||
eSatipModuleDVBC,
|
||||
eSatipModuleDVBC2,
|
||||
eSatipModuleCount
|
||||
enum eSatipFrontend {
|
||||
eSatipFrontendDVBS2 = 0,
|
||||
eSatipFrontendDVBT,
|
||||
eSatipFrontendDVBT2,
|
||||
eSatipFrontendDVBC,
|
||||
eSatipFrontendDVBC2,
|
||||
eSatipFrontendCount
|
||||
};
|
||||
cString addressM;
|
||||
cString modelM;
|
||||
cString descriptionM;
|
||||
int modelCountM[eSatipModuleCount];
|
||||
int modelTypeM;
|
||||
cString quirksM;
|
||||
cSatipFrontends frontendsM[eSatipFrontendCount];
|
||||
int quirkM;
|
||||
int useCountM;
|
||||
int transponderM;
|
||||
bool hasCiM;
|
||||
time_t createdM;
|
||||
cTimeMs lastSeenM;
|
||||
|
||||
@@ -37,39 +70,31 @@ public:
|
||||
eSatipQuirkSessionId = 0x01,
|
||||
eSatipQuirkPlayPids = 0x02,
|
||||
eSatipQuirkForceLock = 0x04,
|
||||
eSatipQuirkUseXCI = 0x08,
|
||||
eSatipQuirkMask = 0x0F
|
||||
};
|
||||
enum eSatipModelType {
|
||||
eSatipModelTypeNone = 0x00,
|
||||
eSatipModelTypeDVBS2 = 0x01,
|
||||
eSatipModelTypeDVBT = 0x02,
|
||||
eSatipModelTypeDVBT2 = 0x04,
|
||||
eSatipModelTypeDVBC = 0x08,
|
||||
eSatipModelTypeDVBC2 = 0x10,
|
||||
eSatipModelTypeMask = 0xFF
|
||||
};
|
||||
cSatipServer(const char *addressP, const char *modelP, const char *descriptionP);
|
||||
virtual ~cSatipServer();
|
||||
virtual int Compare(const cListObject &listObjectP) const;
|
||||
void Use(bool onOffP);
|
||||
void SetTransponder(const int transponderP) { transponderM = transponderP; }
|
||||
int Transponder(void) { return transponderM; }
|
||||
bool Used(void) { return !!useCountM; }
|
||||
const char *Address() { return *addressM; }
|
||||
const char *Model(void) { return *modelM; }
|
||||
const char *Description() { return *descriptionM; }
|
||||
bool Quirk(int quirkP) { return ((quirkP & eSatipQuirkMask) & quirkM); }
|
||||
int ModelType(void) { return modelTypeM; }
|
||||
bool Match(int modelP) { return ((modelP & eSatipModelTypeMask) & modelTypeM); }
|
||||
int Cable() { return Match(eSatipModelTypeDVBC) ? modelCountM[eSatipModuleDVBC] : 0; }
|
||||
int Cable2() { return Match(eSatipModelTypeDVBC2) ? modelCountM[eSatipModuleDVBC2] : 0; }
|
||||
int Satellite() { return Match(eSatipModelTypeDVBS2) ? modelCountM[eSatipModuleDVBS2] : 0; }
|
||||
int Terrestrial() { return Match(eSatipModelTypeDVBT) ? modelCountM[eSatipModuleDVBT] : 0; }
|
||||
int Terrestrial2() { return Match(eSatipModelTypeDVBT2) ? modelCountM[eSatipModuleDVBT2] : 0; }
|
||||
void Update(void) { lastSeenM.Set(); }
|
||||
uint64_t LastSeen(void) { return lastSeenM.Elapsed(); }
|
||||
time_t Created(void) { return createdM; }
|
||||
bool Assign(int deviceIdP, int sourceP, int systemP, int transponderP);
|
||||
bool Matches(int sourceP);
|
||||
bool Matches(int deviceIdP, int sourceP, int systemP, int transponderP);
|
||||
void Attach(int deviceIdP, int transponderP);
|
||||
void Detach(int deviceIdP, int transponderP);
|
||||
int GetModulesDVBS2(void);
|
||||
int GetModulesDVBT(void);
|
||||
int GetModulesDVBT2(void);
|
||||
int GetModulesDVBC(void);
|
||||
int GetModulesDVBC2(void);
|
||||
const char *Address(void) { return *addressM; }
|
||||
const char *Model(void) { return *modelM; }
|
||||
const char *Description(void) { return *descriptionM; }
|
||||
const char *Quirks(void) { return *quirksM; }
|
||||
bool Quirk(int quirkP) { return ((quirkP & eSatipQuirkMask) & quirkM); }
|
||||
bool HasQuirk(void) { return (quirkM != eSatipQuirkNone); }
|
||||
bool HasCI(void) { return hasCiM; }
|
||||
void Update(void) { lastSeenM.Set(); }
|
||||
uint64_t LastSeen(void) { return lastSeenM.Elapsed(); }
|
||||
time_t Created(void) { return createdM; }
|
||||
};
|
||||
|
||||
// --- cSatipServers ----------------------------------------------------------
|
||||
@@ -77,11 +102,15 @@ public:
|
||||
class cSatipServers : public cList<cSatipServer> {
|
||||
public:
|
||||
cSatipServer *Find(cSatipServer *serverP);
|
||||
cSatipServer *Find(int sourceP, int transponderP, int systemP);
|
||||
void SetTransponder(cSatipServer *serverP, int transponderP);
|
||||
cSatipServer *Find(int sourceP);
|
||||
cSatipServer *Assign(int deviceIdP, int sourceP, int transponderP, int systemP);
|
||||
cSatipServer *Update(cSatipServer *serverP);
|
||||
void Use(cSatipServer *serverP, bool onOffP);
|
||||
void Attach(cSatipServer *serverP, int deviceIdP, int transponderP);
|
||||
void Detach(cSatipServer *serverP, int deviceIdP, int transponderP);
|
||||
bool IsQuirk(cSatipServer *serverP, int quirkP);
|
||||
bool HasCI(cSatipServer *serverP);
|
||||
void Cleanup(uint64_t intervalMsP = 0);
|
||||
cString GetAddress(cSatipServer *serverP);
|
||||
cString GetString(cSatipServer *serverP);
|
||||
cString List(void);
|
||||
int NumProvidedSystems(void);
|
||||
|
2
setup.c
2
setup.c
@@ -104,7 +104,7 @@ cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP)
|
||||
addressM(serverP ? serverP->Address() : "---"),
|
||||
modelM(serverP ? serverP->Model() : "---"),
|
||||
descriptionM(serverP ? serverP->Description() : "---"),
|
||||
ciExtensionM(serverP && serverP->Quirk(cSatipServer::eSatipQuirkUseXCI) ? trVDR("yes") : trVDR("no")),
|
||||
ciExtensionM(serverP && serverP->HasCI() ? trVDR("yes") : trVDR("no")),
|
||||
createdM(serverP ? serverP->Created() : 0)
|
||||
{
|
||||
SetMenuCategory(mcSetupPlugins);
|
||||
|
15
socket.c
15
socket.c
@@ -129,19 +129,24 @@ int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP)
|
||||
if (len > 0)
|
||||
return len;
|
||||
} while (len > 0);
|
||||
ERROR_IF_RET(len < 0 && errno != EAGAIN, "recvmsg()", return -1);
|
||||
ERROR_IF_RET(len < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmsg()", return -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRecvSizeP, unsigned int elementCountP, unsigned int elementBufferSizeP)
|
||||
{
|
||||
debug16("%s (, , %d, %d)", __PRETTY_FUNCTION__, elementCountP, elementBufferSizeP);
|
||||
#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,12)
|
||||
int count = -1;
|
||||
// Error out if socket not initialized
|
||||
if (socketDescM <= 0) {
|
||||
error("%s Invalid socket", __PRETTY_FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
if (!bufferAddrP || !elementRecvSizeP || !elementCountP || !elementBufferSizeP) {
|
||||
error("%s Invalid parameter(s)", __PRETTY_FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,12)
|
||||
// Initialize iov and msgh structures
|
||||
struct mmsghdr mmsgh[elementCountP];
|
||||
struct iovec iov[elementCountP];
|
||||
@@ -154,14 +159,12 @@ int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRec
|
||||
}
|
||||
|
||||
// Read data from socket as a set
|
||||
int count = -1;
|
||||
if (socketDescM && bufferAddrP && elementRecvSizeP && (elementCountP > 0) && (elementBufferSizeP > 0))
|
||||
count = (int)recvmmsg(socketDescM, mmsgh, elementCountP, MSG_DONTWAIT, NULL);
|
||||
count = (int)recvmmsg(socketDescM, mmsgh, elementCountP, MSG_DONTWAIT, NULL);
|
||||
ERROR_IF_RET(count < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmmsg()", return -1);
|
||||
for (int i = 0; i < count; ++i)
|
||||
elementRecvSizeP[i] = mmsgh[i].msg_len;
|
||||
#else
|
||||
int count = 0;
|
||||
count = 0;
|
||||
while (count < (int)elementCountP) {
|
||||
int len = Read(bufferAddrP + count * elementBufferSizeP, elementBufferSizeP);
|
||||
if (len < 0)
|
||||
|
48
tuner.c
48
tuner.c
@@ -25,8 +25,8 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
||||
rtcpM(*this),
|
||||
streamAddrM(""),
|
||||
streamParamM(""),
|
||||
currentServerM(NULL),
|
||||
nextServerM(NULL),
|
||||
currentServerM(NULL, deviceP.GetId(), 0),
|
||||
nextServerM(NULL, deviceP.GetId(), 0),
|
||||
mutexM(),
|
||||
reConnectM(),
|
||||
keepAliveM(),
|
||||
@@ -40,6 +40,7 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
||||
hasLockM(false),
|
||||
signalStrengthM(-1),
|
||||
signalQualityM(-1),
|
||||
frontendIdM(-1),
|
||||
streamIdM(-1),
|
||||
pmtPidM(-1),
|
||||
addPidsM(),
|
||||
@@ -118,7 +119,7 @@ void cSatipTuner::Action(void)
|
||||
// Read reception statistics via DESCRIBE and RTCP
|
||||
if (hasLockM || ReadReceptionStatus()) {
|
||||
// Quirk for devices without valid reception data
|
||||
if (currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkForceLock)) {
|
||||
if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkForceLock)) {
|
||||
hasLockM = true;
|
||||
signalStrengthM = eDefaultSignalStrength;
|
||||
signalQualityM = eDefaultSignalQuality;
|
||||
@@ -196,15 +197,15 @@ bool cSatipTuner::Connect(void)
|
||||
else if (rtspM.Options(*connectionUri)) {
|
||||
cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM);
|
||||
// Flush any old content
|
||||
rtpM.Flush();
|
||||
rtcpM.Flush();
|
||||
//rtpM.Flush();
|
||||
//rtcpM.Flush();
|
||||
if (rtspM.Setup(*uri, rtpM.Port(), rtcpM.Port())) {
|
||||
keepAliveM.Set(timeoutM);
|
||||
if (nextServerM) {
|
||||
cSatipDiscover::GetInstance()->UseServer(nextServerM, true);
|
||||
if (nextServerM.IsValid()) {
|
||||
currentServerM = nextServerM;
|
||||
nextServerM = NULL;
|
||||
nextServerM.Reset();
|
||||
}
|
||||
currentServerM.Attach();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -234,9 +235,9 @@ bool cSatipTuner::Disconnect(void)
|
||||
hasLockM = false;
|
||||
signalStrengthM = -1;
|
||||
signalQualityM = -1;
|
||||
frontendIdM = -1;
|
||||
|
||||
if (currentServerM)
|
||||
cSatipDiscover::GetInstance()->UseServer(currentServerM, false);
|
||||
currentServerM.Detach();
|
||||
statusUpdateM.Set(0);
|
||||
timeoutM = eMinKeepAliveIntervalMs;
|
||||
pmtPidM = -1;
|
||||
@@ -285,6 +286,9 @@ void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP)
|
||||
if (c) {
|
||||
int value;
|
||||
|
||||
// feID:
|
||||
frontendIdM = atoi(c + 7);
|
||||
|
||||
// level:
|
||||
// Numerical value between 0 and 255
|
||||
// An incoming L-band satellite signal of
|
||||
@@ -330,7 +334,7 @@ void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
debug1("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, sessionP, timeoutP, deviceIdM);
|
||||
sessionM = sessionP;
|
||||
if (nextServerM && nextServerM->Quirk(cSatipServer::eSatipQuirkSessionId) && !isempty(*sessionM) && startswith(*sessionM, "0"))
|
||||
if (nextServerM.IsQuirk(cSatipServer::eSatipQuirkSessionId) && !isempty(*sessionM) && startswith(*sessionM, "0"))
|
||||
rtspM.SetSession(SkipZeroes(*sessionM));
|
||||
timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs;
|
||||
}
|
||||
@@ -341,15 +345,15 @@ int cSatipTuner::GetId(void)
|
||||
return deviceIdM;
|
||||
}
|
||||
|
||||
bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const int indexP)
|
||||
bool cSatipTuner::SetSource(cSatipServer *serverP, const int transponderP, const char *parameterP, const int indexP)
|
||||
{
|
||||
debug1("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, parameterP, indexP, deviceIdM);
|
||||
debug1("%s (%d, %s, %d) [device %d]", __PRETTY_FUNCTION__, transponderP, parameterP, indexP, deviceIdM);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
if (serverP) {
|
||||
nextServerM = cSatipDiscover::GetInstance()->GetServer(serverP);
|
||||
if (nextServerM && !isempty(nextServerM->Address()) && !isempty(parameterP)) {
|
||||
nextServerM.Set(serverP, transponderP);
|
||||
if (!isempty(*nextServerM.GetAddress()) && !isempty(parameterP)) {
|
||||
// Update stream address and parameter
|
||||
streamAddrM = rtspM.RtspUnescapeString(nextServerM->Address());
|
||||
streamAddrM = rtspM.RtspUnescapeString(*nextServerM.GetAddress());
|
||||
streamParamM = rtspM.RtspUnescapeString(parameterP);
|
||||
// Reconnect
|
||||
RequestState(tsSet, smExternal);
|
||||
@@ -390,8 +394,8 @@ bool cSatipTuner::UpdatePids(bool forceP)
|
||||
if (((forceP && pidsM.Size()) || (pidUpdateCacheM.TimedOut() && (addPidsM.Size() || delPidsM.Size()))) &&
|
||||
!isempty(*streamAddrM) && (streamIdM > 0)) {
|
||||
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||
bool useci = (SatipConfig.GetCIExtension() && !!(currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkUseXCI)));
|
||||
bool usedummy = !!(currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkPlayPids));
|
||||
bool useci = (SatipConfig.GetCIExtension() && currentServerM.HasCI());
|
||||
bool usedummy = currentServerM.IsQuirk(cSatipServer::eSatipQuirkPlayPids);
|
||||
if (forceP || usedummy) {
|
||||
if (pidsM.Size())
|
||||
uri = cString::sprintf("%s?pids=%s", *uri, *pidsM.ListPids());
|
||||
@@ -558,6 +562,12 @@ const char *cSatipTuner::TunerStateString(eTunerState stateP)
|
||||
return "---";
|
||||
}
|
||||
|
||||
int cSatipTuner::FrontendId(void)
|
||||
{
|
||||
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||
return frontendIdM;
|
||||
}
|
||||
|
||||
int cSatipTuner::SignalStrength(void)
|
||||
{
|
||||
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||
@@ -579,7 +589,7 @@ bool cSatipTuner::HasLock(void)
|
||||
cString cSatipTuner::GetSignalStatus(void)
|
||||
{
|
||||
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||
return cString::sprintf("lock=%d strength=%d quality=%d", HasLock(), SignalStrength(), SignalQuality());
|
||||
return cString::sprintf("lock=%d strength=%d quality=%d frontend=%d", HasLock(), SignalStrength(), SignalQuality(), FrontendId());
|
||||
}
|
||||
|
||||
cString cSatipTuner::GetInformation(void)
|
||||
|
60
tuner.h
60
tuner.h
@@ -8,11 +8,11 @@
|
||||
#ifndef __SATIP_TUNER_H
|
||||
#define __SATIP_TUNER_H
|
||||
|
||||
#include <vdr/config.h> // APIVERSNUM
|
||||
#include <vdr/thread.h>
|
||||
#include <vdr/tools.h>
|
||||
|
||||
#include "deviceif.h"
|
||||
#include "discover.h"
|
||||
#include "rtp.h"
|
||||
#include "rtcp.h"
|
||||
#include "rtsp.h"
|
||||
@@ -27,33 +27,6 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
#if defined(APIVERSNUM) && APIVERSNUM < 20107
|
||||
int IndexOf(const int &pidP)
|
||||
{
|
||||
for (int i = 0; i < Size(); ++i) {
|
||||
if (pidP == At(i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
bool RemoveElement(const int &pidP)
|
||||
{
|
||||
int i = IndexOf(pidP);
|
||||
if (i >= 0) {
|
||||
Remove(i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool AppendUnique(int pidP)
|
||||
{
|
||||
if (IndexOf(pidP) < 0) {
|
||||
Append(pidP);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
void RemovePid(const int &pidP)
|
||||
{
|
||||
if (RemoveElement(pidP))
|
||||
@@ -76,6 +49,29 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class cSatipTunerServer
|
||||
{
|
||||
private:
|
||||
cSatipServer *serverM;
|
||||
int deviceIdM;
|
||||
int transponderM;
|
||||
|
||||
public:
|
||||
cSatipTunerServer(cSatipServer *serverP, const int deviceIdP, const int transponderP) : serverM(serverP), deviceIdM(deviceIdP), transponderM(transponderP) {}
|
||||
~cSatipTunerServer() {}
|
||||
cSatipTunerServer(const cSatipTunerServer &objP) { serverM = NULL; deviceIdM = -1; transponderM = 0; }
|
||||
cSatipTunerServer& operator= (const cSatipTunerServer &objP) { serverM = objP.serverM; deviceIdM = objP.deviceIdM; transponderM = objP.transponderM; return *this; }
|
||||
bool IsValid(void) { return !!serverM; }
|
||||
bool IsQuirk(int quirkP) { return (serverM && cSatipDiscover::GetInstance()->IsServerQuirk(serverM, quirkP)); }
|
||||
bool HasCI(void) { return (serverM && cSatipDiscover::GetInstance()->HasServerCI(serverM)); }
|
||||
void Attach(void) { if (serverM) cSatipDiscover::GetInstance()->AttachServer(serverM, deviceIdM, transponderM); }
|
||||
void Detach(void) { if (serverM) cSatipDiscover::GetInstance()->DetachServer(serverM, deviceIdM, transponderM); }
|
||||
void Set(cSatipServer *serverP, const int transponderP) { serverM = serverP; transponderM = transponderP; }
|
||||
void Reset(void) { serverM = NULL; transponderM = 0; }
|
||||
cString GetAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerAddress(serverM) : ""; }
|
||||
cString GetInfo(void) { return cString::sprintf("server=%s deviceid=%d transponder=%d", serverM ? "assigned" : "null", deviceIdM, transponderM); }
|
||||
};
|
||||
|
||||
class cSatipTuner : public cThread, public cSatipTunerStatistics, public cSatipTunerIf
|
||||
{
|
||||
private:
|
||||
@@ -100,8 +96,8 @@ private:
|
||||
cSatipRtcp rtcpM;
|
||||
cString streamAddrM;
|
||||
cString streamParamM;
|
||||
cSatipServer *currentServerM;
|
||||
cSatipServer *nextServerM;
|
||||
cSatipTunerServer currentServerM;
|
||||
cSatipTunerServer nextServerM;
|
||||
cMutex mutexM;
|
||||
cTimeMs reConnectM;
|
||||
cTimeMs keepAliveM;
|
||||
@@ -115,6 +111,7 @@ private:
|
||||
bool hasLockM;
|
||||
int signalStrengthM;
|
||||
int signalQualityM;
|
||||
int frontendIdM;
|
||||
int streamIdM;
|
||||
int pmtPidM;
|
||||
cSatipPid addPidsM;
|
||||
@@ -139,10 +136,11 @@ public:
|
||||
cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP);
|
||||
virtual ~cSatipTuner();
|
||||
bool IsTuned(void) const { return (currentStateM >= tsTuned); }
|
||||
bool SetSource(cSatipServer *serverP, const char *parameterP, const int indexP);
|
||||
bool SetSource(cSatipServer *serverP, const int transponderP, const char *parameterP, const int indexP);
|
||||
bool SetPid(int pidP, int typeP, bool onP);
|
||||
bool Open(void);
|
||||
bool Close(void);
|
||||
int FrontendId(void);
|
||||
int SignalStrength(void);
|
||||
int SignalQuality(void);
|
||||
bool HasLock(void);
|
||||
|
Reference in New Issue
Block a user