1
0
mirror of https://github.com/rofafor/vdr-plugin-satip.git synced 2023-10-10 11:37:42 +00:00

19 Commits

Author SHA1 Message Date
Rolf Ahrenberg
8184a785b7 Updated README. 2015-02-20 21:15:55 +02:00
Rolf Ahrenberg
1b4094696a Updated HISTORY. 2015-02-20 20:53:20 +02:00
Rolf Ahrenberg
4139e87f4a Disable socket flushing. 2015-02-20 20:51:31 +02:00
Rolf Ahrenberg
7196c9403b Updated the APIVERSNUM requirement. 2015-02-20 20:47:58 +02:00
Rolf Ahrenberg
e1c896c1a6 Added a missing linefeed. 2015-02-17 21:16:30 +02:00
Rolf Ahrenberg
6b63ad145f Fixed the frontend assignment. 2015-02-16 19:42:18 +02:00
Rolf Ahrenberg
84dfc6701e Refactored the frontend attaching/detaching signaling. 2015-02-16 17:59:27 +02:00
Rolf Ahrenberg
653d9d659b Updated README. 2015-02-16 16:49:51 +02:00
Rolf Ahrenberg
26cd34f965 Updated version to 2.2.0. 2015-02-08 22:41:01 +02:00
Rolf Ahrenberg
df258d127f Reverted the force locking quirk for Triax TSS 400. 2015-01-27 21:31:39 +02:00
Rolf Ahrenberg
3e4b1c0383 Updated the server info message to show used quirks. 2015-01-27 17:19:06 +02:00
Rolf Ahrenberg
73ed299ed9 Fixed to nag about any malfunctioning firmware only once. 2015-01-26 00:24:07 +02:00
Rolf Ahrenberg
37e151b3e3 Added the force locking quirk for Triax TSS 400. 2015-01-25 23:47:56 +02:00
Rolf Ahrenberg
b1aad3fb80 Updated the version number. 2015-01-24 17:21:04 +02:00
Rolf Ahrenberg
a87dfc43f7 Refactored the frontend handling. 2015-01-24 17:16:09 +02:00
Rolf Ahrenberg
26be862d89 Refactored some errno handling. 2015-01-24 16:20:13 +02:00
Rolf Ahrenberg
ab2a47e3e7 Got rid of scan-build warnings. 2015-01-22 21:37:33 +02:00
Rolf Ahrenberg
3d1efe7a80 Fixed freeing some memory. 2015-01-21 22:40:24 +02:00
Rolf Ahrenberg
c9898bfbfd Added support for showing the frontend id. 2015-01-20 00:35:46 +02:00
20 changed files with 486 additions and 242 deletions

12
HISTORY
View File

@@ -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
View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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());
}
}

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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
View File

@@ -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
View File

@@ -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());

View File

@@ -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
View File

@@ -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
View File

@@ -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);

View File

@@ -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);

View File

@@ -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
View File

@@ -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
View File

@@ -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);