Refactored code and added support for 'C' sources.

This commit is contained in:
Rolf Ahrenberg 2014-03-13 18:23:55 +02:00
parent 8c05ce31f9
commit 497b1893db
20 changed files with 519 additions and 283 deletions

View File

@ -7,8 +7,8 @@ VDR Plugin 'satip' Revision History
- Initial revision. - Initial revision.
- Added German translation (Thanks to Frank Neumann). - Added German translation (Thanks to Frank Neumann).
2014-03-15: Version 0.0.2 2014-03-15: Version 0.1.0
- Switched to standard 'S' and 'T' sources. - Switched to the standard S/T/C source identifiers.
- Added a new OperationMode setup parameter. - Added a new operation mode setup parameter.
- Added new SVDRP commands. - Added new SVDRP commands.

View File

@ -78,7 +78,7 @@ all-redirect: all
### The object files (add further files here): ### The object files (add further files here):
OBJS = $(PLUGIN).o common.o config.o device.o discover.o param.o \ OBJS = $(PLUGIN).o common.o config.o device.o discover.o param.o \
sectionfilter.o setup.o socket.o statistics.o tuner.o sectionfilter.o server.o setup.o socket.o statistics.o tuner.o
### The main target: ### The main target:

13
README
View File

@ -57,9 +57,11 @@ Setup menu:
- Operating mode = off If you want exclude all SAT>IP devices - Operating mode = off If you want exclude all SAT>IP devices
low from VDR's device handling, set this low from VDR's device handling, set this
normal option to "off". Otherwise, if you want normal option to "off". Otherwise, if you want
to keep SAT>IP at a low priority when high to keep SAT>IP at a low priority when
selecting available devices, set this selecting available devices, set this
option to "low". option to "low". Similarly, the "high"
value prefers the SAT>IP over the local
DVB cards when selecting available devices.
- Enable EPG scanning = yes If you want exclude all SAT>IP devices - Enable EPG scanning = yes If you want exclude all SAT>IP devices
from VDR's EIT background scanning, set from VDR's EIT background scanning, set
this option to "no". this option to "no".
@ -72,6 +74,7 @@ Setup menu:
"Disable filter" options which allow you "Disable filter" options which allow you
to disable the individual section filters. to disable the individual section filters.
Valid range: "none" = 0 ... 7 Valid range: "none" = 0 ... 7
- [Red:Scan] Forces network scanning of SAT>IP hardware.
- [Blue:Info] Opens SAT>IP information/statistics menu. - [Blue:Info] Opens SAT>IP information/statistics menu.
- [Ok] Opens information menu of selected SAT>IP - [Ok] Opens information menu of selected SAT>IP
device. device.
@ -88,7 +91,8 @@ Notes:
- The stream id "-1" states about unsuccessful tuning. This might be a - The stream id "-1" states about unsuccessful tuning. This might be a
result of invalid channel parameters or lack of free SAT>IP tuners. result of invalid channel parameters or lack of free SAT>IP tuners.
- SAT>IP specification 1.2 doesn't support DVB-C/DVB-C2 receivers yet. - SAT>IP specification 1.2 doesn't support DVB-C/DVB-C2 receivers yet,
but DVB-C is supported for Digital Devices Octopus Net devices.
- If the plugin doesn't detect your SAT>IP network device, make sure - If the plugin doesn't detect your SAT>IP network device, make sure
your setup doesn't have firewalled the UDP port 1900. your setup doesn't have firewalled the UDP port 1900.
@ -97,7 +101,8 @@ Notes:
direct access to any DVB card devices. direct access to any DVB card devices.
- The 100% compliance against SAT>IP specification 1.2 requires a - The 100% compliance against SAT>IP specification 1.2 requires a
patched VDR. patched VDR providing channel configuration for pilot, T2 system id,
and SISO/MISO values.
Acknowledgements: Acknowledgements:

View File

@ -11,7 +11,7 @@
cSatipConfig SatipConfig; cSatipConfig SatipConfig;
cSatipConfig::cSatipConfig(void) cSatipConfig::cSatipConfig(void)
: operatingModeM(OPERATING_MODE_LOW), : operatingModeM(eOperatingModeLow),
eitScanM(1), eitScanM(1),
useBytesM(1) useBytesM(1)
{ {

View File

@ -22,19 +22,19 @@ private:
public: public:
enum { enum {
OPERATING_MODE_OFF = 0, eOperatingModeOff = 0,
OPERATING_MODE_LOW, eOperatingModeLow,
OPERATING_MODE_NORMAL, eOperatingModeNormal,
OPERATING_MODE_HIGH, eOperatingModeHigh,
NUMBER_OF_OPERATING_MODES eOperatingModeCount
}; };
cSatipConfig(); cSatipConfig();
unsigned int GetOperatingMode(void) const { return operatingModeM; } unsigned int GetOperatingMode(void) const { return operatingModeM; }
bool IsOperatingModeOff(void) const { return (operatingModeM == OPERATING_MODE_OFF); } bool IsOperatingModeOff(void) const { return (operatingModeM == eOperatingModeOff); }
bool IsOperatingModeLow(void) const { return (operatingModeM == OPERATING_MODE_LOW); } bool IsOperatingModeLow(void) const { return (operatingModeM == eOperatingModeLow); }
bool IsOperatingModeNormal(void) const { return (operatingModeM == OPERATING_MODE_NORMAL); } bool IsOperatingModeNormal(void) const { return (operatingModeM == eOperatingModeNormal); }
bool IsOperatingModeHigh(void) const { return (operatingModeM == OPERATING_MODE_HIGH); } bool IsOperatingModeHigh(void) const { return (operatingModeM == eOperatingModeHigh); }
void ToggleOperatingMode(void) { operatingModeM = (operatingModeM + 1) % NUMBER_OF_OPERATING_MODES; } void ToggleOperatingMode(void) { operatingModeM = (operatingModeM + 1) % eOperatingModeCount; }
unsigned int GetEITScan(void) const { return eitScanM; } unsigned int GetEITScan(void) const { return eitScanM; }
unsigned int GetUseBytes(void) const { return useBytesM; } unsigned int GetUseBytes(void) const { return useBytesM; }
const char *GetConfigDirectory(void) const { return configDirectoryM; } const char *GetConfigDirectory(void) const { return configDirectoryM; }

View File

@ -277,9 +277,8 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
debug("cSatipDevice::%s(%u): no suitable server found", __FUNCTION__, deviceIndexM); debug("cSatipDevice::%s(%u): no suitable server found", __FUNCTION__, deviceIndexM);
return false; return false;
} }
address = server->Address(); if (pTunerM && pTunerM->SetSource(server, *params, deviceIndexM)) {
if (pTunerM && pTunerM->SetSource(*address, *params, deviceIndexM)) { deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server));
deviceNameM = cString::sprintf("%s %d %s:%s:%s", *DeviceType(), deviceIndexM, server->Address(), server->Model(), server->Description());
channelM = *channelP; channelM = *channelP;
return true; return true;
} }

View File

