2014-03-13 17:23:55 +01:00
|
|
|
/*
|
|
|
|
* server.c: SAT>IP plugin for the Video Disk Recorder
|
|
|
|
*
|
|
|
|
* See the README file for copyright information and how to reach the author.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <vdr/sources.h>
|
|
|
|
|
2014-12-03 18:57:23 +01:00
|
|
|
#include "config.h"
|
2014-03-13 17:23:55 +01:00
|
|
|
#include "common.h"
|
2014-12-05 22:14:40 +01:00
|
|
|
#include "log.h"
|
2014-03-13 17:23:55 +01:00
|
|
|
#include "server.h"
|
|
|
|
|
|
|
|
// --- cSatipServer -----------------------------------------------------------
|
|
|
|
|
2014-11-10 23:05:03 +01:00
|
|
|
cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char *descriptionP)
|
2014-03-13 17:23:55 +01:00
|
|
|
: addressM(addressP),
|
|
|
|
modelM(modelP),
|
2014-11-10 23:05:03 +01:00
|
|
|
descriptionM(descriptionP),
|
2014-05-08 21:09:35 +02:00
|
|
|
modelTypeM(eSatipModelTypeNone),
|
|
|
|
quirkM(eSatipQuirkNone),
|
2014-03-13 17:23:55 +01:00
|
|
|
useCountM(0),
|
2014-11-01 15:31:44 +01:00
|
|
|
transponderM(0),
|
2014-03-13 17:23:55 +01:00
|
|
|
createdM(time(NULL)),
|
|
|
|
lastSeenM(0)
|
|
|
|
{
|
|
|
|
memset(modelCountM, 0, sizeof(modelCountM));
|
|
|
|
if (isempty(*modelM))
|
|
|
|
modelM = "DVBS-1";
|
2014-10-31 17:18:33 +01:00
|
|
|
if (!isempty(*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
|
2014-11-04 20:02:30 +01:00
|
|
|
strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1
|
2014-10-31 17:18:33 +01:00
|
|
|
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
|
|
|
)
|
|
|
|
quirkM |= eSatipQuirkSessionId;
|
2014-11-01 15:31:44 +01:00
|
|
|
// These devices contain a play (add/delpids) parameter bug:
|
2014-10-31 17:18:33 +01:00
|
|
|
if (strstr(*descriptionM, "fritzdvbc")) // Fritz!WLAN Repeater DVB-C
|
2014-11-22 16:04:32 +01:00
|
|
|
quirkM |= eSatipQuirkPlayPids;
|
|
|
|
// These devices contain a frontend locking bug:
|
|
|
|
if (strstr(*descriptionM, "fritzdvbc")) // Fritz!WLAN Repeater DVB-C
|
|
|
|
quirkM |= eSatipQuirkForceLock;
|
2014-12-20 17:46:18 +01:00
|
|
|
if (quirkM != eSatipQuirkNone)
|
|
|
|
info("Malfunctioning '%s' server detected! Please, fix the firmware.", *descriptionM);
|
2015-01-05 23:58:35 +01:00
|
|
|
// These devices support the X_PMT protocol extension
|
|
|
|
if (strstr(*descriptionM, "OctopusNet")) // Digital Devices OctopusNet
|
2015-01-09 14:42:03 +01:00
|
|
|
quirkM |= eSatipQuirkUseXCI;
|
2014-10-31 17:18:33 +01:00
|
|
|
}
|
2014-03-13 17:23:55 +01:00
|
|
|
char *s, *p = strdup(*modelM);
|
|
|
|
char *r = strtok_r(p, ",", &s);
|
|
|
|
while (r) {
|
2015-01-14 19:34:12 +01:00
|
|
|
if (strstr(r, "DVBS2-")) {
|
|
|
|
modelTypeM |= eSatipModelTypeDVBS2;
|
2014-03-13 17:23:55 +01:00
|
|
|
if (char *c = strstr(r, "-"))
|
|
|
|
modelCountM[eSatipModuleDVBS2] = atoi(++c);
|
|
|
|
}
|
2015-01-14 19:34:12 +01:00
|
|
|
else if (strstr(r, "DVBT2-")) {
|
|
|
|
modelTypeM |= eSatipModelTypeDVBT2;
|
2014-03-13 17:23:55 +01:00
|
|
|
if (char *c = strstr(r, "-"))
|
|
|
|
modelCountM[eSatipModuleDVBT2] = atoi(++c);
|
2015-01-14 19:34:12 +01:00
|
|
|
modelTypeM |= eSatipModelTypeDVBT;
|
|
|
|
modelCountM[eSatipModuleDVBT] = modelCountM[eSatipModuleDVBT2];
|
2014-03-13 17:23:55 +01:00
|
|
|
}
|
2015-01-14 19:34:12 +01:00
|
|
|
else if (strstr(r, "DVBT-")) {
|
|
|
|
modelTypeM |= eSatipModelTypeDVBT;
|
2014-03-13 17:23:55 +01:00
|
|
|
if (char *c = strstr(r, "-"))
|
|
|
|
modelCountM[eSatipModuleDVBT] = atoi(++c);
|
2014-10-30 21:10:09 +01:00
|
|
|
}
|
2015-01-14 19:34:12 +01:00
|
|
|
else if (strstr(r, "DVBC2-")) {
|
|
|
|
modelTypeM |= eSatipModelTypeDVBC2;
|
2014-11-20 21:30:18 +01:00
|
|
|
if (char *c = strstr(r, "-"))
|
|
|
|
modelCountM[eSatipModuleDVBC2] = atoi(++c);
|
2015-01-14 19:34:12 +01:00
|
|
|
modelTypeM |= eSatipModelTypeDVBC;
|
|
|
|
modelCountM[eSatipModuleDVBC] = modelCountM[eSatipModuleDVBC2];
|
2014-11-20 21:30:18 +01:00
|
|
|
}
|
2015-01-14 19:34:12 +01:00
|
|
|
else if (strstr(r, "DVBC-")) {
|
|
|
|
modelTypeM |= eSatipModelTypeDVBC;
|
2014-10-30 21:10:09 +01:00
|
|
|
if (char *c = strstr(r, "-"))
|
|
|
|
modelCountM[eSatipModuleDVBC] = atoi(++c);
|
2014-03-13 17:23:55 +01:00
|
|
|
}
|
|
|
|
r = strtok_r(NULL, ",", &s);
|
|
|
|
}
|
|
|
|
free(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
cSatipServer::~cSatipServer()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int cSatipServer::Compare(const cListObject &listObjectP) const
|
|
|
|
{
|
|
|
|
const cSatipServer *s = (const cSatipServer *)&listObjectP;
|
2015-01-13 20:24:31 +01:00
|
|
|
int result = strcasecmp(*addressM, *s->addressM);
|
|
|
|
if (!result) {
|
|
|
|
result = strcasecmp(*modelM, *s->modelM);
|
|
|
|
if (!result)
|
|
|
|
result = strcasecmp(*descriptionM, *s->descriptionM);
|
|
|
|
}
|
|
|
|
return result;
|
2014-03-13 17:23:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void cSatipServer::Use(bool onOffP)
|
|
|
|
{
|
|
|
|
if (onOffP)
|
|
|
|
++useCountM;
|
|
|
|
else
|
|
|
|
--useCountM;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --- cSatipServers ----------------------------------------------------------
|
|
|
|
|
|
|
|
cSatipServer *cSatipServers::Find(cSatipServer *serverP)
|
|
|
|
{
|
|
|
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
|
|
if (s == serverP)
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-11-01 15:31:44 +01:00
|
|
|
cSatipServer *cSatipServers::Find(int sourceP, int transponderP, int systemP)
|
2014-03-13 17:23:55 +01:00
|
|
|
{
|
|
|
|
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;
|
2014-11-01 15:31:44 +01:00
|
|
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
|
|
if (s->Match(model) && s->Used() && (s->Transponder() == transponderP))
|
|
|
|
return s;
|
|
|
|
}
|
2014-03-13 17:23:55 +01:00
|
|
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
|
|
if (s->Match(model)) {
|
|
|
|
result = s;
|
|
|
|
if (!s->Used()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2014-11-01 15:31:44 +01:00
|
|
|
void cSatipServers::SetTransponder(cSatipServer *serverP, bool transponderP)
|
|
|
|
{
|
|
|
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
|
|
if (s == serverP) {
|
|
|
|
s->SetTransponder(transponderP);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-13 17:23:55 +01:00
|
|
|
cSatipServer *cSatipServers::Update(cSatipServer *serverP)
|
|
|
|
{
|
|
|
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
|
|
if (s->Compare(*serverP) == 0) {
|
|
|
|
s->Update();
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSatipServers::Use(cSatipServer *serverP, bool onOffP)
|
|
|
|
{
|
|
|
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
|
|
if (s == serverP) {
|
|
|
|
s->Use(onOffP);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSatipServers::Cleanup(uint64_t intervalMsP)
|
|
|
|
{
|
|
|
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
|
|
if (!intervalMsP || (s->LastSeen() > intervalMsP)) {
|
2014-12-16 22:09:31 +01:00
|
|
|
info("Removing server %s (%s %s)", s->Description(), s->Address(), s->Model());
|
2014-03-13 17:23:55 +01:00
|
|
|
Del(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cString cSatipServers::GetString(cSatipServer *serverP)
|
|
|
|
{
|
|
|
|
cString list = "";
|
|
|
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
|
|
if (s == serverP) {
|
2014-03-23 16:59:08 +01:00
|
|
|
list = cString::sprintf("%s|%s|%s", s->Address(), s->Model(), s->Description());
|
2014-03-13 17:23:55 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
cString cSatipServers::List(void)
|
|
|
|
{
|
|
|
|
cString list = "";
|
|
|
|
for (cSatipServer *s = First(); s; s = Next(s))
|
2014-03-23 16:59:08 +01:00
|
|
|
list = cString::sprintf("%s%s|%s|%s\n", *list, s->Address(), s->Model(), s->Description());
|
2014-03-13 17:23:55 +01:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cSatipServers::NumProvidedSystems(void)
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
2014-11-01 15:31:44 +01:00
|
|
|
// DVB-S2: qpsk, 8psk, 16apsk, 32apsk
|
2014-03-13 17:23:55 +01:00
|
|
|
count += s->Satellite() * 4;
|
2014-11-01 15:31:44 +01:00
|
|
|
// DVB-T2: qpsk, qam16, qam64, qam256
|
|
|
|
// DVB-T: qpsk, qam16, qam64
|
|
|
|
count += s->Terrestrial2() ? s->Terrestrial2() * 4 : s->Terrestrial() * 3;
|
2014-11-20 21:30:18 +01:00
|
|
|
// DVB-C2: qam16, qam32, qam64, qam128, qam256
|
2014-11-01 15:31:44 +01:00
|
|
|
// DVB-C: qam64, qam128, qam256
|
2014-11-20 21:30:18 +01:00
|
|
|
count += s->Cable2() ? s->Cable2() * 5 : s->Cable() * 3;
|
2014-03-13 17:23:55 +01:00
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|