mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 13:37:42 +02:00
Refactored code and added support for 'C' sources.
This commit is contained in:
parent
8c05ce31f9
commit
497b1893db
6
HISTORY
6
HISTORY
@ -7,8 +7,8 @@ VDR Plugin 'satip' Revision History
|
||||
- Initial revision.
|
||||
- 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.
|
||||
- Added a new OperationMode setup parameter.
|
||||
- Switched to the standard S/T/C source identifiers.
|
||||
- Added a new operation mode setup parameter.
|
||||
- Added new SVDRP commands.
|
||||
|
2
Makefile
2
Makefile
@ -78,7 +78,7 @@ all-redirect: all
|
||||
### The object files (add further files here):
|
||||
|
||||
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:
|
||||
|
||||
|
13
README
13
README
@ -57,9 +57,11 @@ Setup menu:
|
||||
- Operating mode = off If you want exclude all SAT>IP devices
|
||||
low from VDR's device handling, set this
|
||||
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
|
||||
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
|
||||
from VDR's EIT background scanning, set
|
||||
this option to "no".
|
||||
@ -72,6 +74,7 @@ Setup menu:
|
||||
"Disable filter" options which allow you
|
||||
to disable the individual section filters.
|
||||
Valid range: "none" = 0 ... 7
|
||||
- [Red:Scan] Forces network scanning of SAT>IP hardware.
|
||||
- [Blue:Info] Opens SAT>IP information/statistics menu.
|
||||
- [Ok] Opens information menu of selected SAT>IP
|
||||
device.
|
||||
@ -88,7 +91,8 @@ Notes:
|
||||
- The stream id "-1" states about unsuccessful tuning. This might be a
|
||||
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
|
||||
your setup doesn't have firewalled the UDP port 1900.
|
||||
@ -97,7 +101,8 @@ Notes:
|
||||
direct access to any DVB card devices.
|
||||
|
||||
- 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:
|
||||
|
||||
|
2
config.c
2
config.c
@ -11,7 +11,7 @@
|
||||
cSatipConfig SatipConfig;
|
||||
|
||||
cSatipConfig::cSatipConfig(void)
|
||||
: operatingModeM(OPERATING_MODE_LOW),
|
||||
: operatingModeM(eOperatingModeLow),
|
||||
eitScanM(1),
|
||||
useBytesM(1)
|
||||
{
|
||||
|
20
config.h
20
config.h
@ -22,19 +22,19 @@ private:
|
||||
|
||||
public:
|
||||
enum {
|
||||
OPERATING_MODE_OFF = 0,
|
||||
OPERATING_MODE_LOW,
|
||||
OPERATING_MODE_NORMAL,
|
||||
OPERATING_MODE_HIGH,
|
||||
NUMBER_OF_OPERATING_MODES
|
||||
eOperatingModeOff = 0,
|
||||
eOperatingModeLow,
|
||||
eOperatingModeNormal,
|
||||
eOperatingModeHigh,
|
||||
eOperatingModeCount
|
||||
};
|
||||
cSatipConfig();
|
||||
unsigned int GetOperatingMode(void) const { return operatingModeM; }
|
||||
bool IsOperatingModeOff(void) const { return (operatingModeM == OPERATING_MODE_OFF); }
|
||||
bool IsOperatingModeLow(void) const { return (operatingModeM == OPERATING_MODE_LOW); }
|
||||
bool IsOperatingModeNormal(void) const { return (operatingModeM == OPERATING_MODE_NORMAL); }
|
||||
bool IsOperatingModeHigh(void) const { return (operatingModeM == OPERATING_MODE_HIGH); }
|
||||
void ToggleOperatingMode(void) { operatingModeM = (operatingModeM + 1) % NUMBER_OF_OPERATING_MODES; }
|
||||
bool IsOperatingModeOff(void) const { return (operatingModeM == eOperatingModeOff); }
|
||||
bool IsOperatingModeLow(void) const { return (operatingModeM == eOperatingModeLow); }
|
||||
bool IsOperatingModeNormal(void) const { return (operatingModeM == eOperatingModeNormal); }
|
||||
bool IsOperatingModeHigh(void) const { return (operatingModeM == eOperatingModeHigh); }
|
||||
void ToggleOperatingMode(void) { operatingModeM = (operatingModeM + 1) % eOperatingModeCount; }
|
||||
unsigned int GetEITScan(void) const { return eitScanM; }
|
||||
unsigned int GetUseBytes(void) const { return useBytesM; }
|
||||
const char *GetConfigDirectory(void) const { return configDirectoryM; }
|
||||
|
5
device.c
5
device.c
@ -277,9 +277,8 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
|
||||
debug("cSatipDevice::%s(%u): no suitable server found", __FUNCTION__, deviceIndexM);
|
||||
return false;
|
||||
}
|
||||
address = server->Address();
|
||||
if (pTunerM && pTunerM->SetSource(*address, *params, deviceIndexM)) {
|
||||
deviceNameM = cString::sprintf("%s %d %s:%s:%s", *DeviceType(), deviceIndexM, server->Address(), server->Model(), server->Description());
|
||||
if (pTunerM && pTunerM->SetSource(server, *params, deviceIndexM)) {
|
||||
deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server));
|
||||
channelM = *channelP;
|
||||
return true;
|
||||
}
|
||||
|
106
discover.c
106
discover.c
@ -31,13 +31,16 @@ cSatipDiscover *cSatipDiscover::GetInstance(void)
|
||||
bool cSatipDiscover::Initialize(void)
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
if (instanceS)
|
||||
instanceS->Activate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void cSatipDiscover::Destroy(void)
|
||||
{
|
||||
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)
|
||||
@ -51,6 +54,7 @@ size_t cSatipDiscover::WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, vo
|
||||
char *desc = NULL, *model = NULL, *addr = NULL;
|
||||
while (r) {
|
||||
//debug("cSatipDiscover::%s(%zu): %s", __FUNCTION__, len, r);
|
||||
r = skipspace(r);
|
||||
// <friendlyName>OctopusNet</friendlyName>
|
||||
if (startswith(r, "<friendlyName"))
|
||||
desc = StripTags(r);
|
||||
@ -85,10 +89,8 @@ cSatipDiscover::cSatipDiscover()
|
||||
cSatipDiscover::~cSatipDiscover()
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
Deactivate();
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
sleepM.Signal();
|
||||
if (Running())
|
||||
Cancel(3);
|
||||
// Free allocated memory
|
||||
DELETENULL(socketM);
|
||||
DELETENULL(serversM);
|
||||
@ -97,6 +99,21 @@ cSatipDiscover::~cSatipDiscover()
|
||||
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)
|
||||
{
|
||||
debug("cSatipDiscover::%s(): entering", __FUNCTION__);
|
||||
@ -117,12 +134,8 @@ void cSatipDiscover::Janitor(void)
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) {
|
||||
if (srv->LastSeen() > eProbeIntervalMs * 2) {
|
||||
info("Removing device %s (%s %s)", srv->Description(), srv->Address(), srv->Model());
|
||||
serversM->Del(srv);
|
||||
}
|
||||
}
|
||||
if (serversM)
|
||||
serversM->Cleanup(eProbeIntervalMs * 2);
|
||||
}
|
||||
|
||||
void cSatipDiscover::Probe(void)
|
||||
@ -213,15 +226,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *descP, const char
|
||||
if (serversM) {
|
||||
cSatipServer *tmp = new cSatipServer(addrP, descP, modelP);
|
||||
// Validate against existing servers
|
||||
bool found = false;
|
||||
for (cSatipServer *s = serversM->First(); s; s = serversM->Next(s)) {
|
||||
if (s->Compare(*tmp) == 0) {
|
||||
found = true;
|
||||
s->Update();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (!serversM->Update(tmp)) {
|
||||
info("Adding device %s (%s %s)", tmp->Description(), tmp->Address(), tmp->Model());
|
||||
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)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d, %d)", __FUNCTION__, sourceP, systemP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
int model = 0;
|
||||
if (cSource::IsType(sourceP, 'S'))
|
||||
model |= cSatipServer::eSatipModelTypeDVBS2;
|
||||
if (cSource::IsType(sourceP, 'T')) {
|
||||
if (systemP < 0)
|
||||
model |= cSatipServer::eSatipModelTypeDVBT2 | cSatipServer::eSatipModelTypeDVBT;
|
||||
else
|
||||
model |= systemP ? cSatipServer::eSatipModelTypeDVBT2 : cSatipServer::eSatipModelTypeDVBT;
|
||||
}
|
||||
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) {
|
||||
if (srv->Match(model))
|
||||
return srv;
|
||||
}
|
||||
return NULL;
|
||||
return serversM ? serversM->Find(sourceP, systemP) : NULL;
|
||||
}
|
||||
|
||||
cSatipServer *cSatipDiscover::GetServer(cSatipServer *serverP)
|
||||
{
|
||||
//debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
return serversM ? serversM->Find(serverP) : NULL;
|
||||
}
|
||||
|
||||
cSatipServers *cSatipDiscover::GetServers(void)
|
||||
@ -268,27 +256,31 @@ cSatipServers *cSatipDiscover::GetServers(void)
|
||||
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)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
cString 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;
|
||||
return serversM ? serversM->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)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
int count = 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;
|
||||
return serversM ? serversM->NumProvidedSystems() : 0;
|
||||
}
|
||||
|
75
discover.h
75
discover.h
@ -9,79 +9,13 @@
|
||||
#define __SATIP_DISCOVER_H
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
#include <vdr/thread.h>
|
||||
#include <vdr/tools.h>
|
||||
|
||||
#include "server.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 {
|
||||
private:
|
||||
enum {
|
||||
@ -101,6 +35,8 @@ private:
|
||||
cCondWait sleepM;
|
||||
cTimeMs probeIntervalM;
|
||||
cSatipServers *serversM;
|
||||
void Activate(void);
|
||||
void Deactivate(void);
|
||||
void Janitor(void);
|
||||
void Probe(void);
|
||||
void Read(void);
|
||||
@ -119,9 +55,12 @@ public:
|
||||
static bool Initialize(void);
|
||||
static void Destroy(void);
|
||||
virtual ~cSatipDiscover();
|
||||
bool IsValidServer(cSatipServer *serverP);
|
||||
void TriggerScan(void) { probeIntervalM.Set(0); }
|
||||
cSatipServer *GetServer(int sourceP, int systemP = -1);
|
||||
cSatipServer *GetServer(cSatipServer *serverP);
|
||||
cSatipServers *GetServers(void);
|
||||
cString GetServerString(cSatipServer *serverP);
|
||||
void UseServer(cSatipServer *serverP, bool onOffP);
|
||||
cString GetServerList(void);
|
||||
int NumProvidedSystems(void);
|
||||
};
|
||||
|
141
param.c
141
param.c
@ -18,94 +18,101 @@ struct tSatipParameterMap {
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipBandwidthValues[] = {
|
||||
{ 5000000, "bw=5" },
|
||||
{ 6000000, "bw=6" },
|
||||
{ 7000000, "bw=7" },
|
||||
{ 8000000, "bw=8" },
|
||||
{ 10000000, "bw=10" },
|
||||
{ 1712000, "bw=1.712" },
|
||||
{ 5000000, "&bw=5" },
|
||||
{ 6000000, "&bw=6" },
|
||||
{ 7000000, "&bw=7" },
|
||||
{ 8000000, "&bw=8" },
|
||||
{ 10000000, "&bw=10" },
|
||||
{ 1712000, "&bw=1.712" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipPilotValues[] = {
|
||||
{ PILOT_OFF, "plts=off" },
|
||||
{ PILOT_ON, "plts=on" },
|
||||
{ PILOT_OFF, "&plts=off" },
|
||||
{ PILOT_ON, "&plts=on" },
|
||||
{ PILOT_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSisoMisoValues[] = {
|
||||
{ 0, "sm=0" },
|
||||
{ 1, "sm=1" },
|
||||
{ 0, "&sm=0" },
|
||||
{ 1, "&sm=1" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipCodeRateValues[] = {
|
||||
{ FEC_NONE, "" },
|
||||
{ FEC_1_2, "fec=12" },
|
||||
{ FEC_2_3, "fec=23" },
|
||||
{ FEC_3_4, "fec=34" },
|
||||
{ FEC_3_5, "fec=35" },
|
||||
{ FEC_4_5, "fec=45" },
|
||||
{ FEC_5_6, "fec=56" },
|
||||
{ FEC_6_7, "fec=67" },
|
||||
{ FEC_7_8, "fec=78" },
|
||||
{ FEC_8_9, "fec=89" },
|
||||
{ FEC_9_10, "fec=910" },
|
||||
{ FEC_1_2, "&fec=12" },
|
||||
{ FEC_2_3, "&fec=23" },
|
||||
{ FEC_3_4, "&fec=34" },
|
||||
{ FEC_3_5, "&fec=35" },
|
||||
{ FEC_4_5, "&fec=45" },
|
||||
{ FEC_5_6, "&fec=56" },
|
||||
{ FEC_6_7, "&fec=67" },
|
||||
{ FEC_7_8, "&fec=78" },
|
||||
{ FEC_8_9, "&fec=89" },
|
||||
{ FEC_9_10, "&fec=910" },
|
||||
{ FEC_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipModulationValues[] = {
|
||||
{ QPSK, "mtype=qpsk" },
|
||||
{ PSK_8, "mtype=8psk" },
|
||||
{ QAM_16, "mtype=16qam" },
|
||||
{ QAM_64, "mtype=64qam" },
|
||||
{ QAM_256, "mtype=256qam" },
|
||||
{ QPSK, "&mtype=qpsk" },
|
||||
{ PSK_8, "&mtype=8psk" },
|
||||
{ QAM_16, "&mtype=16qam" },
|
||||
{ QAM_64, "&mtype=64qam" },
|
||||
{ QAM_128, "&mtype=128qam" },
|
||||
{ QAM_256, "&mtype=256qam" },
|
||||
{ QAM_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSystemValuesSat[] = {
|
||||
{ 0, "msys=dvbs" },
|
||||
{ 1, "msys=dvbs2" },
|
||||
{ 0, "&msys=dvbs" },
|
||||
{ 1, "&msys=dvbs2" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSystemValuesTerr[] = {
|
||||
{ 0, "msys=dvbt" },
|
||||
{ 1, "msys=dvbt2" },
|
||||
static const tSatipParameterMap SatipSystemValuesTerrestrial[] = {
|
||||
{ 0, "&msys=dvbt" },
|
||||
{ 1, "&msys=dvbt2" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSystemValuesCable[] = {
|
||||
{ 0, "&msys=dvbc" },
|
||||
{ 1, "&msys=dvbc2" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipTransmissionValues[] = {
|
||||
{ TRANSMISSION_MODE_1K, "tmode=1k" },
|
||||
{ TRANSMISSION_MODE_2K, "tmode=2k" },
|
||||
{ TRANSMISSION_MODE_4K, "tmode=4k" },
|
||||
{ TRANSMISSION_MODE_8K, "tmode=8k" },
|
||||
{ TRANSMISSION_MODE_16K, "tmode=16k" },
|
||||
{ TRANSMISSION_MODE_32K, "tmode=32k" },
|
||||
{ TRANSMISSION_MODE_1K, "&tmode=1k" },
|
||||
{ TRANSMISSION_MODE_2K, "&tmode=2k" },
|
||||
{ TRANSMISSION_MODE_4K, "&tmode=4k" },
|
||||
{ TRANSMISSION_MODE_8K, "&tmode=8k" },
|
||||
{ TRANSMISSION_MODE_16K, "&tmode=16k" },
|
||||
{ TRANSMISSION_MODE_32K, "&tmode=32k" },
|
||||
{ TRANSMISSION_MODE_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipGuardValues[] = {
|
||||
{ GUARD_INTERVAL_1_4, "gi=14" },
|
||||
{ GUARD_INTERVAL_1_8, "gi=18" },
|
||||
{ GUARD_INTERVAL_1_16, "gi=116" },
|
||||
{ GUARD_INTERVAL_1_32, "gi=132" },
|
||||
{ GUARD_INTERVAL_1_128, "gi=1128" },
|
||||
{ GUARD_INTERVAL_19_128, "gi=19128" },
|
||||
{ GUARD_INTERVAL_19_256, "gi=19256" },
|
||||
{ GUARD_INTERVAL_1_4, "&gi=14" },
|
||||
{ GUARD_INTERVAL_1_8, "&gi=18" },
|
||||
{ GUARD_INTERVAL_1_16, "&gi=116" },
|
||||
{ GUARD_INTERVAL_1_32, "&gi=132" },
|
||||
{ GUARD_INTERVAL_1_128, "&gi=1128" },
|
||||
{ GUARD_INTERVAL_19_128, "&gi=19128" },
|
||||
{ GUARD_INTERVAL_19_256, "&gi=19256" },
|
||||
{ GUARD_INTERVAL_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipRollOffValues[] = {
|
||||
{ ROLLOFF_AUTO, "" },
|
||||
{ ROLLOFF_20, "ro=0.20" },
|
||||
{ ROLLOFF_25, "ro=0.25" },
|
||||
{ ROLLOFF_35, "ro=0.35" },
|
||||
{ ROLLOFF_20, "&ro=0.20" },
|
||||
{ ROLLOFF_25, "&ro=0.25" },
|
||||
{ ROLLOFF_35, "&ro=0.35" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
@ -120,15 +127,16 @@ static int SatipUserIndex(int valueP, const tSatipParameterMap *mapP)
|
||||
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);
|
||||
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)
|
||||
{
|
||||
if (channelP) {
|
||||
char buffer[255];
|
||||
cDvbTransponderParameters dtp(channelP->Parameters());
|
||||
int Pilot = PILOT_AUTO; // 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());
|
||||
cSource *source = Sources.Get(channelP->Source());
|
||||
int src = (strchr("S", type) && source) ? atoi(source->Description()) : 1;
|
||||
char buffer[255];
|
||||
char *q = buffer;
|
||||
*q = 0;
|
||||
// Scale down frequencies to MHz
|
||||
while (freq > 20000L)
|
||||
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, '*')))
|
||||
ST("S *") q += sprintf(q, "&src=%d", ((src > 0) && (src <= 255)) ? src : 1);
|
||||
ST("S *") q += sprintf(q, "&sr=%d", channelP->Srate());
|
||||
ST("S *") q += sprintf(q, "&pol=%c", tolower(dtp.Polarization()));
|
||||
ST(" T2") q += sprintf(q, "&plp=%d", dtp.StreamId());
|
||||
ST(" T2") q += sprintf(q, "&t2id=%d", T2SystemId);
|
||||
ST(" T2") q += PrintUrlString(q, SisoMiso, SatipSisoMisoValues);
|
||||
ST(" T*") q += PrintUrlString(q, dtp.Bandwidth(), SatipBandwidthValues);
|
||||
ST(" T*") q += PrintUrlString(q, dtp.Guard(), SatipGuardValues);
|
||||
ST("ST*") q += PrintUrlString(q, dtp.CoderateH(), SatipCodeRateValues);
|
||||
ST("S 2") q += PrintUrlString(q, Pilot, SatipPilotValues);
|
||||
ST("S 2") q += PrintUrlString(q, dtp.Modulation(), SatipModulationValues);
|
||||
ST(" T*") q += PrintUrlString(q, dtp.Modulation(), SatipModulationValues);
|
||||
ST("S 2") q += PrintUrlString(q, dtp.RollOff(), SatipRollOffValues);
|
||||
ST("S *") q += PrintUrlString(q, dtp.System(), SatipSystemValuesSat);
|
||||
ST(" T*") q += PrintUrlString(q, dtp.System(), SatipSystemValuesTerr);
|
||||
ST(" T*") q += PrintUrlString(q, dtp.Transmission(), SatipTransmissionValues);
|
||||
#define STBUFLEFT (sizeof(buffer) - (q - buffer))
|
||||
q += snprintf(q, STBUFLEFT, "freq=%s", *dtoa(freq, "%.3f"));
|
||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&src=%d", ((src > 0) && (src <= 255)) ? src : 1);
|
||||
ST("CS *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&pol=%c", tolower(dtp.Polarization()));
|
||||
ST("C T2") q += snprintf(q, STBUFLEFT, "&plp=%d", dtp.StreamId());
|
||||
ST(" T2") q += snprintf(q, STBUFLEFT, "&t2id=%d", T2SystemId);
|
||||
ST(" T2") q += PrintUrlString(q, STBUFLEFT, SisoMiso, SatipSisoMisoValues);
|
||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Bandwidth(), SatipBandwidthValues);
|
||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Guard(), SatipGuardValues);
|
||||
ST("CST*") q += PrintUrlString(q, STBUFLEFT, dtp.CoderateH(), SatipCodeRateValues);
|
||||
ST(" S 2") q += PrintUrlString(q, STBUFLEFT, Pilot, SatipPilotValues);
|
||||
ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
||||
ST("C T*") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
||||
ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.RollOff(), SatipRollOffValues);
|
||||
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
|
||||
return buffer;
|
||||
}
|
||||
|
14
po/de_DE.po
14
po/de_DE.po
@ -5,7 +5,7 @@
|
||||
#
|
||||
msgid ""
|
||||
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"
|
||||
"POT-Creation-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"
|
||||
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"
|
||||
msgstr "SAT>IP Informationen"
|
||||
|
||||
|
14
po/fi_FI.po
14
po/fi_FI.po
@ -5,7 +5,7 @@
|
||||
#
|
||||
msgid ""
|
||||
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"
|
||||
"POT-Creation-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"
|
||||
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"
|
||||
msgstr "SAT>IP-tiedot"
|
||||
|
||||
|
10
satip.c
10
satip.c
@ -21,7 +21,7 @@
|
||||
#define GITVERSION ""
|
||||
#endif
|
||||
|
||||
const char VERSION[] = "0.0.2" GITVERSION;
|
||||
const char VERSION[] = "0.1.0" GITVERSION;
|
||||
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
||||
|
||||
class cPluginSatip : public cPlugin {
|
||||
@ -292,16 +292,16 @@ cString cPluginSatip::SVDRPCommand(const char *commandP, const char *optionP, in
|
||||
cString mode;
|
||||
SatipConfig.ToggleOperatingMode();
|
||||
switch (SatipConfig.GetOperatingMode()) {
|
||||
case cSatipConfig::OPERATING_MODE_OFF:
|
||||
case cSatipConfig::eOperatingModeOff:
|
||||
mode = "off";
|
||||
break;
|
||||
case cSatipConfig::OPERATING_MODE_LOW:
|
||||
case cSatipConfig::eOperatingModeLow:
|
||||
mode = "low";
|
||||
break;
|
||||
case cSatipConfig::OPERATING_MODE_NORMAL:
|
||||
case cSatipConfig::eOperatingModeNormal:
|
||||
mode = "normal";
|
||||
break;
|
||||
case cSatipConfig::OPERATING_MODE_HIGH:
|
||||
case cSatipConfig::eOperatingModeHigh:
|
||||
mode = "high";
|
||||
break;
|
||||
default:
|
||||
|
@ -33,11 +33,11 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
||||
filterMaskM[0] = maskP;
|
||||
|
||||
// Invert the filter
|
||||
for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i)
|
||||
for (i = 0; i < eDmxMaxFilterSize; ++i)
|
||||
filterValueM[i] ^= 0xFF;
|
||||
|
||||
uint8_t mask, mode, doneq = 0;
|
||||
for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i) {
|
||||
for (i = 0; i < eDmxMaxFilterSize; ++i) {
|
||||
mode = filterModeM[i];
|
||||
mask = filterMaskM[i];
|
||||
maskAndModeM[i] = (uint8_t)(mask & mode);
|
||||
@ -89,7 +89,7 @@ int cSatipSectionFilter::Filter(void)
|
||||
int i;
|
||||
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]);
|
||||
if (maskAndModeM[i] & calcxor)
|
||||
return 0;
|
||||
@ -122,11 +122,11 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
|
||||
{
|
||||
uint16_t limit, seclen, n;
|
||||
|
||||
if (tsFeedpM >= DMX_MAX_SECFEED_SIZE)
|
||||
if (tsFeedpM >= eDmxMaxSectionFeedSize)
|
||||
return 0;
|
||||
|
||||
if (tsFeedpM + lenP > DMX_MAX_SECFEED_SIZE)
|
||||
lenP = (uint8_t)(DMX_MAX_SECFEED_SIZE - tsFeedpM);
|
||||
if (tsFeedpM + lenP > eDmxMaxSectionFeedSize)
|
||||
lenP = (uint8_t)(eDmxMaxSectionFeedSize - tsFeedpM);
|
||||
|
||||
if (lenP <= 0)
|
||||
return 0;
|
||||
@ -135,7 +135,7 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
|
||||
tsFeedpM = uint16_t(tsFeedpM + lenP);
|
||||
|
||||
limit = tsFeedpM;
|
||||
if (limit > DMX_MAX_SECFEED_SIZE)
|
||||
if (limit > eDmxMaxSectionFeedSize)
|
||||
return -1; // internal error should never happen
|
||||
|
||||
// Always set secbuf
|
||||
@ -143,7 +143,7 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
|
||||
|
||||
for (n = 0; secBufpM + 2 < limit; ++n) {
|
||||
seclen = GetLength(secBufM);
|
||||
if ((seclen <= 0) || (seclen > DMX_MAX_SECTION_SIZE) || ((seclen + secBufpM) > limit))
|
||||
if ((seclen <= 0) || (seclen > eDmxMaxSectionSize) || ((seclen + secBufpM) > limit))
|
||||
return 0;
|
||||
secLenM = seclen;
|
||||
if (pusiSeenM)
|
||||
|
@ -19,9 +19,9 @@
|
||||
class cSatipSectionFilter : public cSatipSectionStatistics {
|
||||
private:
|
||||
enum dmx_limits {
|
||||
DMX_MAX_FILTER_SIZE = 18,
|
||||
DMX_MAX_SECTION_SIZE = 4096,
|
||||
DMX_MAX_SECFEED_SIZE = (DMX_MAX_SECTION_SIZE + TS_SIZE)
|
||||
eDmxMaxFilterSize = 18,
|
||||
eDmxMaxSectionSize = 4096,
|
||||
eDmxMaxSectionFeedSize = (eDmxMaxSectionSize + TS_SIZE)
|
||||
};
|
||||
|
||||
int pusiSeenM;
|
||||
@ -29,7 +29,7 @@ private:
|
||||
int doneqM;
|
||||
|
||||
uint8_t *secBufM;
|
||||
uint8_t secBufBaseM[DMX_MAX_SECFEED_SIZE];
|
||||
uint8_t secBufBaseM[eDmxMaxSectionFeedSize];
|
||||
uint16_t secBufpM;
|
||||
uint16_t secLenM;
|
||||
uint16_t tsFeedpM;
|
||||
@ -38,12 +38,12 @@ private:
|
||||
int deviceIndexM;
|
||||
int socketM[2];
|
||||
|
||||
uint8_t filterValueM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t filterMaskM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t filterModeM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t filterValueM[eDmxMaxFilterSize];
|
||||
uint8_t filterMaskM[eDmxMaxFilterSize];
|
||||
uint8_t filterModeM[eDmxMaxFilterSize];
|
||||
|
||||
uint8_t maskAndModeM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t maskAndNotModeM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t maskAndModeM[eDmxMaxFilterSize];
|
||||
uint8_t maskAndNotModeM[eDmxMaxFilterSize];
|
||||
|
||||
inline uint16_t GetLength(const uint8_t *dataP);
|
||||
void New(void);
|
||||
|
177
server.c
Normal file
177
server.c
Normal 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
71
server.h
Normal 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
76
setup.c
@ -19,32 +19,27 @@
|
||||
class cSatipServerInfo : public cOsdMenu
|
||||
{
|
||||
private:
|
||||
enum {
|
||||
INFO_TIMEOUT_MS = 2000
|
||||
};
|
||||
cString textM;
|
||||
cTimeMs timeoutM;
|
||||
cString addressM;
|
||||
cString modelM;
|
||||
cString descriptionM;
|
||||
uint64_t createdM;
|
||||
void Setup(void);
|
||||
|
||||
public:
|
||||
cSatipServerInfo(cSatipServer *serverP);
|
||||
virtual ~cSatipServerInfo();
|
||||
virtual void Display(void);
|
||||
virtual eOSState ProcessKey(eKeys keyP);
|
||||
};
|
||||
|
||||
cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP)
|
||||
: cOsdMenu(tr("SAT>IP Device")),
|
||||
textM("")
|
||||
: cOsdMenu(tr("SAT>IP Device"), 20),
|
||||
addressM(serverP ? serverP->Address() : "---"),
|
||||
modelM(serverP ? serverP->Model() : "---"),
|
||||
descriptionM(serverP ? serverP->Description() : "---"),
|
||||
createdM(serverP ? serverP->Created() : 0)
|
||||
{
|
||||
SetMenuCategory(mcText);
|
||||
if (serverP) {
|
||||
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());
|
||||
}
|
||||
SetMenuCategory(mcSetupPlugins);
|
||||
Setup();
|
||||
SetHelp(NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
@ -52,12 +47,12 @@ cSatipServerInfo::~cSatipServerInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void cSatipServerInfo::Display(void)
|
||||
void cSatipServerInfo::Setup(void)
|
||||
{
|
||||
cOsdMenu::Display();
|
||||
DisplayMenu()->SetText(textM, true);
|
||||
if (*textM)
|
||||
cStatus::MsgOsdTextItem(textM);
|
||||
Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Address"), *addressM), osUnknown, false));
|
||||
Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Model"), *modelM), osUnknown, false));
|
||||
Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Description"), *descriptionM), osUnknown, false));
|
||||
Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Creation date"), *DayDateTime(createdM)), osUnknown, false));
|
||||
}
|
||||
|
||||
eOSState cSatipServerInfo::ProcessKey(eKeys keyP)
|
||||
@ -66,10 +61,8 @@ eOSState cSatipServerInfo::ProcessKey(eKeys keyP)
|
||||
|
||||
if (state == osUnknown) {
|
||||
switch (keyP) {
|
||||
case kOk: return osBack;
|
||||
case kRed:
|
||||
default: state = osContinue;
|
||||
break;
|
||||
case kOk: state = osBack; break;
|
||||
default: state = osContinue; break;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@ -107,7 +100,7 @@ class cSatipMenuInfo : public cOsdMenu
|
||||
{
|
||||
private:
|
||||
enum {
|
||||
INFO_TIMEOUT_MS = 2000
|
||||
eInfoTimeoutMs = 2000
|
||||
};
|
||||
cString textM;
|
||||
cTimeMs timeoutM;
|
||||
@ -128,7 +121,7 @@ cSatipMenuInfo::cSatipMenuInfo()
|
||||
pageM(SATIP_DEVICE_INFO_GENERAL)
|
||||
{
|
||||
SetMenuCategory(mcText);
|
||||
timeoutM.Set(INFO_TIMEOUT_MS);
|
||||
timeoutM.Set(eInfoTimeoutMs);
|
||||
UpdateInfo();
|
||||
SetHelp(tr("General"), tr("Pids"), tr("Filters"), tr("Bits/bytes"));
|
||||
}
|
||||
@ -145,7 +138,7 @@ void cSatipMenuInfo::UpdateInfo()
|
||||
else
|
||||
textM = cString(tr("SAT>IP information not available!"));
|
||||
Display();
|
||||
timeoutM.Set(INFO_TIMEOUT_MS);
|
||||
timeoutM.Set(eInfoTimeoutMs);
|
||||
}
|
||||
|
||||
void cSatipMenuInfo::Display(void)
|
||||
@ -208,10 +201,10 @@ cSatipPluginSetup::cSatipPluginSetup()
|
||||
numDisabledFiltersM(SatipConfig.GetDisabledFiltersCount())
|
||||
{
|
||||
debug("cSatipPluginSetup::%s()", __FUNCTION__);
|
||||
operatingModeTextsM[0] = tr("off");
|
||||
operatingModeTextsM[1] = tr("low");
|
||||
operatingModeTextsM[2] = tr("normal");
|
||||
operatingModeTextsM[3] = tr("high");
|
||||
operatingModeTextsM[cSatipConfig::eOperatingModeOff] = tr("off");
|
||||
operatingModeTextsM[cSatipConfig::eOperatingModeLow] = tr("low");
|
||||
operatingModeTextsM[cSatipConfig::eOperatingModeNormal] = tr("normal");
|
||||
operatingModeTextsM[cSatipConfig::eOperatingModeHigh] = tr("high");
|
||||
if (numDisabledFiltersM > SECTION_FILTER_TABLE_SIZE)
|
||||
numDisabledFiltersM = SECTION_FILTER_TABLE_SIZE;
|
||||
for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i) {
|
||||
@ -220,7 +213,7 @@ cSatipPluginSetup::cSatipPluginSetup()
|
||||
}
|
||||
SetMenuCategory(mcSetupPlugins);
|
||||
Setup();
|
||||
SetHelp(NULL, NULL, NULL, trVDR("Button$Info"));
|
||||
SetHelp(trVDR("Button$Scan"), NULL, NULL, trVDR("Button$Info"));
|
||||
}
|
||||
|
||||
void cSatipPluginSetup::Setup(void)
|
||||
@ -259,14 +252,22 @@ void cSatipPluginSetup::Setup(void)
|
||||
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__);
|
||||
if (HasSubMenu() || Count() == 0)
|
||||
return osContinue;
|
||||
|
||||
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 osContinue;
|
||||
@ -291,10 +292,11 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
|
||||
// Ugly hack with hardcoded '#' character :(
|
||||
const char *p = Get(Current())->Text();
|
||||
if (!hadSubMenu && !HasSubMenu() && (*p == '#') && (keyP == kOk))
|
||||
return ChannelScan();
|
||||
return DeviceInfo();
|
||||
|
||||
if (state == osUnknown) {
|
||||
switch (keyP) {
|
||||
case kRed: return DeviceScan();
|
||||
case kBlue: return ShowInfo();
|
||||
case kInfo: if (Current() < helpM.Size())
|
||||
return AddSubMenu(new cMenuText(cString::sprintf("%s - %s '%s'", tr("Help"), trVDR("Plugin"), PLUGIN_NAME_I18N), helpM[Current()]));
|
||||
|
5
setup.h
5
setup.h
@ -17,14 +17,15 @@ class cSatipPluginSetup : public cMenuSetupPage
|
||||
private:
|
||||
int deviceCountM;
|
||||
int operatingModeM;
|
||||
const char *operatingModeTextsM[4];
|
||||
const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
|
||||
int eitScanM;
|
||||
int numDisabledFiltersM;
|
||||
int disabledFilterIndexesM[SECTION_FILTER_TABLE_SIZE];
|
||||
const char *disabledFilterNamesM[SECTION_FILTER_TABLE_SIZE];
|
||||
cVector<const char*> helpM;
|
||||
|
||||
eOSState ChannelScan(void);
|
||||
eOSState DeviceScan(void);
|
||||
eOSState DeviceInfo(void);
|
||||
eOSState ShowInfo(void);
|
||||
void Setup(void);
|
||||
void StoreFilters(const char *nameP, int *valuesP);
|
||||
|
26
tuner.c
26
tuner.c
@ -7,6 +7,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "discover.h"
|
||||
#include "tuner.h"
|
||||
|
||||
cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
||||
@ -18,6 +19,8 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
||||
rtcpSocketM(new cSatipSocket()),
|
||||
streamAddrM(""),
|
||||
streamParamM(""),
|
||||
currentServerM(NULL),
|
||||
nextServerM(NULL),
|
||||
mutexM(),
|
||||
handleM(NULL),
|
||||
headerListM(NULL),
|
||||
@ -70,13 +73,14 @@ size_t cSatipTuner::HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void
|
||||
|
||||
while (r) {
|
||||
//debug("cSatipTuner::%s(%zu): %s", __FUNCTION__, len, r);
|
||||
r = skipspace(r);
|
||||
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;
|
||||
}
|
||||
else if (strstr(r, "Session:")) {
|
||||
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;
|
||||
}
|
||||
r = strtok_r(NULL, "\r\n", &s);
|
||||
@ -241,6 +245,7 @@ bool cSatipTuner::Connect(void)
|
||||
// Start playing
|
||||
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_SESSION_ID, NULL);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (!ValidateLatestResponse())
|
||||
@ -248,6 +253,11 @@ bool cSatipTuner::Connect(void)
|
||||
|
||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
||||
tunedM = true;
|
||||
if (nextServerM) {
|
||||
cSatipDiscover::GetInstance()->UseServer(nextServerM, true);
|
||||
currentServerM = nextServerM;
|
||||
nextServerM = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -290,6 +300,8 @@ bool cSatipTuner::Disconnect(void)
|
||||
signalStrengthM = -1;
|
||||
signalQualityM = -1;
|
||||
|
||||
if (currentServerM)
|
||||
cSatipDiscover::GetInstance()->UseServer(currentServerM, false);
|
||||
tunedM = false;
|
||||
|
||||
return true;
|
||||
@ -365,12 +377,14 @@ void cSatipTuner::SetStreamInfo(int idP, int timeoutP)
|
||||
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);
|
||||
if (!isempty(addressP) && !isempty(parameterP)) {
|
||||
debug("cSatipTuner::%s(%s, %d)", __FUNCTION__, parameterP, indexP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
nextServerM = cSatipDiscover::GetInstance()->GetServer(serverP);
|
||||
if (nextServerM && !isempty(nextServerM->Address()) && !isempty(parameterP)) {
|
||||
// Update stream address and parameter
|
||||
streamAddrM = addressP;
|
||||
streamAddrM = nextServerM->Address();
|
||||
streamParamM = parameterP;
|
||||
// Reconnect
|
||||
Connect();
|
||||
|
5
tuner.h
5
tuner.h
@ -19,6 +19,7 @@
|
||||
#include <vdr/tools.h>
|
||||
|
||||
#include "deviceif.h"
|
||||
#include "server.h"
|
||||
#include "statistics.h"
|
||||
#include "socket.h"
|
||||
|
||||
@ -41,6 +42,8 @@ private:
|
||||
cSatipSocket *rtcpSocketM;
|
||||
cString streamAddrM;
|
||||
cString streamParamM;
|
||||
cSatipServer *currentServerM;
|
||||
cSatipServer *nextServerM;
|
||||
cMutex mutexM;
|
||||
CURL *handleM;
|
||||
struct curl_slist *headerListM;
|
||||
@ -73,7 +76,7 @@ public:
|
||||
cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP);
|
||||
virtual ~cSatipTuner();
|
||||
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 Open(void);
|
||||
bool Close(void);
|
||||
|
Loading…
Reference in New Issue
Block a user