@ -31,13 +31,16 @@ cSatipDiscover *cSatipDiscover::GetInstance(void)
bool cSatipDiscover::Initialize(void) bool cSatipDiscover::Initialize(void)
{ {
debug("cSatipDiscover::%s()", __FUNCTION__); debug("cSatipDiscover::%s()", __FUNCTION__);
if (instanceS)
instanceS->Activate();
return true; return true;
} }
void cSatipDiscover::Destroy(void) void cSatipDiscover::Destroy(void)
{ {
debug("cSatipDiscover::%s()", __FUNCTION__); debug("cSatipDiscover::%s()", __FUNCTION__);
DELETE_POINTER(instanceS); if (instanceS)
instanceS->Deactivate();
} }
size_t cSatipDiscover::WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP) size_t cSatipDiscover::WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP)
@ -51,6 +54,7 @@ size_t cSatipDiscover::WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, vo
char *desc = NULL, *model = NULL, *addr = NULL; char *desc = NULL, *model = NULL, *addr = NULL;
while (r) { while (r) {
//debug("cSatipDiscover::%s(%zu): %s", __FUNCTION__, len, r); //debug("cSatipDiscover::%s(%zu): %s", __FUNCTION__, len, r);
r = skipspace(r);
// <friendlyName>OctopusNet</friendlyName> // <friendlyName>OctopusNet</friendlyName>
if (startswith(r, "<friendlyName")) if (startswith(r, "<friendlyName"))
desc = StripTags(r); desc = StripTags(r);
@ -85,10 +89,8 @@ cSatipDiscover::cSatipDiscover()
cSatipDiscover::~cSatipDiscover() cSatipDiscover::~cSatipDiscover()
{ {
debug("cSatipDiscover::%s()", __FUNCTION__); debug("cSatipDiscover::%s()", __FUNCTION__);
Deactivate();
cMutexLock MutexLock(&mutexM); cMutexLock MutexLock(&mutexM);
sleepM.Signal();
if (Running())
Cancel(3);
// Free allocated memory // Free allocated memory
DELETENULL(socketM); DELETENULL(socketM);
DELETENULL(serversM); DELETENULL(serversM);
@ -97,6 +99,21 @@ cSatipDiscover::~cSatipDiscover()
handleM = NULL; handleM = NULL;
} }
void cSatipDiscover::Activate(void)
{
// Start the thread
Start();
}
void cSatipDiscover::Deactivate(void)
{
debug("cSatipDiscover::%s()", __FUNCTION__);
cMutexLock MutexLock(&mutexM);
sleepM.Signal();
if (Running())
Cancel(3);
}
void cSatipDiscover::Action(void) void cSatipDiscover::Action(void)
{ {
debug("cSatipDiscover::%s(): entering", __FUNCTION__); debug("cSatipDiscover::%s(): entering", __FUNCTION__);
@ -117,12 +134,8 @@ void cSatipDiscover::Janitor(void)
{ {
debug("cSatipDiscover::%s()", __FUNCTION__); debug("cSatipDiscover::%s()", __FUNCTION__);
cMutexLock MutexLock(&mutexM); cMutexLock MutexLock(&mutexM);
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) { if (serversM)
if (srv->LastSeen() > eProbeIntervalMs * 2) { serversM->Cleanup(eProbeIntervalMs * 2);
info("Removing device %s (%s %s)", srv->Description(), srv->Address(), srv->Model());
serversM->Del(srv);
}
}
} }
void cSatipDiscover::Probe(void) void cSatipDiscover::Probe(void)
@ -213,15 +226,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *descP, const char
if (serversM) { if (serversM) {
cSatipServer *tmp = new cSatipServer(addrP, descP, modelP); cSatipServer *tmp = new cSatipServer(addrP, descP, modelP);
// Validate against existing servers // Validate against existing servers
bool found = false; if (!serversM->Update(tmp)) {
for (cSatipServer *s = serversM->First(); s; s = serversM->Next(s)) {
if (s->Compare(*tmp) == 0) {
found = true;
s->Update();
break;
}
}
if (!found) {
info("Adding device %s (%s %s)", tmp->Description(), tmp->Address(), tmp->Model()); info("Adding device %s (%s %s)", tmp->Description(), tmp->Address(), tmp->Model());
serversM->Add(tmp); serversM->Add(tmp);
} }
@ -230,35 +235,18 @@ void cSatipDiscover::AddServer(const char *addrP, const char *descP, const char
} }
} }
bool cSatipDiscover::IsValidServer(cSatipServer *serverP)
{
//debug("cSatipDiscover::%s(%d)", __FUNCTION__);
cMutexLock MutexLock(&mutexM);
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) {
if (srv == serverP)
return true;
}
return false;
}
cSatipServer *cSatipDiscover::GetServer(int sourceP, int systemP) cSatipServer *cSatipDiscover::GetServer(int sourceP, int systemP)
{ {
//debug("cSatipDiscover::%s(%d, %d)", __FUNCTION__, sourceP, systemP); //debug("cSatipDiscover::%s(%d, %d)", __FUNCTION__, sourceP, systemP);
cMutexLock MutexLock(&mutexM); cMutexLock MutexLock(&mutexM);
int model = 0; return serversM ? serversM->Find(sourceP, systemP) : NULL;
if (cSource::IsType(sourceP, 'S')) }
model |= cSatipServer::eSatipModelTypeDVBS2;
if (cSource::IsType(sourceP, 'T')) { cSatipServer *cSatipDiscover::GetServer(cSatipServer *serverP)
if (systemP < 0) {
model |= cSatipServer::eSatipModelTypeDVBT2 | cSatipServer::eSatipModelTypeDVBT; //debug("cSatipDiscover::%s()", __FUNCTION__);
else cMutexLock MutexLock(&mutexM);
model |= systemP ? cSatipServer::eSatipModelTypeDVBT2 : cSatipServer::eSatipModelTypeDVBT; return serversM ? serversM->Find(serverP) : NULL;
}
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) {
if (srv->Match(model))
return srv;
}
return NULL;
} }
cSatipServers *cSatipDiscover::GetServers(void) cSatipServers *cSatipDiscover::GetServers(void)
@ -268,27 +256,31 @@ cSatipServers *cSatipDiscover::GetServers(void)
return serversM; return serversM;
} }
cString cSatipDiscover::GetServerString(cSatipServer *serverP)
{
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
cMutexLock MutexLock(&mutexM);
return serversM ? serversM->GetString(serverP) : "";
}
cString cSatipDiscover::GetServerList(void) cString cSatipDiscover::GetServerList(void)
{ {
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP); //debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
cMutexLock MutexLock(&mutexM); cMutexLock MutexLock(&mutexM);
cString list = ""; return serversM ? serversM->List() : "";
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) }
list = cString::sprintf("%s%s:%s:%s\n", *list, srv->Address(), srv->Model(), srv->Description());
return list; void cSatipDiscover::UseServer(cSatipServer *serverP, bool onOffP)
{
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
cMutexLock MutexLock(&mutexM);
if (serversM)
serversM->Use(serverP, onOffP);
} }
int cSatipDiscover::NumProvidedSystems(void) int cSatipDiscover::NumProvidedSystems(void)
{ {
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP); //debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
cMutexLock MutexLock(&mutexM); cMutexLock MutexLock(&mutexM);
int count = 0; return serversM ? serversM->NumProvidedSystems() : 0;
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) {
// DVB-S*: qpsk, 8psk
count += srv->Satellite() * 4;
// DVB-T*: qpsk, qam16, qam64, qam256
count += (srv->Terrestrial2() ? srv->Terrestrial2() : srv->Terrestrial()) * 4;
}
count = 1;
return count;
} }

View File

