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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

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

View File

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