diff --git a/HISTORY b/HISTORY index 7d0b5b3..9b8c597 100644 --- a/HISTORY +++ b/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. diff --git a/Makefile b/Makefile index b4de8b6..1d7b7c6 100644 --- a/Makefile +++ b/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: diff --git a/README b/README index df03584..ff5578a 100644 --- a/README +++ b/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: diff --git a/config.c b/config.c index b1503b5..94b64c0 100644 --- a/config.c +++ b/config.c @@ -11,7 +11,7 @@ cSatipConfig SatipConfig; cSatipConfig::cSatipConfig(void) -: operatingModeM(OPERATING_MODE_LOW), +: operatingModeM(eOperatingModeLow), eitScanM(1), useBytesM(1) { diff --git a/config.h b/config.h index c77de1c..b270b4c 100644 --- a/config.h +++ b/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; } diff --git a/device.c b/device.c index fa1d45d..b3748fb 100644 --- a/device.c +++ b/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; } diff --git a/discover.c b/discover.c index 9d28963..9a70b8a 100644 --- a/discover.c +++ b/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); // OctopusNet if (startswith(r, "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; } diff --git a/discover.h b/discover.h index 91eeb89..9234f68 100644 --- a/discover.h +++ b/discover.h @@ -9,79 +9,13 @@ #define __SATIP_DISCOVER_H #include -#include #include #include +#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 { -}; - - 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); }; diff --git a/param.c b/param.c index 9d853a8..3c8c163 100644 --- a/param.c +++ b/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; } diff --git a/po/de_DE.po b/po/de_DE.po index 1dde4b2..b6ed04f 100644 --- a/po/de_DE.po +++ b/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: \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" diff --git a/po/fi_FI.po b/po/fi_FI.po index 5089486..bfffc60 100644 --- a/po/fi_FI.po +++ b/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: \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" diff --git a/satip.c b/satip.c index 18711c2..4c7062e 100644 --- a/satip.c +++ b/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: diff --git a/sectionfilter.c b/sectionfilter.c index 58e5fdb..047d9e3 100644 --- a/sectionfilter.c +++ b/sectionfilter.c @@ -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) diff --git a/sectionfilter.h b/sectionfilter.h index aae7f49..1ae6dd8 100644 --- a/sectionfilter.h +++ b/sectionfilter.h @@ -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); diff --git a/server.c b/server.c new file mode 100644 index 0000000..126ed3d --- /dev/null +++ b/server.c @@ -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 + +#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; +} diff --git a/server.h b/server.h new file mode 100644 index 0000000..7636cac --- /dev/null +++ b/server.h @@ -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 { +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 diff --git a/setup.c b/setup.c index d0b7438..5cf73c2 100644 --- a/setup.c +++ b/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(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()])); diff --git a/setup.h b/setup.h index d097381..7d2b60a 100644 --- a/setup.h +++ b/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 helpM; - eOSState ChannelScan(void); + eOSState DeviceScan(void); + eOSState DeviceInfo(void); eOSState ShowInfo(void); void Setup(void); void StoreFilters(const char *nameP, int *valuesP); diff --git a/tuner.c b/tuner.c index 04fd0bf..ef53c65 100644 --- a/tuner.c +++ b/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(); diff --git a/tuner.h b/tuner.h index bd6bf19..167b477 100644 --- a/tuner.h +++ b/tuner.h @@ -19,6 +19,7 @@ #include #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);