@ -9,79 +9,13 @@
#define __SATIP_DISCOVER_H #define __SATIP_DISCOVER_H
#include <curl/curl.h> #include <curl/curl.h>
#include <curl/easy.h>
#include <vdr/thread.h> #include <vdr/thread.h>
#include <vdr/tools.h> #include <vdr/tools.h>
#include "server.h"
#include "socket.h" #include "socket.h"
class cSatipServer : public cListObject {
private:
enum eSatipServer {
eSatipServerDVBS2 = 0,
eSatipServerDVBT,
eSatipServerDVBT2,
eSatipServerCount
};
cString addressM;
cString descriptionM;
cString modelM;
int modelCountM[eSatipServerCount];
int modelTypeM;
cTimeMs lastSeenM;
public:
enum eSatipModelType {
eSatipModelTypeDVBS2 = 0x01,
eSatipModelTypeDVBT = 0x02,
eSatipModelTypeDVBT2 = 0x04,
eSatipModelTypeMask = 0x0F
};
cSatipServer(const char *addressP, const char *descriptionP, const char *modelP) : addressM(addressP), descriptionM(descriptionP), modelM(modelP), modelTypeM(eSatipModelTypeMask), lastSeenM(0)
{
memset(modelCountM, 0, sizeof(modelCountM));
if (isempty(*modelM))
modelM = "DVBS-1,DVBT2-1";
char *s, *p = strdup(*modelM);
char *r = strtok_r(p, ",", &s);
while (r) {
if (strstr(r, "DVBS2")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBS2;
if (char *c = strstr(r, "-"))
modelCountM[eSatipServerDVBS2] = atoi(++c);
}
if (strstr(r, "DVBT2")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBT | cSatipServer::eSatipModelTypeDVBT2;
if (char *c = strstr(r, "-"))
modelCountM[eSatipServerDVBT2] = atoi(++c);
}
if (strstr(r, "DVBT")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBT;
if (char *c = strstr(r, "-"))
modelCountM[eSatipServerDVBT] = atoi(++c);
}
r = strtok_r(NULL, ",", &s);
}
free(p);
}
virtual int Compare(const cListObject &listObjectP) const { const cSatipServer *s = (const cSatipServer *)&listObjectP; return strcasecmp(*addressM, *s->addressM); }
const char *Description() { return *descriptionM; }
const char *Address() { return *addressM; }
const char *Model(void) { return modelM; }
int ModelType(void) { return modelTypeM; }
bool Match(int modelP) { return ((modelP & eSatipModelTypeMask) & modelTypeM); }
int Satellite() { return (modelTypeM & eSatipModelTypeDVBS2) ? modelCountM[eSatipServerDVBS2] : 0; }
int Terrestrial() { return (modelTypeM & eSatipModelTypeDVBT) ? modelCountM[eSatipServerDVBT] : 0; }
int Terrestrial2() { return (modelTypeM & eSatipModelTypeDVBT2) ? modelCountM[eSatipServerDVBT2] : 0; }
int LastSeen(void) { return lastSeenM.Elapsed(); }
void Update(void) { lastSeenM.Set(); }
};
class cSatipServers : public cList<cSatipServer> {
};
class cSatipDiscover : public cThread { class cSatipDiscover : public cThread {
private: private:
enum { enum {
@ -101,6 +35,8 @@ private:
cCondWait sleepM; cCondWait sleepM;
cTimeMs probeIntervalM; cTimeMs probeIntervalM;
cSatipServers *serversM; cSatipServers *serversM;
void Activate(void);
void Deactivate(void);
void Janitor(void); void Janitor(void);
void Probe(void); void Probe(void);
void Read(void); void Read(void);
@ -119,9 +55,12 @@ public:
static bool Initialize(void); static bool Initialize(void);
static void Destroy(void); static void Destroy(void);
virtual ~cSatipDiscover(); virtual ~cSatipDiscover();
bool IsValidServer(cSatipServer *serverP); void TriggerScan(void) { probeIntervalM.Set(0); }
cSatipServer *GetServer(int sourceP, int systemP = -1); cSatipServer *GetServer(int sourceP, int systemP = -1);
cSatipServer *GetServer(cSatipServer *serverP);
cSatipServers *GetServers(void); cSatipServers *GetServers(void);
cString GetServerString(cSatipServer *serverP);
void UseServer(cSatipServer *serverP, bool onOffP);
cString GetServerList(void); cString GetServerList(void);
int NumProvidedSystems(void); int NumProvidedSystems(void);
}; };

141
param.c
View File

@ -18,94 +18,101 @@ struct tSatipParameterMap {
}; };
static const tSatipParameterMap SatipBandwidthValues[] = { static const tSatipParameterMap SatipBandwidthValues[] = {
{ 5000000, "bw=5" }, { 5000000, "&bw=5" },
{ 6000000, "bw=6" }, { 6000000, "&bw=6" },
{ 7000000, "bw=7" }, { 7000000, "&bw=7" },
{ 8000000, "bw=8" }, { 8000000, "&bw=8" },
{ 10000000, "bw=10" }, { 10000000, "&bw=10" },
{ 1712000, "bw=1.712" }, { 1712000, "&bw=1.712" },
{ -1, NULL } { -1, NULL }
}; };
static const tSatipParameterMap SatipPilotValues[] = { static const tSatipParameterMap SatipPilotValues[] = {
{ PILOT_OFF, "plts=off" }, { PILOT_OFF, "&plts=off" },
{ PILOT_ON, "plts=on" }, { PILOT_ON, "&plts=on" },
{ PILOT_AUTO, "" }, { PILOT_AUTO, "" },
{ -1, NULL } { -1, NULL }
}; };
static const tSatipParameterMap SatipSisoMisoValues[] = { static const tSatipParameterMap SatipSisoMisoValues[] = {
{ 0, "sm=0" }, { 0, "&sm=0" },
{ 1, "sm=1" }, { 1, "&sm=1" },
{ -1, NULL } { -1, NULL }
}; };
static const tSatipParameterMap SatipCodeRateValues[] = { static const tSatipParameterMap SatipCodeRateValues[] = {
{ FEC_NONE, "" }, { FEC_NONE, "" },
{ FEC_1_2, "fec=12" }, { FEC_1_2, "&fec=12" },
{ FEC_2_3, "fec=23" }, { FEC_2_3, "&fec=23" },
{ FEC_3_4, "fec=34" }, { FEC_3_4, "&fec=34" },
{ FEC_3_5, "fec=35" }, { FEC_3_5, "&fec=35" },
{ FEC_4_5, "fec=45" }, { FEC_4_5, "&fec=45" },
{ FEC_5_6, "fec=56" }, { FEC_5_6, "&fec=56" },
{ FEC_6_7, "fec=67" }, { FEC_6_7, "&fec=67" },
{ FEC_7_8, "fec=78" }, { FEC_7_8, "&fec=78" },
{ FEC_8_9, "fec=89" }, { FEC_8_9, "&fec=89" },
{ FEC_9_10, "fec=910" }, { FEC_9_10, "&fec=910" },
{ FEC_AUTO, "" }, { FEC_AUTO, "" },
{ -1, NULL } { -1, NULL }
}; };
static const tSatipParameterMap SatipModulationValues[] = { static const tSatipParameterMap SatipModulationValues[] = {
{ QPSK, "mtype=qpsk" }, { QPSK, "&mtype=qpsk" },
{ PSK_8, "mtype=8psk" }, { PSK_8, "&mtype=8psk" },
{ QAM_16, "mtype=16qam" }, { QAM_16, "&mtype=16qam" },
{ QAM_64, "mtype=64qam" }, { QAM_64, "&mtype=64qam" },
{ QAM_256, "mtype=256qam" }, { QAM_128, "&mtype=128qam" },
{ QAM_256, "&mtype=256qam" },
{ QAM_AUTO, "" }, { QAM_AUTO, "" },
{ -1, NULL } { -1, NULL }
}; };
static const tSatipParameterMap SatipSystemValuesSat[] = { static const tSatipParameterMap SatipSystemValuesSat[] = {
{ 0, "msys=dvbs" }, { 0, "&msys=dvbs" },
{ 1, "msys=dvbs2" }, { 1, "&msys=dvbs2" },
{ -1, NULL } { -1, NULL }
}; };
static const tSatipParameterMap SatipSystemValuesTerr[] = { static const tSatipParameterMap SatipSystemValuesTerrestrial[] = {
{ 0, "msys=dvbt" }, { 0, "&msys=dvbt" },
{ 1, "msys=dvbt2" }, { 1, "&msys=dvbt2" },
{ -1, NULL }
};
static const tSatipParameterMap SatipSystemValuesCable[] = {
{ 0, "&msys=dvbc" },
{ 1, "&msys=dvbc2" },
{ -1, NULL } { -1, NULL }
}; };
static const tSatipParameterMap SatipTransmissionValues[] = { static const tSatipParameterMap SatipTransmissionValues[] = {
{ TRANSMISSION_MODE_1K, "tmode=1k" }, { TRANSMISSION_MODE_1K, "&tmode=1k" },
{ TRANSMISSION_MODE_2K, "tmode=2k" }, { TRANSMISSION_MODE_2K, "&tmode=2k" },
{ TRANSMISSION_MODE_4K, "tmode=4k" }, { TRANSMISSION_MODE_4K, "&tmode=4k" },
{ TRANSMISSION_MODE_8K, "tmode=8k" }, { TRANSMISSION_MODE_8K, "&tmode=8k" },
{ TRANSMISSION_MODE_16K, "tmode=16k" }, { TRANSMISSION_MODE_16K, "&tmode=16k" },
{ TRANSMISSION_MODE_32K, "tmode=32k" }, { TRANSMISSION_MODE_32K, "&tmode=32k" },
{ TRANSMISSION_MODE_AUTO, "" }, { TRANSMISSION_MODE_AUTO, "" },
{ -1, NULL } { -1, NULL }
}; };
static const tSatipParameterMap SatipGuardValues[] = { static const tSatipParameterMap SatipGuardValues[] = {
{ GUARD_INTERVAL_1_4, "gi=14" }, { GUARD_INTERVAL_1_4, "&gi=14" },
{ GUARD_INTERVAL_1_8, "gi=18" }, { GUARD_INTERVAL_1_8, "&gi=18" },
{ GUARD_INTERVAL_1_16, "gi=116" }, { GUARD_INTERVAL_1_16, "&gi=116" },
{ GUARD_INTERVAL_1_32, "gi=132" }, { GUARD_INTERVAL_1_32, "&gi=132" },
{ GUARD_INTERVAL_1_128, "gi=1128" }, { GUARD_INTERVAL_1_128, "&gi=1128" },
{ GUARD_INTERVAL_19_128, "gi=19128" }, { GUARD_INTERVAL_19_128, "&gi=19128" },
{ GUARD_INTERVAL_19_256, "gi=19256" }, { GUARD_INTERVAL_19_256, "&gi=19256" },
{ GUARD_INTERVAL_AUTO, "" }, { GUARD_INTERVAL_AUTO, "" },
{ -1, NULL } { -1, NULL }
}; };
static const tSatipParameterMap SatipRollOffValues[] = { static const tSatipParameterMap SatipRollOffValues[] = {
{ ROLLOFF_AUTO, "" }, { ROLLOFF_AUTO, "" },
{ ROLLOFF_20, "ro=0.20" }, { ROLLOFF_20, "&ro=0.20" },
{ ROLLOFF_25, "ro=0.25" }, { ROLLOFF_25, "&ro=0.25" },
{ ROLLOFF_35, "ro=0.35" }, { ROLLOFF_35, "&ro=0.35" },
{ -1, NULL } { -1, NULL }
}; };
@ -120,15 +127,16 @@ static int SatipUserIndex(int valueP, const tSatipParameterMap *mapP)
return -1; return -1;
} }
static int PrintUrlString(char *ptrP, int valueP, const tSatipParameterMap *mapP) static int PrintUrlString(char *bufP, int lenP, int valueP, const tSatipParameterMap *mapP)
{ {
int n = SatipUserIndex(valueP, mapP); int n = SatipUserIndex(valueP, mapP);
return (n >= 0) ? sprintf(ptrP, "&%s", tr(mapP[n].satipString)) : 0; return ((n >= 0) && (lenP > 0)) ? snprintf(bufP, lenP, "%s", mapP[n].satipString) : 0;
} }
cString GetTransponderUrlParameters(const cChannel *channelP) cString GetTransponderUrlParameters(const cChannel *channelP)
{ {
if (channelP) { if (channelP) {
char buffer[255];
cDvbTransponderParameters dtp(channelP->Parameters()); cDvbTransponderParameters dtp(channelP->Parameters());
int Pilot = PILOT_AUTO; // should be added into cDvbTransponderParameters int Pilot = PILOT_AUTO; // should be added into cDvbTransponderParameters
int T2SystemId = 0; // should be added into cDvbTransponderParameters int T2SystemId = 0; // should be added into cDvbTransponderParameters
@ -137,30 +145,31 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
char type = cSource::ToChar(channelP->Source()); char type = cSource::ToChar(channelP->Source());
cSource *source = Sources.Get(channelP->Source()); cSource *source = Sources.Get(channelP->Source());
int src = (strchr("S", type) && source) ? atoi(source->Description()) : 1; int src = (strchr("S", type) && source) ? atoi(source->Description()) : 1;
char buffer[255];
char *q = buffer; char *q = buffer;
*q = 0; *q = 0;
// Scale down frequencies to MHz // Scale down frequencies to MHz
while (freq > 20000L) while (freq > 20000L)
freq /= 1000L; freq /= 1000L;
q += sprintf(q, "freq=%s", *dtoa(freq, "%.3f"));
#define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*'))) #define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*')))
ST("S *") q += sprintf(q, "&src=%d", ((src > 0) && (src <= 255)) ? src : 1); #define STBUFLEFT (sizeof(buffer) - (q - buffer))
ST("S *") q += sprintf(q, "&sr=%d", channelP->Srate()); q += snprintf(q, STBUFLEFT, "freq=%s", *dtoa(freq, "%.3f"));
ST("S *") q += sprintf(q, "&pol=%c", tolower(dtp.Polarization())); ST(" S *") q += snprintf(q, STBUFLEFT, "&src=%d", ((src > 0) && (src <= 255)) ? src : 1);
ST(" T2") q += sprintf(q, "&plp=%d", dtp.StreamId()); ST("CS *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
ST(" T2") q += sprintf(q, "&t2id=%d", T2SystemId); ST(" S *") q += snprintf(q, STBUFLEFT, "&pol=%c", tolower(dtp.Polarization()));
ST(" T2") q += PrintUrlString(q, SisoMiso, SatipSisoMisoValues); ST("C T2") q += snprintf(q, STBUFLEFT, "&plp=%d", dtp.StreamId());
ST(" T*") q += PrintUrlString(q, dtp.Bandwidth(), SatipBandwidthValues); ST(" T2") q += snprintf(q, STBUFLEFT, "&t2id=%d", T2SystemId);
ST(" T*") q += PrintUrlString(q, dtp.Guard(), SatipGuardValues); ST(" T2") q += PrintUrlString(q, STBUFLEFT, SisoMiso, SatipSisoMisoValues);
ST("ST*") q += PrintUrlString(q, dtp.CoderateH(), SatipCodeRateValues); ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Bandwidth(), SatipBandwidthValues);
ST("S 2") q += PrintUrlString(q, Pilot, SatipPilotValues); ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Guard(), SatipGuardValues);
ST("S 2") q += PrintUrlString(q, dtp.Modulation(), SatipModulationValues); ST("CST*") q += PrintUrlString(q, STBUFLEFT, dtp.CoderateH(), SatipCodeRateValues);
ST(" T*") q += PrintUrlString(q, dtp.Modulation(), SatipModulationValues); ST(" S 2") q += PrintUrlString(q, STBUFLEFT, Pilot, SatipPilotValues);
ST("S 2") q += PrintUrlString(q, dtp.RollOff(), SatipRollOffValues); ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
ST("S *") q += PrintUrlString(q, dtp.System(), SatipSystemValuesSat); ST("C T*") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
ST(" T*") q += PrintUrlString(q, dtp.System(), SatipSystemValuesTerr); ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.RollOff(), SatipRollOffValues);
ST(" T*") q += PrintUrlString(q, dtp.Transmission(), SatipTransmissionValues); ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesSat);
ST("C *") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesCable);
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesTerrestrial);
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Transmission(), SatipTransmissionValues);
#undef ST #undef ST
return buffer; return buffer;
} }

View File

@ -5,7 +5,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-satip 0.0.2\n" "Project-Id-Version: vdr-satip 0.1.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2014-03-15 03:15+0200\n" "POT-Creation-Date: 2014-03-15 03:15+0200\n"
"PO-Revision-Date: 2014-03-15 03:15+0200\n" "PO-Revision-Date: 2014-03-15 03:15+0200\n"
@ -43,6 +43,18 @@ msgstr "SAT>IP Geräte"
msgid "SAT>IP Device" msgid "SAT>IP Device"
msgstr "SAT>IP Gerät" msgstr "SAT>IP Gerät"
msgid "Address"
msgstr "Adresse"
msgid "Model"
msgstr "Modell"
msgid "Description"
msgstr "Beschreibung"
msgid "Creation date"
msgstr "Erstellungsdatum"
msgid "SAT>IP Information" msgid "SAT>IP Information"
msgstr "SAT>IP Informationen" msgstr "SAT>IP Informationen"

View File

@ -5,7 +5,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-satip 0.0.2\n" "Project-Id-Version: vdr-satip 0.1.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2014-03-15 03:15+0200\n" "POT-Creation-Date: 2014-03-15 03:15+0200\n"
"PO-Revision-Date: 2014-03-15 03:15+0200\n" "PO-Revision-Date: 2014-03-15 03:15+0200\n"
@ -43,6 +43,18 @@ msgstr "SAT>IP-laitteet"
msgid "SAT>IP Device" msgid "SAT>IP Device"
msgstr "SAT>IP-laite" msgstr "SAT>IP-laite"
msgid "Address"
msgstr "Osoite"
msgid "Model"
msgstr "Malli"
msgid "Description"
msgstr "Kuvaus"
msgid "Creation date"
msgstr "Luontiajankohta"
msgid "SAT>IP Information" msgid "SAT>IP Information"
msgstr "SAT>IP-tiedot" msgstr "SAT>IP-tiedot"

10
satip.c
View File

@ -21,7 +21,7 @@
#define GITVERSION "" #define GITVERSION ""
#endif #endif
const char VERSION[] = "0.0.2" GITVERSION; const char VERSION[] = "0.1.0" GITVERSION;
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices"); static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
class cPluginSatip : public cPlugin { class cPluginSatip : public cPlugin {
@ -292,16 +292,16 @@ cString cPluginSatip::SVDRPCommand(const char *commandP, const char *optionP, in
cString mode; cString mode;
SatipConfig.ToggleOperatingMode(); SatipConfig.ToggleOperatingMode();
switch (SatipConfig.GetOperatingMode()) { switch (SatipConfig.GetOperatingMode()) {
case cSatipConfig::OPERATING_MODE_OFF: case cSatipConfig::eOperatingModeOff:
mode = "off"; mode = "off";
break; break;
case cSatipConfig::OPERATING_MODE_LOW: case cSatipConfig::eOperatingModeLow:
mode = "low"; mode = "low";
break; break;
case cSatipConfig::OPERATING_MODE_NORMAL: case cSatipConfig::eOperatingModeNormal:
mode = "normal"; mode = "normal";
break; break;
case cSatipConfig::OPERATING_MODE_HIGH: case cSatipConfig::eOperatingModeHigh:
mode = "high"; mode = "high";
break; break;
default: default:

View File

@ -33,11 +33,11 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
filterMaskM[0] = maskP; filterMaskM[0] = maskP;
// Invert the filter // Invert the filter
for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i) for (i = 0; i < eDmxMaxFilterSize; ++i)
filterValueM[i] ^= 0xFF; filterValueM[i] ^= 0xFF;
uint8_t mask, mode, doneq = 0; uint8_t mask, mode, doneq = 0;
for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i) { for (i = 0; i < eDmxMaxFilterSize; ++i) {
mode = filterModeM[i]; mode = filterModeM[i];
mask = filterMaskM[i]; mask = filterMaskM[i];
maskAndModeM[i] = (uint8_t)(mask & mode); maskAndModeM[i] = (uint8_t)(mask & mode);
@ -89,7 +89,7 @@ int cSatipSectionFilter::Filter(void)
int i; int i;
uint8_t neq = 0; uint8_t neq = 0;
for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i) { for (i = 0; i < eDmxMaxFilterSize; ++i) {
uint8_t calcxor = (uint8_t)(filterValueM[i] ^ secBufM[i]); uint8_t calcxor = (uint8_t)(filterValueM[i] ^ secBufM[i]);
if (maskAndModeM[i] & calcxor) if (maskAndModeM[i] & calcxor)
return 0; return 0;
@ -122,11 +122,11 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
{ {
uint16_t limit, seclen, n; uint16_t limit, seclen, n;
if (tsFeedpM >= DMX_MAX_SECFEED_SIZE) if (tsFeedpM >= eDmxMaxSectionFeedSize)
return 0; return 0;
if (tsFeedpM + lenP > DMX_MAX_SECFEED_SIZE) if (tsFeedpM + lenP > eDmxMaxSectionFeedSize)
lenP = (uint8_t)(DMX_MAX_SECFEED_SIZE - tsFeedpM); lenP = (uint8_t)(eDmxMaxSectionFeedSize - tsFeedpM);
if (lenP <= 0) if (lenP <= 0)
return 0; return 0;
@ -135,7 +135,7 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
tsFeedpM = uint16_t(tsFeedpM + lenP); tsFeedpM = uint16_t(tsFeedpM + lenP);
limit = tsFeedpM; limit = tsFeedpM;
if (limit > DMX_MAX_SECFEED_SIZE) if (limit > eDmxMaxSectionFeedSize)
return -1; // internal error should never happen return -1; // internal error should never happen
// Always set secbuf // Always set secbuf
@ -143,7 +143,7 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
for (n = 0; secBufpM + 2 < limit; ++n) { for (n = 0; secBufpM + 2 < limit; ++n) {
seclen = GetLength(secBufM); seclen = GetLength(secBufM);
if ((seclen <= 0) || (seclen > DMX_MAX_SECTION_SIZE) || ((seclen + secBufpM) > limit)) if ((seclen <= 0) || (seclen > eDmxMaxSectionSize) || ((seclen + secBufpM) > limit))
return 0; return 0;
secLenM = seclen; secLenM = seclen;
if (pusiSeenM) if (pusiSeenM)

View File

@ -19,9 +19,9 @@
class cSatipSectionFilter : public cSatipSectionStatistics { class cSatipSectionFilter : public cSatipSectionStatistics {
private: private:
enum dmx_limits { enum dmx_limits {
DMX_MAX_FILTER_SIZE = 18, eDmxMaxFilterSize = 18,
DMX_MAX_SECTION_SIZE = 4096, eDmxMaxSectionSize = 4096,
DMX_MAX_SECFEED_SIZE = (DMX_MAX_SECTION_SIZE + TS_SIZE) eDmxMaxSectionFeedSize = (eDmxMaxSectionSize + TS_SIZE)
}; };
int pusiSeenM; int pusiSeenM;
@ -29,7 +29,7 @@ private:
int doneqM; int doneqM;
uint8_t *secBufM; uint8_t *secBufM;
uint8_t secBufBaseM[DMX_MAX_SECFEED_SIZE]; uint8_t secBufBaseM[eDmxMaxSectionFeedSize];
uint16_t secBufpM; uint16_t secBufpM;
uint16_t secLenM; uint16_t secLenM;
uint16_t tsFeedpM; uint16_t tsFeedpM;
@ -38,12 +38,12 @@ private:
int deviceIndexM; int deviceIndexM;
int socketM[2]; int socketM[2];
uint8_t filterValueM[DMX_MAX_FILTER_SIZE]; uint8_t filterValueM[eDmxMaxFilterSize];
uint8_t filterMaskM[DMX_MAX_FILTER_SIZE]; uint8_t filterMaskM[eDmxMaxFilterSize];
uint8_t filterModeM[DMX_MAX_FILTER_SIZE]; uint8_t filterModeM[eDmxMaxFilterSize];
uint8_t maskAndModeM[DMX_MAX_FILTER_SIZE]; uint8_t maskAndModeM[eDmxMaxFilterSize];
uint8_t maskAndNotModeM[DMX_MAX_FILTER_SIZE]; uint8_t maskAndNotModeM[eDmxMaxFilterSize];
inline uint16_t GetLength(const uint8_t *dataP); inline uint16_t GetLength(const uint8_t *dataP);
void New(void); void New(void);

177
server.c Normal file
View File

@ -0,0 +1,177 @@
/*
* 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>
#include "common.h"
#include "server.h"
// --- cSatipServer -----------------------------------------------------------
cSatipServer::cSatipServer(const char *addressP, const char *descriptionP, const char *modelP)
: addressM(addressP),
descriptionM(descriptionP),
modelM(modelP),
modelTypeM(eSatipModelTypeMask),
useCountM(0),
createdM(time(NULL)),
lastSeenM(0)
{
memset(modelCountM, 0, sizeof(modelCountM));
if (isempty(*modelM))
modelM = "DVBS-1";
char *s, *p = strdup(*modelM);
char *r = strtok_r(p, ",", &s);
while (r) {
if (strstr(r, "DVBS2")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBS2;
if (char *c = strstr(r, "-"))
modelCountM[eSatipModuleDVBS2] = atoi(++c);
else
modelCountM[eSatipModuleDVBS2] = 1;
}
if (strstr(r, "DVBT2")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBT | cSatipServer::eSatipModelTypeDVBT2;
if (char *c = strstr(r, "-"))
modelCountM[eSatipModuleDVBT2] = atoi(++c);
else
modelCountM[eSatipModuleDVBT2] = 1;
// Add model quirks here
if (strstr(*addressM, "OctopusNet"))
modelTypeM |= cSatipServer::eSatipModelTypeDVBC;
}
if (strstr(r, "DVBT")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBT;
if (char *c = strstr(r, "-"))
modelCountM[eSatipModuleDVBT] = atoi(++c);
else
modelCountM[eSatipModuleDVBT] = 1;
// Add model quirks here
if (strstr(*addressM, "OctopusNet"))
modelTypeM |= cSatipServer::eSatipModelTypeDVBC;
}
r = strtok_r(NULL, ",", &s);
}
free(p);
}
cSatipServer::~cSatipServer()
{
}
int cSatipServer::Compare(const cListObject &listObjectP) const
{
const cSatipServer *s = (const cSatipServer *)&listObjectP;
return strcasecmp(*addressM, *s->addressM);
}
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;
}
cSatipServer *cSatipServers::Find(int sourceP, int systemP)
{
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)) {
result = s;
if (!s->Used()) {
break;
}
}
}
return result;
}
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)) {
info("Removing device %s (%s %s)", s->Description(), s->Address(), s->Model());
Del(s);
}
}
}
cString cSatipServers::GetString(cSatipServer *serverP)
{
cString list = "";
for (cSatipServer *s = First(); s; s = Next(s)) {
if (s == serverP) {
list = cString::sprintf("%s:%s:%s", s->Address(), s->Model(), s->Description());
break;
}
}
return list;
}
cString cSatipServers::List(void)
{
cString list = "";
for (cSatipServer *s = First(); s; s = Next(s))
list = cString::sprintf("%s%s:%s:%s\n", *list, s->Address(), s->Model(), s->Description());
return list;
}
int cSatipServers::NumProvidedSystems(void)
{
int count = 0;
for (cSatipServer *s = First(); s; s = Next(s)) {
// DVB-S*: qpsk, 8psk
count += s->Satellite() * 4;
// DVB-T*: qpsk, qam16, qam64, qam256
count += (s->Terrestrial2() ? s->Terrestrial2() : s->Terrestrial()) * 4;
}
return count;
}

71
server.h Normal file
View File

@ -0,0 +1,71 @@
/*
* server.h: SAT>IP plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#ifndef __SATIP_SERVER_H
#define __SATIP_SERVER_H
// --- cSatipServer -----------------------------------------------------------
class cSatipServer : public cListObject {
private:
enum eSatipModule {
eSatipModuleDVBS2 = 0,
eSatipModuleDVBT,
eSatipModuleDVBT2,
eSatipModuleCount
};
cString addressM;
cString descriptionM;
cString modelM;
int modelCountM[eSatipModuleCount];
int modelTypeM;
int useCountM;
time_t createdM;
cTimeMs lastSeenM;
public:
enum eSatipModelType {
eSatipModelTypeDVBS2 = 0x01,
eSatipModelTypeDVBT = 0x02,
eSatipModelTypeDVBT2 = 0x04,
eSatipModelTypeDVBC = 0x08,
eSatipModelTypeMask = 0x0F
};
cSatipServer(const char *addressP, const char *descriptionP, const char *modelP);
virtual ~cSatipServer();
virtual int Compare(const cListObject &listObjectP) const;
void Use(bool onOffP);
bool Used(void) { return !!useCountM; }
const char *Description() { return *descriptionM; }
const char *Address() { return *addressM; }
const char *Model(void) { return modelM; }
int ModelType(void) { return modelTypeM; }
bool Match(int modelP) { return ((modelP & eSatipModelTypeMask) & modelTypeM); }
int Cable() { return Match(eSatipModelTypeDVBC) ? (Match(eSatipModelTypeDVBT2) ? modelCountM[eSatipModuleDVBT2] : modelCountM[eSatipModuleDVBT]) : 0; } // an ugly hack
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; }
};
// --- cSatipServers ----------------------------------------------------------
class cSatipServers : public cList<cSatipServer> {
public:
cSatipServer *Find(cSatipServer *serverP);
cSatipServer *Find(int sourceP, int systemP);
cSatipServer *Update(cSatipServer *serverP);
void Use(cSatipServer *serverP, bool onOffP);
void Cleanup(uint64_t intervalMsP = 0);
cString GetString(cSatipServer *serverP);
cString List(void);
int NumProvidedSystems(void);
};
#endif // __SATIP_SERVER_H

76
setup.c
View File

@ -19,32 +19,27 @@
class cSatipServerInfo : public cOsdMenu class cSatipServerInfo : public cOsdMenu
{ {
private: private:
enum { cString addressM;
INFO_TIMEOUT_MS = 2000 cString modelM;
}; cString descriptionM;
cString textM; uint64_t createdM;
cTimeMs timeoutM; void Setup(void);
public: public:
cSatipServerInfo(cSatipServer *serverP); cSatipServerInfo(cSatipServer *serverP);
virtual ~cSatipServerInfo(); virtual ~cSatipServerInfo();
virtual void Display(void);
virtual eOSState ProcessKey(eKeys keyP); virtual eOSState ProcessKey(eKeys keyP);
}; };
cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP) cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP)
: cOsdMenu(tr("SAT>IP Device")), : cOsdMenu(tr("SAT>IP Device"), 20),
textM("") addressM(serverP ? serverP->Address() : "---"),
modelM(serverP ? serverP->Model() : "---"),
descriptionM(serverP ? serverP->Description() : "---"),
createdM(serverP ? serverP->Created() : 0)
{ {
SetMenuCategory(mcText); SetMenuCategory(mcSetupPlugins);
if (serverP) { Setup();
if (serverP->Model())
textM = cString::sprintf("%s\nModel:\t%s", *textM, serverP->Model());
if (serverP->Address())
textM = cString::sprintf("%s\nAddress:\t%s", *textM, serverP->Address());
if (serverP->Description())
textM = cString::sprintf("%s\nDescription:\t%s", *textM, serverP->Description());
}
SetHelp(NULL, NULL, NULL, NULL); SetHelp(NULL, NULL, NULL, NULL);
} }
@ -52,12 +47,12 @@ cSatipServerInfo::~cSatipServerInfo()
{ {
} }
void cSatipServerInfo::Display(void) void cSatipServerInfo::Setup(void)
{ {
cOsdMenu::Display(); Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Address"), *addressM), osUnknown, false));
DisplayMenu()->SetText(textM, true); Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Model"), *modelM), osUnknown, false));
if (*textM) Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Description"), *descriptionM), osUnknown, false));
cStatus::MsgOsdTextItem(textM); Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Creation date"), *DayDateTime(createdM)), osUnknown, false));
} }
eOSState cSatipServerInfo::ProcessKey(eKeys keyP) eOSState cSatipServerInfo::ProcessKey(eKeys keyP)
@ -66,10 +61,8 @@ eOSState cSatipServerInfo::ProcessKey(eKeys keyP)
if (state == osUnknown) { if (state == osUnknown) {
switch (keyP) { switch (keyP) {
case kOk: return osBack; case kOk: state = osBack; break;
case kRed: default: state = osContinue; break;
default: state = osContinue;
break;
} }
} }
return state; return state;
@ -107,7 +100,7 @@ class cSatipMenuInfo : public cOsdMenu
{ {
private: private:
enum { enum {
INFO_TIMEOUT_MS = 2000 eInfoTimeoutMs = 2000
}; };
cString textM; cString textM;
cTimeMs timeoutM; cTimeMs timeoutM;
@ -128,7 +121,7 @@ cSatipMenuInfo::cSatipMenuInfo()
pageM(SATIP_DEVICE_INFO_GENERAL) pageM(SATIP_DEVICE_INFO_GENERAL)
{ {
SetMenuCategory(mcText); SetMenuCategory(mcText);
timeoutM.Set(INFO_TIMEOUT_MS); timeoutM.Set(eInfoTimeoutMs);
UpdateInfo(); UpdateInfo();
SetHelp(tr("General"), tr("Pids"), tr("Filters"), tr("Bits/bytes")); SetHelp(tr("General"), tr("Pids"), tr("Filters"), tr("Bits/bytes"));
} }
@ -145,7 +138,7 @@ void cSatipMenuInfo::UpdateInfo()
else else
textM = cString(tr("SAT>IP information not available!")); textM = cString(tr("SAT>IP information not available!"));
Display(); Display();
timeoutM.Set(INFO_TIMEOUT_MS); timeoutM.Set(eInfoTimeoutMs);
} }
void cSatipMenuInfo::Display(void) void cSatipMenuInfo::Display(void)
@ -208,10 +201,10 @@ cSatipPluginSetup::cSatipPluginSetup()
numDisabledFiltersM(SatipConfig.GetDisabledFiltersCount()) numDisabledFiltersM(SatipConfig.GetDisabledFiltersCount())
{ {
debug("cSatipPluginSetup::%s()", __FUNCTION__); debug("cSatipPluginSetup::%s()", __FUNCTION__);
operatingModeTextsM[0] = tr("off"); operatingModeTextsM[cSatipConfig::eOperatingModeOff] = tr("off");
operatingModeTextsM[1] = tr("low"); operatingModeTextsM[cSatipConfig::eOperatingModeLow] = tr("low");
operatingModeTextsM[2] = tr("normal"); operatingModeTextsM[cSatipConfig::eOperatingModeNormal] = tr("normal");
operatingModeTextsM[3] = tr("high"); operatingModeTextsM[cSatipConfig::eOperatingModeHigh] = tr("high");
if (numDisabledFiltersM > SECTION_FILTER_TABLE_SIZE) if (numDisabledFiltersM > SECTION_FILTER_TABLE_SIZE)
numDisabledFiltersM = SECTION_FILTER_TABLE_SIZE; numDisabledFiltersM = SECTION_FILTER_TABLE_SIZE;
for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i) { for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i) {
@ -220,7 +213,7 @@ cSatipPluginSetup::cSatipPluginSetup()
} }
SetMenuCategory(mcSetupPlugins); SetMenuCategory(mcSetupPlugins);
Setup(); Setup();
SetHelp(NULL, NULL, NULL, trVDR("Button$Info")); SetHelp(trVDR("Button$Scan"), NULL, NULL, trVDR("Button$Info"));
} }
void cSatipPluginSetup::Setup(void) void cSatipPluginSetup::Setup(void)
@ -259,14 +252,22 @@ void cSatipPluginSetup::Setup(void)
Display(); Display();
} }
eOSState cSatipPluginSetup::ChannelScan(void) eOSState cSatipPluginSetup::DeviceScan(void)
{
debug("cSatipPluginSetup::%s()", __FUNCTION__);
cSatipDiscover::GetInstance()->TriggerScan();
return osContinue;
}
eOSState cSatipPluginSetup::DeviceInfo(void)
{ {
debug("cSatipPluginSetup::%s()", __FUNCTION__); debug("cSatipPluginSetup::%s()", __FUNCTION__);
if (HasSubMenu() || Count() == 0) if (HasSubMenu() || Count() == 0)
return osContinue; return osContinue;
cSatipServerItem *item = reinterpret_cast<cSatipServerItem *>(Get(Current())); cSatipServerItem *item = reinterpret_cast<cSatipServerItem *>(Get(Current()));
if (item && cSatipDiscover::GetInstance()->IsValidServer(item->Server())) if (item && !!cSatipDiscover::GetInstance()->GetServer(item->Server()))
return AddSubMenu(new cSatipServerInfo(item->Server())); return AddSubMenu(new cSatipServerInfo(item->Server()));
return osContinue; return osContinue;
@ -291,10 +292,11 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
// Ugly hack with hardcoded '#' character :( // Ugly hack with hardcoded '#' character :(
const char *p = Get(Current())->Text(); const char *p = Get(Current())->Text();
if (!hadSubMenu && !HasSubMenu() && (*p == '#') && (keyP == kOk)) if (!hadSubMenu && !HasSubMenu() && (*p == '#') && (keyP == kOk))
return ChannelScan(); return DeviceInfo();
if (state == osUnknown) { if (state == osUnknown) {
switch (keyP) { switch (keyP) {
case kRed: return DeviceScan();
case kBlue: return ShowInfo(); case kBlue: return ShowInfo();
case kInfo: if (Current() < helpM.Size()) case kInfo: if (Current() < helpM.Size())
return AddSubMenu(new cMenuText(cString::sprintf("%s - %s '%s'", tr("Help"), trVDR("Plugin"), PLUGIN_NAME_I18N), helpM[Current()])); return AddSubMenu(new cMenuText(cString::sprintf("%s - %s '%s'", tr("Help"), trVDR("Plugin"), PLUGIN_NAME_I18N), helpM[Current()]));

View File

@ -17,14 +17,15 @@ class cSatipPluginSetup : public cMenuSetupPage
private: private:
int deviceCountM; int deviceCountM;
int operatingModeM; int operatingModeM;
const char *operatingModeTextsM[4]; const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
int eitScanM; int eitScanM;
int numDisabledFiltersM; int numDisabledFiltersM;
int disabledFilterIndexesM[SECTION_FILTER_TABLE_SIZE]; int disabledFilterIndexesM[SECTION_FILTER_TABLE_SIZE];
const char *disabledFilterNamesM[SECTION_FILTER_TABLE_SIZE]; const char *disabledFilterNamesM[SECTION_FILTER_TABLE_SIZE];
cVector<const char*> helpM; cVector<const char*> helpM;
eOSState ChannelScan(void); eOSState DeviceScan(void);
eOSState DeviceInfo(void);
eOSState ShowInfo(void); eOSState ShowInfo(void);
void Setup(void); void Setup(void);
void StoreFilters(const char *nameP, int *valuesP); void StoreFilters(const char *nameP, int *valuesP);

26
tuner.c
View File

@ -7,6 +7,7 @@
#include "common.h" #include "common.h"
#include "config.h" #include "config.h"
#include "discover.h"
#include "tuner.h" #include "tuner.h"
cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP) cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
@ -18,6 +19,8 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
rtcpSocketM(new cSatipSocket()), rtcpSocketM(new cSatipSocket()),
streamAddrM(""), streamAddrM(""),
streamParamM(""), streamParamM(""),
currentServerM(NULL),
nextServerM(NULL),
mutexM(), mutexM(),
handleM(NULL), handleM(NULL),
headerListM(NULL), headerListM(NULL),
@ -70,13 +73,14 @@ size_t cSatipTuner::HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void
while (r) { while (r) {
//debug("cSatipTuner::%s(%zu): %s", __FUNCTION__, len, r); //debug("cSatipTuner::%s(%zu): %s", __FUNCTION__, len, r);
r = skipspace(r);
if (strstr(r, "com.ses.streamID")) { if (strstr(r, "com.ses.streamID")) {
if (sscanf(r, "com.ses.streamID: %11d", &id) != 1) if (sscanf(r, "com.ses.streamID:%11d", &id) != 1)
id = -1; id = -1;
} }
else if (strstr(r, "Session:")) { else if (strstr(r, "Session:")) {
int session = -1; int session = -1;
if (sscanf(r, "Session: %11d;timeout=%11d", &session, &timeout) != 2) if (sscanf(r, "Session:%11d;timeout=%11d", &session, &timeout) != 2)
timeout = -1; timeout = -1;
} }
r = strtok_r(NULL, "\r\n", &s); r = strtok_r(NULL, "\r\n", &s);
@ -241,6 +245,7 @@ bool cSatipTuner::Connect(void)
// Start playing // Start playing
uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM); uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri); SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, NULL);
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY); SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
SATIP_CURL_EASY_PERFORM(handleM); SATIP_CURL_EASY_PERFORM(handleM);
if (!ValidateLatestResponse()) if (!ValidateLatestResponse())
@ -248,6 +253,11 @@ bool cSatipTuner::Connect(void)
keepAliveM.Set(eKeepAliveIntervalMs); keepAliveM.Set(eKeepAliveIntervalMs);
tunedM = true; tunedM = true;
if (nextServerM) {
cSatipDiscover::GetInstance()->UseServer(nextServerM, true);
currentServerM = nextServerM;
nextServerM = NULL;
}
return true; return true;
} }
@ -290,6 +300,8 @@ bool cSatipTuner::Disconnect(void)
signalStrengthM = -1; signalStrengthM = -1;
signalQualityM = -1; signalQualityM = -1;
if (currentServerM)
cSatipDiscover::GetInstance()->UseServer(currentServerM, false);
tunedM = false; tunedM = false;
return true; return true;
@ -365,12 +377,14 @@ void cSatipTuner::SetStreamInfo(int idP, int timeoutP)
timeoutM = timeoutP > 0 ? timeoutP * 1000L : eKeepAliveIntervalMs; timeoutM = timeoutP > 0 ? timeoutP * 1000L : eKeepAliveIntervalMs;
} }
bool cSatipTuner::SetSource(const char* addressP, const char *parameterP, const int indexP) bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const int indexP)
{ {
debug("cSatipTuner::%s(%s, %s, %d)", __FUNCTION__, addressP, parameterP, indexP); debug("cSatipTuner::%s(%s, %d)", __FUNCTION__, parameterP, indexP);
if (!isempty(addressP) && !isempty(parameterP)) { cMutexLock MutexLock(&mutexM);
nextServerM = cSatipDiscover::GetInstance()->GetServer(serverP);
if (nextServerM && !isempty(nextServerM->Address()) && !isempty(parameterP)) {
// Update stream address and parameter // Update stream address and parameter
streamAddrM = addressP; streamAddrM = nextServerM->Address();
streamParamM = parameterP; streamParamM = parameterP;
// Reconnect // Reconnect
Connect(); Connect();

View File

@ -19,6 +19,7 @@
#include <vdr/tools.h> #include <vdr/tools.h>
#include "deviceif.h" #include "deviceif.h"
#include "server.h"
#include "statistics.h" #include "statistics.h"
#include "socket.h" #include "socket.h"
@ -41,6 +42,8 @@ private:
cSatipSocket *rtcpSocketM; cSatipSocket *rtcpSocketM;
cString streamAddrM; cString streamAddrM;
cString streamParamM; cString streamParamM;
cSatipServer *currentServerM;
cSatipServer *nextServerM;
cMutex mutexM; cMutex mutexM;
CURL *handleM; CURL *handleM;
struct curl_slist *headerListM; struct curl_slist *headerListM;
@ -73,7 +76,7 @@ public:
cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP); cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP);
virtual ~cSatipTuner(); virtual ~cSatipTuner();
bool IsTuned(void) const { return tunedM; } bool IsTuned(void) const { return tunedM; }
bool SetSource(const char* addressP, const char *parameterP, const int indexP); bool SetSource(cSatipServer *serverP, const char *parameterP, const int indexP);
bool SetPid(int pidP, int typeP, bool onP); bool SetPid(int pidP, int typeP, bool onP);
bool Open(void); bool Open(void);
bool Close(void); bool Close(void);