diff -Nru vdr-plugin-satip-2.3.0/config.c vdr-plugin-satip-2.4.0/config.c --- vdr-plugin-satip-2.3.0/config.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/config.c 2018-04-15 18:30:59.000000000 +0000 @@ -22,7 +22,8 @@ transportModeM(eTransportModeUnicast), detachedModeM(false), disableServerQuirksM(false), - useSingleModelServersM(false) + useSingleModelServersM(false), + rtpRcvBufSizeM(0) { for (unsigned int i = 0; i < ELEMENTS(cicamsM); ++i) cicamsM[i] = 0; diff -Nru vdr-plugin-satip-2.3.0/config.h vdr-plugin-satip-2.4.0/config.h --- vdr-plugin-satip-2.3.0/config.h 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/config.h 2018-04-15 18:30:59.000000000 +0000 @@ -28,6 +28,7 @@ int cicamsM[MAX_CICAM_COUNT]; int disabledSourcesM[MAX_DISABLED_SOURCES_COUNT]; int disabledFiltersM[SECTION_FILTER_TABLE_SIZE]; + size_t rtpRcvBufSizeM; public: enum eOperatingMode { @@ -89,6 +90,7 @@ int GetDisabledFilters(unsigned int indexP) const; unsigned int GetPortRangeStart(void) const { return portRangeStartM; } unsigned int GetPortRangeStop(void) const { return portRangeStopM; } + size_t GetRtpRcvBufSize(void) const { return rtpRcvBufSizeM; } void SetOperatingMode(unsigned int operatingModeP) { operatingModeM = operatingModeP; } void SetTraceMode(unsigned int modeP) { traceModeM = (modeP & eTraceModeMask); } @@ -104,6 +106,7 @@ void SetDisabledFilters(unsigned int indexP, int numberP); void SetPortRangeStart(unsigned int rangeStartP) { portRangeStartM = rangeStartP; } void SetPortRangeStop(unsigned int rangeStopP) { portRangeStopM = rangeStopP; } + void SetRtpRcvBufSize(size_t sizeP) { rtpRcvBufSizeM = sizeP; } }; extern cSatipConfig SatipConfig; diff -Nru vdr-plugin-satip-2.3.0/debian/changelog vdr-plugin-satip-2.4.0/debian/changelog --- vdr-plugin-satip-2.3.0/debian/changelog 2018-04-15 17:42:26.000000000 +0000 +++ vdr-plugin-satip-2.4.0/debian/changelog 2018-05-30 20:30:44.000000000 +0000 @@ -1,3 +1,10 @@ +vdr-plugin-satip (2.4.0-1) unstable; urgency=medium + + * New upstream version + * Dropped gcc7-patch - fixed upstream + + -- Tobias Grimm Wed, 30 May 2018 22:30:44 +0200 + vdr-plugin-satip (2.3.0-3) unstable; urgency=medium * VCS moved to salsa.debian.org diff -Nru vdr-plugin-satip-2.3.0/debian/patches/gcc7.patch vdr-plugin-satip-2.4.0/debian/patches/gcc7.patch --- vdr-plugin-satip-2.3.0/debian/patches/gcc7.patch 2018-04-15 17:42:26.000000000 +0000 +++ vdr-plugin-satip-2.4.0/debian/patches/gcc7.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ ---- a/satip.c -+++ b/satip.c -@@ -5,6 +5,7 @@ - * - */ - -+#include - #include - #include - #include "common.h" diff -Nru vdr-plugin-satip-2.3.0/debian/patches/series vdr-plugin-satip-2.4.0/debian/patches/series --- vdr-plugin-satip-2.3.0/debian/patches/series 2018-04-15 17:42:26.000000000 +0000 +++ vdr-plugin-satip-2.4.0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -gcc7.patch diff -Nru vdr-plugin-satip-2.3.0/detectsatip.py vdr-plugin-satip-2.4.0/detectsatip.py --- vdr-plugin-satip-2.3.0/detectsatip.py 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/detectsatip.py 2018-04-15 18:30:59.000000000 +0000 @@ -0,0 +1,91 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +""" Simple tool to detect SAT>IP devices as JSON. +""" +import json +import socket +import sys +import xml.etree.ElementTree as ET +import requests + +SSDP_BIND = '0.0.0.0' +SSDP_ADDR = '239.255.255.250' +SSDP_PORT = 1900 +SSDP_MX = 1 +SSDP_ST = 'urn:ses-com:device:SatIPServer:1' +SSDP_REQUEST = 'M-SEARCH * HTTP/1.1\r\n' + \ + 'HOST: %s:%d\r\n' % (SSDP_ADDR, SSDP_PORT) + \ + 'MAN: "ssdp:discover"\r\n' + \ + 'MX: %d\r\n' % (SSDP_MX, ) + \ + 'ST: %s\r\n' % (SSDP_ST, ) + \ + '\r\n' + + +def parse_satip_xml(data): + """ Parse SAT>IP XML data. + + Args: + data (str): XML input data.. + + Returns: + dict: Parsed SAT>IP device name and frontend information. + """ + result = {'name': '', 'frontends': {}} + if data: + root = ET.fromstring(data) + name = root.find('.//*/{urn:schemas-upnp-org:device-1-0}friendlyName') + result['name'] = name.text + satipcap = root.find('.//*/{urn:ses-com:satip}X_SATIPCAP') + caps = {} + for system in satipcap.text.split(","): + cap = system.split("-") + if cap: + count = int(cap[1]) + if cap[0] in caps: + count = count + caps[cap[0]] + caps[cap[0]] = count + result['frontends'] = caps + return result + + +def detect_satip_devices(): + """ Detect available SAT>IP devices by sending a broadcast message. + + Returns: + list: Found SAT>IP devices. + """ + urls = [] + devices = [] + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.setblocking(0) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + try: + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + except BaseException: + pass + sock.settimeout(1) + sock.bind((SSDP_BIND, SSDP_PORT)) + sock.sendto(SSDP_REQUEST, (SSDP_ADDR, SSDP_PORT)) + try: + while 1: + data = sock.recv(1024) + if data: + for row in data.split('\r\n'): + if 'LOCATION:' in row: + url = row.replace('LOCATION:', '').strip() + if url in urls: + continue + urls.append(url) + info = requests.get(url, timeout=2) + devices.append(parse_satip_xml(info.text)) + else: + break + except BaseException: + pass + sock.close() + return devices + + +if __name__ == '__main__': + json.dump(detect_satip_devices(), fp=sys.stdout, sort_keys=True, indent=2) diff -Nru vdr-plugin-satip-2.3.0/device.c vdr-plugin-satip-2.4.0/device.c --- vdr-plugin-satip-2.3.0/device.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/device.c 2018-04-15 18:30:58.000000000 +0000 @@ -15,14 +15,17 @@ static cSatipDevice * SatipDevicesS[SATIP_MAX_DEVICES] = { NULL }; +cMutex cSatipDevice::mutexS = cMutex(); + cSatipDevice::cSatipDevice(unsigned int indexP) : deviceIndexM(indexP), - isPacketDeliveredM(false), + bytesDeliveredM(0), isOpenDvrM(false), + checkTsBufferM(false), deviceNameM(*cString::sprintf("%s %d", *DeviceType(), deviceIndexM)), channelM(), createdM(0), - mutexM() + tunedM() { unsigned int bufsize = (unsigned int)SATIP_BUFFER_SIZE; bufsize -= (bufsize % TS_SIZE); @@ -42,6 +45,8 @@ cSatipDevice::~cSatipDevice() { debug1("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); + // Release immediately any pending conditional wait + tunedM.Broadcast(); // Stop section handler StopSectionHandler(); DELETE_POINTER(pSectionFilterHandlerM); @@ -211,6 +216,21 @@ return SatipConfig.IsOperatingModeLow(); } +bool cSatipDevice::SignalStats(int &Valid, double *Strength, double *Cnr, double *BerPre, double *BerPost, double *Per, int *Status) const +{ + debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); + Valid = DTV_STAT_VALID_NONE; + if (Strength && pTunerM) { + *Strength = pTunerM->SignalStrengthDBm(); + Valid |= DTV_STAT_VALID_STRENGTH; + } + if (Status) { + *Status = HasLock() ? (DTV_STAT_HAS_SIGNAL | DTV_STAT_HAS_CARRIER | DTV_STAT_HAS_VITERBI | DTV_STAT_HAS_SYNC | DTV_STAT_HAS_LOCK) : DTV_STAT_HAS_NONE; + Valid |= DTV_STAT_VALID_STATUS; + } + return Valid != DTV_STAT_VALID_NONE; +} + int cSatipDevice::SignalStrength(void) const { debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); @@ -329,6 +349,7 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP) { + cMutexLock MutexLock(&mutexS); // Global lock to prevent any simultaneous zapping debug9("%s (%d, %d) [device %u]", __PRETTY_FUNCTION__, channelP ? channelP->Number() : -1, liveViewP, deviceIndexM); if (channelP) { cDvbTransponderParameters dtp(channelP->Parameters()); @@ -346,6 +367,8 @@ if (pTunerM && pTunerM->SetSource(server, channelP->Transponder(), *params, deviceIndexM)) { channelM = *channelP; deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server)); + // Wait for actual channel tuning to prevent simultaneous frontend allocation failures + tunedM.TimedWait(mutexS, eTuningTimeoutMs); return true; } } @@ -357,6 +380,13 @@ return false; } +void cSatipDevice::SetChannelTuned(void) +{ + debug9("%s () [device %u]", __PRETTY_FUNCTION__, deviceIndexM); + // Release immediately any pending conditional wait + tunedM.Broadcast(); +} + bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP) { debug12("%s (%d, %d, %d) [device %u]", __PRETTY_FUNCTION__, handleP ? handleP->pid : -1, typeP, onP, deviceIndexM); @@ -395,7 +425,7 @@ bool cSatipDevice::OpenDvr(void) { debug9("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); - isPacketDeliveredM = false; + bytesDeliveredM = 0; tsBufferM->Clear(); if (pTunerM) pTunerM->Open(); @@ -481,13 +511,17 @@ return !Receiving(); } -uchar *cSatipDevice::GetData(int *availableP) +uchar *cSatipDevice::GetData(int *availableP, bool checkTsBuffer) { debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); if (isOpenDvrM && tsBufferM) { int count = 0; - if (isPacketDeliveredM) - SkipData(TS_SIZE); + if (bytesDeliveredM) { + tsBufferM->Del(bytesDeliveredM); + bytesDeliveredM = 0; + } + if (checkTsBuffer && tsBufferM->Available() < TS_SIZE) + return NULL; uchar *p = tsBufferM->Get(count); if (p && count >= TS_SIZE) { if (*p != TS_SYNC_BYTE) { @@ -501,7 +535,7 @@ info("Skipped %d bytes to sync on TS packet", count); return NULL; } - isPacketDeliveredM = true; + bytesDeliveredM = TS_SIZE; if (availableP) *availableP = count; // Update pid statistics @@ -515,8 +549,7 @@ void cSatipDevice::SkipData(int countP) { debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); - tsBufferM->Del(countP); - isPacketDeliveredM = false; + bytesDeliveredM = countP; // Update buffer statistics AddBufferStatistic(countP, tsBufferM->Available()); } @@ -530,11 +563,12 @@ if (cCamSlot *cs = CamSlot()) { if (cs->WantsTsData()) { int available; - dataP = GetData(&available); - if (dataP) { - dataP = cs->Decrypt(dataP, available); - SkipData(available); - } + dataP = GetData(&available, checkTsBufferM); + if (!dataP) + available = 0; + dataP = cs->Decrypt(dataP, available); + SkipData(available); + checkTsBufferM = dataP != NULL; return true; } } diff -Nru vdr-plugin-satip-2.3.0/device.h vdr-plugin-satip-2.4.0/device.h --- vdr-plugin-satip-2.3.0/device.h 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/device.h 2018-04-15 18:30:58.000000000 +0000 @@ -18,7 +18,7 @@ class cSatipDevice : public cDevice, public cSatipPidStatistics, public cSatipBufferStatistics, public cSatipDeviceIf { // static ones public: - static unsigned int deviceCount; + static cMutex mutexS; static bool Initialize(unsigned int DeviceCount); static void Shutdown(void); static unsigned int Count(void); @@ -28,18 +28,20 @@ // private parts private: enum { - eReadyTimeoutMs = 2000 // in milliseconds + eReadyTimeoutMs = 2000, // in milliseconds + eTuningTimeoutMs = 1000 // in milliseconds }; unsigned int deviceIndexM; - bool isPacketDeliveredM; + int bytesDeliveredM; bool isOpenDvrM; + bool checkTsBufferM; cString deviceNameM; cChannel channelM; cRingBufferLinear *tsBufferM; cSatipTuner *pTunerM; cSatipSectionFilterHandler *pSectionFilterHandlerM; cTimeMs createdM; - cMutex mutexM; + cCondVar tunedM; // constructor & destructor public: @@ -63,6 +65,7 @@ virtual cString DeviceType(void) const; virtual cString DeviceName(void) const; virtual bool AvoidRecording(void) const; + virtual bool SignalStats(int &Valid, double *Strength = NULL, double *Cnr = NULL, double *BerPre = NULL, double *BerPost = NULL, double *Per = NULL, int *Status = NULL) const; virtual int SignalStrength(void) const; virtual int SignalQuality(void) const; @@ -82,7 +85,7 @@ // for recording private: - uchar *GetData(int *availableP = NULL); + uchar *GetData(int *availableP = NULL, bool checkTsBuffer = false); void SkipData(int countP); protected: @@ -98,7 +101,7 @@ // for transponder lock public: - virtual bool HasLock(int timeoutMsP) const; + virtual bool HasLock(int timeoutMsP = 0) const; // for common interface public: @@ -107,6 +110,7 @@ // for internal device interface public: virtual void WriteData(u_char *bufferP, int lengthP); + virtual void SetChannelTuned(void); virtual int GetId(void); virtual int GetPmtPid(void); virtual int GetCISlot(void); diff -Nru vdr-plugin-satip-2.3.0/deviceif.h vdr-plugin-satip-2.4.0/deviceif.h --- vdr-plugin-satip-2.3.0/deviceif.h 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/deviceif.h 2018-04-15 18:30:59.000000000 +0000 @@ -13,6 +13,7 @@ cSatipDeviceIf() {} virtual ~cSatipDeviceIf() {} virtual void WriteData(u_char *bufferP, int lengthP) = 0; + virtual void SetChannelTuned(void) = 0; virtual int GetId(void) = 0; virtual int GetPmtPid(void) = 0; virtual int GetCISlot(void) = 0; diff -Nru vdr-plugin-satip-2.3.0/discover.c vdr-plugin-satip-2.4.0/discover.c --- vdr-plugin-satip-2.3.0/discover.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/discover.c 2018-04-15 18:30:58.000000000 +0000 @@ -30,10 +30,10 @@ { debug1("%s", __PRETTY_FUNCTION__); if (instanceS) { - if (serversP) { - for (cSatipDiscoverServer *s = serversP->First(); s; s = serversP->Next(s)) - instanceS->AddServer(s->IpAddress(), s->IpPort(), s->Model(), s->Filters(), s->Description(), s->Quirk()); - } + if (serversP) { + for (cSatipDiscoverServer *s = serversP->First(); s; s = serversP->Next(s)) + instanceS->AddServer(s->SrcAddress(), s->IpAddress(), s->IpPort(), s->Model(), s->Filters(), s->Description(), s->Quirk()); + } else instanceS->Activate(); } @@ -271,12 +271,12 @@ model = modelNode.text().as_string("DVBS2-1"); } #endif - AddServer(addrP, portP, model, NULL, desc, cSatipServer::eSatipQuirkNone); + AddServer(NULL, addrP, portP, model, NULL, desc, cSatipServer::eSatipQuirkNone); } -void cSatipDiscover::AddServer(const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP) +void cSatipDiscover::AddServer(const char *srcAddrP, const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP) { - debug1("%s (%s, %d, %s, %s, %s, %d)", __PRETTY_FUNCTION__, addrP, portP, modelP, filtersP, descP, quirkP); + debug1("%s (%s, %s, %d, %s, %s, %s, %d)", __PRETTY_FUNCTION__, srcAddrP, addrP, portP, modelP, filtersP, descP, quirkP); cMutexLock MutexLock(&mutexM); if (SatipConfig.GetUseSingleModelServers() && modelP && !isempty(modelP)) { int n = 0; @@ -285,9 +285,9 @@ while (r) { r = skipspace(r); cString desc = cString::sprintf("%s #%d", !isempty(descP) ? descP : "MyBrokenHardware", n++); - cSatipServer *tmp = new cSatipServer(addrP, portP, r, filtersP, desc, quirkP); + cSatipServer *tmp = new cSatipServer(srcAddrP, addrP, portP, r, filtersP, desc, quirkP); if (!serversM.Update(tmp)) { - info("Adding server '%s|%s|%s' Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none"); + info("Adding server '%s|%s|%s' Bind: %s Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->SrcAddress()) ? tmp->SrcAddress() : "default", !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none"); serversM.Add(tmp); } else @@ -297,9 +297,9 @@ FREE_POINTER(p); } else { - cSatipServer *tmp = new cSatipServer(addrP, portP, modelP, filtersP, descP, quirkP); + cSatipServer *tmp = new cSatipServer(srcAddrP, addrP, portP, modelP, filtersP, descP, quirkP); if (!serversM.Update(tmp)) { - info("Adding server '%s|%s|%s' Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none"); + info("Adding server '%s|%s|%s' Bind: %s Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->SrcAddress()) ? tmp->SrcAddress() : "default", !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none"); serversM.Add(tmp); } else @@ -391,6 +391,13 @@ return serversM.HasCI(serverP); } +cString cSatipDiscover::GetSourceAddress(cSatipServer *serverP) +{ + debug16("%s", __PRETTY_FUNCTION__); + cMutexLock MutexLock(&mutexM); + return serversM.GetSrcAddress(serverP); +} + cString cSatipDiscover::GetServerAddress(cSatipServer *serverP) { debug16("%s", __PRETTY_FUNCTION__); diff -Nru vdr-plugin-satip-2.3.0/discover.h vdr-plugin-satip-2.4.0/discover.h --- vdr-plugin-satip-2.3.0/discover.h 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/discover.h 2018-04-15 18:30:58.000000000 +0000 @@ -23,17 +23,19 @@ private: int ipPortM; int quirkM; + cString srcAddressM; cString ipAddressM; cString descriptionM; cString modelM; cString filtersM; public: - cSatipDiscoverServer(const char *ipAddressP, const int ipPortP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP) + cSatipDiscoverServer(const char *srcAddressP, const char *ipAddressP, const int ipPortP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP) { - ipAddressM = ipAddressP; ipPortM = ipPortP; modelM = modelP; filtersM = filtersP; descriptionM = descriptionP; quirkM = quirkP; + srcAddressM = srcAddressP; ipAddressM = ipAddressP; ipPortM = ipPortP; modelM = modelP; filtersM = filtersP; descriptionM = descriptionP; quirkM = quirkP; } int IpPort(void) { return ipPortM; } int Quirk(void) { return quirkM; } + const char *SrcAddress(void) { return *srcAddressM; } const char *IpAddress(void) { return *ipAddressM; } const char *Model(void) { return *modelM; } const char *Filters(void) { return *filtersM; } @@ -69,7 +71,7 @@ void Deactivate(void); int ParseRtspPort(void); void ParseDeviceInfo(const char *addrP, const int portP); - void AddServer(const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP); + void AddServer(const char *srcAddrP, const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP); void Fetch(const char *urlP); // constructor cSatipDiscover(); @@ -98,6 +100,7 @@ bool IsServerQuirk(cSatipServer *serverP, int quirkP); bool HasServerCI(cSatipServer *serverP); cString GetServerAddress(cSatipServer *serverP); + cString GetSourceAddress(cSatipServer *serverP); int GetServerPort(cSatipServer *serverP); cString GetServerList(void); int NumProvidedSystems(void); diff -Nru vdr-plugin-satip-2.3.0/HISTORY vdr-plugin-satip-2.4.0/HISTORY --- vdr-plugin-satip-2.3.0/HISTORY 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/HISTORY 2018-04-15 19:42:06.000000000 +0000 @@ -157,6 +157,15 @@ - Added support for activating/deactivating server on-the-fly. - Extended command-line parameters for setting server quirks. +2017-08-15: Version 2.2.5 + +- Added Polish translation (Thanks to Tomasz Nowak). +- Updated Catalan and Spanish translations (Thanks to Gabriel Bonich). +- Added support for KATHREIN SatIP Server (Thanks to kavanu). +- Added support for FRITZ!Box 6490 Cable (Thanks to 9000h). +- Updated FRITZ!WLAN Repeater DVB-C detection for the latest firmware (Thanks to 9000h). +- Added GCC7 compatibility (Thanks to Sascha Kuehndel). + =================================== VDR Plugin 'satip' Revision History @@ -174,3 +183,27 @@ - Added multicast and RTP-over-TCP support. - Added support for activating/deactivating server on-the-fly. - Extended command-line parameters for setting server quirks. + +2017-08-15: Version 2.3.1 + +- Updated for vdr-2.3.7 (Thanks to Klaus Schmidinger). +- Added Polish translation (Thanks to Tomasz Nowak). +- Updated Catalan and Spanish translations (Thanks to Gabriel Bonich). +- Added support for KATHREIN SatIP Server (Thanks to kavanu). +- Added support for FRITZ!Box 6490 Cable (Thanks to 9000h). +- Updated FRITZ!WLAN Repeater DVB-C detection for the latest firmware (Thanks to 9000h). +- Added GCC7 compatibility (Thanks to Sascha Kuehndel). + + +=================================== +VDR Plugin 'satip' Revision History +=================================== + +2018-04-15: Version 2.4.0 + +- Updated for vdr-2.4.0. +- Removed speed limit. +- Fixed transport media changes. +- Fixed memory leak in cSatipSectionFilter (Thanks to Alexander Pipelka). +- Added more robust section filter handling (Thanks to Alexander Pipelka). +- Added a command line parameter for the RTP receive buffer size (Thanks to Stefan Rehm). diff -Nru vdr-plugin-satip-2.3.0/Makefile vdr-plugin-satip-2.4.0/Makefile --- vdr-plugin-satip-2.3.0/Makefile 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/Makefile 2018-04-15 18:30:58.000000000 +0000 @@ -88,14 +88,15 @@ ### Implicit rules: %.o: %.c - $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< + @echo CC $@ + $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< ### Dependencies: MAKEDEP = $(CXX) -MM -MG DEPFILE = .dependencies $(DEPFILE): Makefile - @$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + $(Q)$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ -include $(DEPFILE) @@ -108,17 +109,21 @@ I18Npot = $(PODIR)/$(PLUGIN).pot %.mo: %.po - msgfmt -c -o $@ $< + @echo MO $@ + $(Q)msgfmt -c -o $@ $< $(I18Npot): $(wildcard *.c) - xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ `ls $^` + @echo GT $@ + $(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ `ls $^` %.po: $(I18Npot) - msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< + @echo PO $@ + $(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @touch $@ $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo - install -D -m644 $< $@ + @echo IN $@ + $(Q)install -D -m644 $< $@ .PHONY: i18n i18n: $(I18Nmo) $(I18Npot) @@ -128,11 +133,13 @@ ### Targets: $(SOFILE): $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@ - @$(STRIP) $@ + @echo LD $@ + $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@ + $(Q)$(STRIP) $@ install-lib: $(SOFILE) - install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) + @echo IN $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) + $(Q)install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install-conf: @mkdir -p $(DESTDIR)$(CFGDIR)/plugins/$(PLUGIN) @@ -153,4 +160,4 @@ .PHONY: cppcheck cppcheck: - @cppcheck --language=c++ --enable=all -v -f $(OBJS:%.o=%.c) + $(Q)cppcheck --language=c++ --enable=all -v -f $(OBJS:%.o=%.c) diff -Nru vdr-plugin-satip-2.3.0/param.c vdr-plugin-satip-2.4.0/param.c --- vdr-plugin-satip-2.3.0/param.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/param.c 2018-04-15 18:30:59.000000000 +0000 @@ -166,6 +166,7 @@ if ((channelP->Rid() % 100) > 0) q += snprintf(q, STBUFLEFT, "&fe=%d", channelP->Rid() % 100); ST(" S *") q += snprintf(q, STBUFLEFT, "src=%d&", ((src > 0) && (src <= 255)) ? src : 1); + if (freq >= 0L) q += snprintf(q, STBUFLEFT, "freq=%s", *dtoa(freq, "%lg")); ST(" S *") q += snprintf(q, STBUFLEFT, "&pol=%c", tolower(dtp.Polarization())); ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.RollOff(), SatipRollOffValues); diff -Nru vdr-plugin-satip-2.3.0/po/ca_ES.po vdr-plugin-satip-2.4.0/po/ca_ES.po --- vdr-plugin-satip-2.3.0/po/ca_ES.po 2016-12-18 15:44:25.000000000 +0000 +++ vdr-plugin-satip-2.4.0/po/ca_ES.po 2018-04-15 19:42:17.000000000 +0000 @@ -1,14 +1,14 @@ # VDR plugin language source file. -# Copyright (C) 2007-2016 Rolf Ahrenberg +# Copyright (C) 2007-2018 Rolf Ahrenberg # This file is distributed under the same license as the satip package. -# Gabriel Bonich, 2014-2015 +# Gabriel Bonich, 2014-2017 # msgid "" msgstr "" -"Project-Id-Version: vdr-satip 2.3.0\n" +"Project-Id-Version: vdr-satip 2.4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-12-18 12:18+0200\n" -"PO-Revision-Date: 2016-12-18 12:18+0200\n" +"POT-Creation-Date: 2018-04-15 04:15+0300+0300\n" +"PO-Revision-Date: 2018-04-15 04:15+0300+0300\n" "Last-Translator: Gabriel Bonich \n" "Language-Team: Catalan \n" "Language: ca\n" @@ -86,13 +86,13 @@ msgstr "Alt" msgid "Unicast" -msgstr "" +msgstr "Unicast" msgid "Multicast" -msgstr "" +msgstr "Multicast" msgid "RTP-over-TCP" -msgstr "" +msgstr "RTP-per sobre-TCP" msgid "Button$Devices" msgstr "Dispositius" @@ -188,7 +188,7 @@ msgstr "Definir un filtre mal comportar a la llista negra." msgid "Transport mode" -msgstr "" +msgstr "Tipus de Transmissió" msgid "" "Define which transport mode shall be used.\n" diff -Nru vdr-plugin-satip-2.3.0/po/de_DE.po vdr-plugin-satip-2.4.0/po/de_DE.po --- vdr-plugin-satip-2.3.0/po/de_DE.po 2016-12-18 15:44:25.000000000 +0000 +++ vdr-plugin-satip-2.4.0/po/de_DE.po 2018-04-15 19:42:17.000000000 +0000 @@ -1,14 +1,14 @@ # VDR plugin language source file. -# Copyright (C) 2007-2016 Rolf Ahrenberg +# Copyright (C) 2007-2018 Rolf Ahrenberg # This file is distributed under the same license as the satip package. -# Frank Neumann, 2014-2016 +# Frank Neumann, 2014-2017 # msgid "" msgstr "" -"Project-Id-Version: vdr-satip 2.3.0\n" +"Project-Id-Version: vdr-satip 2.4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-12-18 12:18+0200\n" -"PO-Revision-Date: 2016-12-18 12:18+0200\n" +"POT-Creation-Date: 2018-04-15 04:15+0300+0300\n" +"PO-Revision-Date: 2018-04-15 04:15+0300+0300\n" "Last-Translator: Frank Neumann \n" "Language-Team: German \n" "Language: de\n" diff -Nru vdr-plugin-satip-2.3.0/po/es_ES.po vdr-plugin-satip-2.4.0/po/es_ES.po --- vdr-plugin-satip-2.3.0/po/es_ES.po 2016-12-18 15:44:25.000000000 +0000 +++ vdr-plugin-satip-2.4.0/po/es_ES.po 2018-04-15 19:42:17.000000000 +0000 @@ -1,14 +1,14 @@ # VDR plugin language source file. -# Copyright (C) 2007-2016 Rolf Ahrenberg +# Copyright (C) 2007-2018 Rolf Ahrenberg # This file is distributed under the same license as the satip package. -# Gabriel Bonich, 2014-2015 +# Gabriel Bonich, 2014-2017 # msgid "" msgstr "" -"Project-Id-Version: vdr-satip 2.3.0\n" +"Project-Id-Version: vdr-satip 2.4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-12-18 12:18+0200\n" -"PO-Revision-Date: 2016-12-18 12:18+0200\n" +"POT-Creation-Date: 2018-04-15 04:15+0300+0300\n" +"PO-Revision-Date: 2018-04-15 04:15+0300+0300\n" "Last-Translator: Gabriel Bonich \n" "Language-Team: Spanish \n" "Language: es\n" @@ -86,13 +86,13 @@ msgstr "Alto" msgid "Unicast" -msgstr "" +msgstr "Unicast" msgid "Multicast" -msgstr "" +msgstr "Multicast" msgid "RTP-over-TCP" -msgstr "" +msgstr "RTP-antes que-TCP" msgid "Button$Devices" msgstr "Dispositivos" @@ -188,7 +188,7 @@ msgstr "Define un filtro para poner en la lista negra." msgid "Transport mode" -msgstr "" +msgstr "Tipo de Transmisión" msgid "" "Define which transport mode shall be used.\n" diff -Nru vdr-plugin-satip-2.3.0/po/fi_FI.po vdr-plugin-satip-2.4.0/po/fi_FI.po --- vdr-plugin-satip-2.3.0/po/fi_FI.po 2016-12-18 15:44:25.000000000 +0000 +++ vdr-plugin-satip-2.4.0/po/fi_FI.po 2018-04-15 19:42:17.000000000 +0000 @@ -1,14 +1,14 @@ # VDR plugin language source file. -# Copyright (C) 2007-2016 Rolf Ahrenberg +# Copyright (C) 2007-2018 Rolf Ahrenberg # This file is distributed under the same license as the satip package. -# Rolf Ahrenberg, 2015-2016 +# Rolf Ahrenberg, 2015-2017 # msgid "" msgstr "" -"Project-Id-Version: vdr-satip 2.3.0\n" +"Project-Id-Version: vdr-satip 2.4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-12-18 12:18+0200\n" -"PO-Revision-Date: 2016-12-18 12:18+0200\n" +"POT-Creation-Date: 2018-04-15 04:15+0300+0300\n" +"PO-Revision-Date: 2018-04-15 04:15+0300+0300\n" "Last-Translator: Rolf Ahrenberg\n" "Language-Team: Finnish \n" "Language: fi\n" diff -Nru vdr-plugin-satip-2.3.0/po/pl_PL.po vdr-plugin-satip-2.4.0/po/pl_PL.po --- vdr-plugin-satip-2.3.0/po/pl_PL.po 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/po/pl_PL.po 2018-04-15 19:42:17.000000000 +0000 @@ -0,0 +1,206 @@ +# VDR plugin language source file. +# Copyright (C) 2007-2018 Rolf Ahrenberg +# This file is distributed under the same license as the vdr-satip package. +# Tomasz Maciej Nowak, 2017 +# +msgid "" +msgstr "" +"Project-Id-Version: vdr-satip 2.4.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-04-15 04:15+0300+0300\n" +"PO-Revision-Date: 2018-04-15 04:15+0300+0300\n" +"Last-Translator: Tomasz Maciej Nowak \n" +"Language-Team: Polish \n" +"Language: pl_PL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.11\n" + +msgid "PAT (0x00)" +msgstr "PAT (0x00)" + +msgid "NIT (0x40)" +msgstr "NIT (0x40)" + +msgid "SDT (0x42)" +msgstr "SDT (0x42)" + +msgid "EIT (0x4E/0x4F/0x5X/0x6X)" +msgstr "EIT (0x4E/0x4F/0x5X/0x6X)" + +msgid "TDT (0x70)" +msgstr "TDT (0x70)" + +msgid "SAT>IP information not available!" +msgstr "Informacja o SAT>IP niedostępna!" + +msgid "SAT>IP Devices" +msgstr "Urządzenia SAT>IP" + +msgid "SAT>IP Server" +msgstr "Serwer SAT>IP" + +msgid "Address" +msgstr "Adres" + +msgid "Model" +msgstr "Model" + +msgid "Description" +msgstr "Opis" + +msgid "CI extension" +msgstr "Rozszerzenie CI" + +msgid "Creation date" +msgstr "Data produkcji" + +msgid "SAT>IP Device Status" +msgstr "Status urządzenia SAT>IP" + +msgid "SAT>IP Information" +msgstr "SAT>IP - informacje" + +msgid "General" +msgstr "Główne" + +msgid "Pids" +msgstr "Pidy" + +msgid "Filters" +msgstr "Filtry" + +msgid "Bits/bytes" +msgstr "Bity/bajty" + +msgid "off" +msgstr "wyłączone" + +msgid "low" +msgstr "niski" + +msgid "normal" +msgstr "normalny" + +msgid "high" +msgstr "wysoki" + +msgid "Unicast" +msgstr "Unicast" + +msgid "Multicast" +msgstr "Multicast" + +msgid "RTP-over-TCP" +msgstr "RTP-over-TCP" + +msgid "Button$Devices" +msgstr "Urządzenia" + +msgid "Operating mode" +msgstr "Tryb pracy" + +msgid "" +"Define the used operating mode for all SAT>IP devices:\n" +"\n" +"off - devices are disabled\n" +"low - devices are working at the lowest priority\n" +"normal - devices are working within normal parameters\n" +"high - devices are working at the highest priority" +msgstr "" +"Określa tryb pracy wszystkich urządzeń SAT>IP:\n" +"\n" +"wyłączone - urządzenia są wyłączone\n" +"niski - urządzenia pracują z najniższym priorytetem\n" +"normalny - urządzenia pracują z normalnymi parametrami\n" +"wysoki - urządzenia pracują z najwyższym priorytetem" + +msgid "Enable CI extension" +msgstr "Włącz rozszerzenie CI" + +msgid "" +"Define whether a CI extension shall be used.\n" +"\n" +"This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)." +msgstr "" +"Określa czy korzystać z rozszerzenia CI.\n" +"\n" +"To ustawienie włącza obsługę dostępnego czytnika CI/CAM w niektórych urządzeniach SAT>IP (np. Digital Devices OctopusNet)." + +msgid "CI/CAM" +msgstr "CI/CAM" + +msgid "" +"Define a desired CAM type for the CI slot.\n" +"\n" +"The '---' option lets SAT>IP hardware do the auto-selection." +msgstr "" +"Określa typ modułu CAM w czytniku CI.\n" +"\n" +"Opcja '---' pozwala urządzeniu SAT>IP automatycznie wybrać typ." + +msgid "Enable EPG scanning" +msgstr "Włącz skanowanie EPG" + +msgid "" +"Define whether the EPG background scanning shall be used.\n" +"\n" +"This setting disables the automatic EIT scanning functionality for all SAT>IP devices." +msgstr "" +"Określa czy przeprowadzać skanowanie EPG w tle.\n" +"\n" +"To ustawienie wyłącza funkcję automatycznego skanowania EIT dla wszystkich urządzeń SAT>IP." + +msgid "Disabled sources" +msgstr "Wyłączone źródła" + +msgid "none" +msgstr "brak" + +msgid "" +"Define number of sources to be disabled.\n" +"\n" +"SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here." +msgstr "" +"Określa liczbę wyłączonych źródeł.\n" +"\n" +"Serwery SAT>IP mogą nie mieć dostępu do niektórych pozycji satelitarnych, więc tutaj można je wyłączyć." + +msgid "Define a source to be blacklisted." +msgstr "Określ źródła do wyłączenia." + +msgid "Disabled filters" +msgstr "Wyłączone filtry" + +msgid "" +"Define number of section filters to be disabled.\n" +"\n" +"Certain section filters might cause some unwanted behaviour to VDR such as time being falsely synchronized. By blacklisting the filters here, useful section data can be left intact for VDR to process." +msgstr "" +"Określa liczbę wyłączonych filtrów sekcji.\n" +"\n" +"Niektóre filtry sekcji mogą powodować niezamierzone efekty w VDR, takie jak zły czas synchronizacji. Poprzez wyłączenie niektórych filtrów, użyteczne dane sekcji będą dostępne do przetworzenia dla VDR." + +msgid "Filter" +msgstr "Filtr" + +msgid "Define an ill-behaving filter to be blacklisted." +msgstr "Określa filtry powodujące zakłócenia, które mają być wyłączone." + +msgid "Transport mode" +msgstr "Tryb" + +msgid "" +"Define which transport mode shall be used.\n" +"\n" +"Unicast, Multicast, RTP-over-TCP" +msgstr "" +"Określa tryb transmisji.\n" +"Unicast, Multicast, RTP-over-TCP." + +msgid "Active SAT>IP servers:" +msgstr "Aktywne serwery SAT>IP:" + +msgid "Help" +msgstr "Pomoc" diff -Nru vdr-plugin-satip-2.3.0/README vdr-plugin-satip-2.4.0/README --- vdr-plugin-satip-2.3.0/README 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/README 2018-04-15 18:30:58.000000000 +0000 @@ -52,7 +52,7 @@ consists of a DVB system (DVBS2,DVBT2,DVBT,DVBC) and number of available frontends separated by a hyphen: -vdr -P 'satip -s [:]|[:]|[:];...' +vdr -P 'satip -s [@][:]|[:]|[:];...' vdr -P 'satip -s 192.168.0.1|DVBS2-2,DVBT2-2|OctopusNet' vdr -P 'satip -s 192.168.0.1|DVBS2-4|OctopusNet;192.168.0.2|DVBT2-4|minisatip:0x18' vdr -P 'satip -s 192.168.0.1:554|DVBS2-2:S19.2E|OctopusNet;192.168.0.2:8554|DVBS2-4:S19.2E,S1W|minisatip' @@ -159,6 +159,19 @@ from their webpage: http://www.inverto.tv/support/ An update to a newer firmware should be offered afterwards. +- If you are experiencing glitches in the video stream, one possible + reason can be buffer overflows in RTP receive sockets. You can verify + this by checking "receive buffer errors" counter by running "netstat -s" + command. If the counter increases every time a video glitch happens, + you should try to tweak the RTP receive buffer size with the "--rcvbuf" + (-r) plugin parameter. + A good starting point for the buffer size is to double the operating + system default value until errors disappear or the maximum value is + reached. You can check these values in Linux by checking the kernel + parameters: + $ cat /proc/sys/net/core/rmem_default + $ cat /proc/sys/net/core/rmem_max + Acknowledgements: - Big thanks to Digital Devices GmbH for providing the Octopus Net diff -Nru vdr-plugin-satip-2.3.0/rtp.c vdr-plugin-satip-2.4.0/rtp.c --- vdr-plugin-satip-2.3.0/rtp.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/rtp.c 2018-04-15 18:30:59.000000000 +0000 @@ -14,7 +14,8 @@ #include "rtp.h" cSatipRtp::cSatipRtp(cSatipTunerIf &tunerP) -: tunerM(tunerP), +: cSatipSocket(SatipConfig.GetRtpRcvBufSize()), + tunerM(tunerP), bufferLenM(eRtpPacketReadCount * eMaxUdpPacketSizeB), bufferM(MALLOC(unsigned char, bufferLenM)), lastErrorReportM(0), @@ -45,7 +46,7 @@ sequenceNumberM = -1; if (packetErrorsM) { - info("Detected %d RTP packet errors [device %d]", packetErrorsM, tunerM.GetId()); + info("Detected %d RTP packet error%s [device %d]", packetErrorsM, packetErrorsM == 1 ? "": "s", tunerM.GetId()); packetErrorsM = 0; lastErrorReportM = time(NULL); } @@ -80,7 +81,7 @@ else if ((sequenceNumberM >= 0) && (((sequenceNumberM + 1) % 0xFFFF) != seq)) { packetErrorsM++; if (time(NULL) - lastErrorReportM > eReportIntervalS) { - info("Detected %d RTP packet errors [device %d]", packetErrorsM, tunerM.GetId()); + info("Detected %d RTP packet error%s [device %d]", packetErrorsM, packetErrorsM == 1 ? "": "s", tunerM.GetId()); packetErrorsM = 0; lastErrorReportM = time(NULL); } diff -Nru vdr-plugin-satip-2.3.0/rtsp.c vdr-plugin-satip-2.4.0/rtsp.c --- vdr-plugin-satip-2.3.0/rtsp.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/rtsp.c 2018-04-15 18:30:58.000000000 +0000 @@ -164,9 +164,6 @@ SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_TIMEOUT_MS, (long)eConnectTimeoutMs); SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_CONNECTTIMEOUT_MS, (long)eConnectTimeoutMs); - // Limit download speed (bytes/s) - SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_MAX_RECV_SPEED_LARGE, eMaxDownloadSpeedMBits * 131072L); - // Set user-agent SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s (device %d)", PLUGIN_NAME_I18N, VERSION, tunerM.GetId())); } @@ -193,6 +190,22 @@ Create(); } +bool cSatipRtsp::SetInterface(const char *bindAddrP) +{ + debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, bindAddrP, tunerM.GetId()); + bool result = true; + CURLcode res = CURLE_OK; + + if (handleM && !isempty(bindAddrP)) { + SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERFACE, *cString::sprintf("host!%s", bindAddrP)); + } + else { + SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERFACE, NULL); + } + + return result; +} + bool cSatipRtsp::Options(const char *uriP) { debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, uriP, tunerM.GetId()); diff -Nru vdr-plugin-satip-2.3.0/rtsp.h vdr-plugin-satip-2.4.0/rtsp.h --- vdr-plugin-satip-2.3.0/rtsp.h 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/rtsp.h 2018-04-15 18:30:59.000000000 +0000 @@ -27,7 +27,6 @@ enum { eConnectTimeoutMs = 1500, // in milliseconds - eMaxDownloadSpeedMBits = 20, // in megabits per second }; cSatipTunerIf &tunerM; @@ -59,6 +58,7 @@ cString GetActiveMode(void); cString RtspUnescapeString(const char *strP); void Reset(void); + bool SetInterface(const char *bindAddrP); bool Options(const char *uriP); bool Setup(const char *uriP, int rtpPortP, int rtcpPortP, bool useTcpP); bool SetSession(const char *sessionP); diff -Nru vdr-plugin-satip-2.3.0/satip.c vdr-plugin-satip-2.4.0/satip.c --- vdr-plugin-satip-2.3.0/satip.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/satip.c 2018-04-15 19:32:22.000000000 +0000 @@ -5,6 +5,7 @@ * */ +#include #include #include #include "common.h" @@ -19,15 +20,15 @@ #warning "CURL version >= 7.36.0 is recommended" #endif -#if defined(APIVERSNUM) && APIVERSNUM < 20301 -#error "VDR-2.3.1 API version or greater is required!" +#if defined(APIVERSNUM) && APIVERSNUM < 20400 +#error "VDR-2.4.0 API version or greater is required!" #endif #ifndef GITVERSION #define GITVERSION "" #endif - const char VERSION[] = "2.3.0" GITVERSION; + const char VERSION[] = "2.4.0" GITVERSION; static const char DESCRIPTION[] = trNOOP("SAT>IP Devices"); class cPluginSatip : public cPlugin { @@ -90,7 +91,8 @@ " -S, --single set the single model server mode on\n" " -n, --noquirks disable autodetection of the server quirks\n" " -p, --portrange=- set a range of ports used for the RT[C]P server\n" - " a minimum of 2 ports per device is required.\n"; + " a minimum of 2 ports per device is required.\n" + " -r, --rcvbuf override the size of the RTP receive buffer in bytes\n"; } bool cPluginSatip::ProcessArgs(int argc, char *argv[]) @@ -102,6 +104,7 @@ { "trace", required_argument, NULL, 't' }, { "server", required_argument, NULL, 's' }, { "portrange",required_argument, NULL, 'p' }, + { "rcvbuf", required_argument, NULL, 'r' }, { "detach", no_argument, NULL, 'D' }, { "single", no_argument, NULL, 'S' }, { "noquirks", no_argument, NULL, 'n' }, @@ -111,7 +114,7 @@ cString server; cString portrange; int c; - while ((c = getopt_long(argc, argv, "d:t:s:p:DSn", long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "d:t:s:p:r:DSn", long_options, NULL)) != -1) { switch (c) { case 'd': deviceCountM = strtol(optarg, NULL, 0); @@ -134,6 +137,9 @@ case 'p': portrange = optarg; break; + case 'r': + SatipConfig.SetRtpRcvBufSize(strtol(optarg, NULL, 0)); + break; default: return false; } @@ -232,7 +238,7 @@ while (r) { r = skipspace(r); debug3("%s server[%d]=%s", __PRETTY_FUNCTION__, n, r); - cString serverAddr, serverModel, serverFilters, serverDescription; + cString sourceAddr, serverAddr, serverModel, serverFilters, serverDescription; int serverQuirk = cSatipServer::eSatipQuirkNone; int serverPort = SATIP_DEFAULT_RTSP_PORT; int n2 = 0; @@ -243,8 +249,14 @@ switch (n2++) { case 0: { + char *r3 = strchr(r2, '@'); + if (r3) { + *r3 = 0; + sourceAddr = r2; + r2 = r3 + 1; + } serverAddr = r2; - char *r3 = strchr(r2, ':'); + r3 = strchr(r2, ':'); if (r3) { serverPort = strtol(r3 + 1, NULL, 0); serverAddr = serverAddr.Truncate(r3 - r2); @@ -277,10 +289,10 @@ r2 = strtok_r(NULL, "|", &s2); } if (*serverAddr && *serverModel && *serverDescription) { - debug1("%s ipaddr=%s port=%d model=%s (%s) desc=%s (%d)", __PRETTY_FUNCTION__, *serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk); + debug1("%s srcaddr=%s ipaddr=%s port=%d model=%s (%s) desc=%s (%d)", __PRETTY_FUNCTION__, *sourceAddr, *serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk); if (!serversM) serversM = new cSatipDiscoverServers(); - serversM->Add(new cSatipDiscoverServer(*serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk)); + serversM->Add(new cSatipDiscoverServer(*sourceAddr, *serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk)); } ++n; r = strtok_r(NULL, ";", &s); diff -Nru vdr-plugin-satip-2.3.0/sectionfilter.c vdr-plugin-satip-2.4.0/sectionfilter.c --- vdr-plugin-satip-2.3.0/sectionfilter.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/sectionfilter.c 2018-04-15 18:30:59.000000000 +0000 @@ -102,8 +102,11 @@ if (doneqM && !neq) return 0; - if (ringBufferM && (secLenM > 0)) - ringBufferM->Put(new cFrame(secBufM, secLenM)); + if (ringBufferM && (secLenM > 0)) { + cFrame* section = new cFrame(secBufM, secLenM); + if (!ringBufferM->Put(section)) + DELETE_POINTER(section); + } } return 0; } @@ -126,7 +129,7 @@ if (tsFeedpM + lenP > eDmxMaxSectionFeedSize) lenP = (uint8_t)(eDmxMaxSectionFeedSize - tsFeedpM); - if (lenP <= 0) + if (lenP == 0) return 0; memcpy(secBufBaseM + tsFeedpM, bufP, lenP); @@ -141,7 +144,7 @@ for (n = 0; secBufpM + 2 < limit; ++n) { uint16_t seclen = GetLength(secBufM); - if ((seclen <= 0) || (seclen > eDmxMaxSectionSize) || ((seclen + secBufpM) > limit)) + if ((seclen > eDmxMaxSectionSize) || ((seclen + secBufpM) > limit)) return 0; secLenM = seclen; if (pusiSeenM) @@ -209,27 +212,28 @@ } } -bool cSatipSectionFilter::Send(void) +void cSatipSectionFilter::Send(void) { - bool result = false; cFrame *section = ringBufferM->Get(); if (section) { uchar *data = section->Data(); int count = section->Count(); if (data && (count > 0) && (socketM[1] >= 0) && (socketM[0] >= 0)) { - ssize_t len = send(socketM[1], data, count, MSG_EOR); - ERROR_IF(len < 0 && errno != EAGAIN, "send()"); - if (len > 0) { - ringBufferM->Drop(section); - result = !!ringBufferM->Available(); + if (send(socketM[1], data, count, MSG_EOR) > 0) { // Update statistics - AddSectionStatistic(len, 1); + AddSectionStatistic(count, 1); } + else if (errno != EAGAIN) + error("failed to send section data (%i bytes) [device=%d]", count, deviceIndexM); } + ringBufferM->Drop(section); } - return result; } +int cSatipSectionFilter::Available(void) const +{ + return ringBufferM->Available(); +} cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP) : cThread(cString::sprintf("SATIP#%d section handler", deviceIndexP)), @@ -267,54 +271,73 @@ Delete(i); } +void cSatipSectionFilterHandler::SendAll(void) +{ + cMutexLock MutexLock(&mutexM); + bool pendingData; + do { + pendingData = false; + + // zero polling structures + memset(pollFdsM, 0, sizeof(pollFdsM)); + + // assemble all handlers to poll (use -1 to ignore handlers) + for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) { + if (filtersM[i] && filtersM[i]->Available() != 0) { + pollFdsM[i].fd = filtersM[i]->GetFd(); + pollFdsM[i].events = POLLOUT; + pendingData = true; + } + else + pollFdsM[i].fd = -1; + } + + // exit if there isn't any pending data or we time out + if (!pendingData || poll(pollFdsM, eMaxSecFilterCount, eSecFilterSendTimeoutMs) <= 0) + return; + + // send data (if available) + for (unsigned int i = 0; i < eMaxSecFilterCount && pendingData; ++i) { + if (pollFdsM[i].revents & POLLOUT) + filtersM[i]->Send(); + } + } while (pendingData); +} + void cSatipSectionFilterHandler::Action(void) { debug1("%s Entering [device %d]", __PRETTY_FUNCTION__, deviceIndexM); - bool processed = false; // Do the thread loop while (Running()) { - // Send demuxed section packets through all filters - bool retry = false; - mutexM.Lock(); - for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) { - if (filtersM[i] && filtersM[i]->Send()) - retry = true; - } - mutexM.Unlock(); - if (retry) - continue; - // Read one TS packet - if (ringBufferM) { - int len = 0; - if (processed) { - ringBufferM->Del(TS_SIZE); - processed = false; - } - uchar *p = ringBufferM->Get(len); - if (p && (len >= TS_SIZE)) { - if (*p != TS_SYNC_BYTE) { - for (int i = 1; i < len; ++i) { - if (p[i] == TS_SYNC_BYTE) { - len = i; - break; + uchar *p = NULL; + int len = 0; + // Process all pending TS packets + while ((p = ringBufferM->Get(len)) != NULL) { + if (p && (len >= TS_SIZE)) { + if (*p != TS_SYNC_BYTE) { + for (int i = 1; i < len; ++i) { + if (p[i] == TS_SYNC_BYTE) { + len = i; + break; + } } - } - ringBufferM->Del(len); - debug1("%s Skipped %d bytes to sync on TS packet [device %d]", __PRETTY_FUNCTION__, len, deviceIndexM); - continue; - } - // Process TS packet through all filters - mutexM.Lock(); - for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) { - if (filtersM[i]) - filtersM[i]->Process(p); - } - mutexM.Unlock(); - processed = true; - continue; - } - } - cCondWait::SleepMs(10); // to avoid busy loop and reduce cpu load + ringBufferM->Del(len); + debug1("%s Skipped %d bytes to sync on TS packet [device %d]", __PRETTY_FUNCTION__, len, deviceIndexM); + continue; + } + // Process TS packet through all filters + mutexM.Lock(); + for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) { + if (filtersM[i]) + filtersM[i]->Process(p); + } + mutexM.Unlock(); + ringBufferM->Del(TS_SIZE); + } + } + + // Send demuxed section packets through all filters + SendAll(); } debug1("%s Exiting [device %d]", __PRETTY_FUNCTION__, deviceIndexM); } diff -Nru vdr-plugin-satip-2.3.0/sectionfilter.h vdr-plugin-satip-2.4.0/sectionfilter.h --- vdr-plugin-satip-2.3.0/sectionfilter.h 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/sectionfilter.h 2018-04-15 18:30:59.000000000 +0000 @@ -8,6 +8,7 @@ #ifndef __SATIP_SECTIONFILTER_H #define __SATIP_SECTIONFILTER_H +#include #include #include "common.h" @@ -55,23 +56,27 @@ cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_t tidP, uint8_t maskP); virtual ~cSatipSectionFilter(); void Process(const uint8_t* dataP); - bool Send(void); + void Send(void); int GetFd(void) { return socketM[0]; } uint16_t GetPid(void) const { return pidM; } + int Available(void) const; }; class cSatipSectionFilterHandler : public cThread { private: enum { - eMaxSecFilterCount = 32 + eMaxSecFilterCount = 32, + eSecFilterSendTimeoutMs = 10 }; cRingBufferLinear *ringBufferM; cMutex mutexM; int deviceIndexM; cSatipSectionFilter *filtersM[eMaxSecFilterCount]; + struct pollfd pollFdsM[eMaxSecFilterCount]; bool Delete(unsigned int indexP); bool IsBlackListed(u_short pidP, u_char tidP, u_char maskP) const; + void SendAll(void); protected: virtual void Action(void); diff -Nru vdr-plugin-satip-2.3.0/server.c vdr-plugin-satip-2.4.0/server.c --- vdr-plugin-satip-2.3.0/server.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/server.c 2018-04-15 18:30:58.000000000 +0000 @@ -80,8 +80,9 @@ // --- cSatipServer ----------------------------------------------------------- -cSatipServer::cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP) -: addressM((addressP && *addressP) ? addressP : "0.0.0.0"), +cSatipServer::cSatipServer(const char *srcAddressP, const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP) +: srcAddressM((srcAddressP && *srcAddressP) ? srcAddressP : ""), + addressM((addressP && *addressP) ? addressP : "0.0.0.0"), modelM((modelP && *modelP) ? modelP : "DVBS-1"), filtersM((filtersP && *filtersP) ? filtersP : ""), descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"), @@ -116,42 +117,43 @@ // These devices contain a session id bug: // Inverto Airscreen Server IDL 400 ? // Elgato EyeTV Netstream 4Sat ? - if (strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400 - strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1 - strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400 + if (strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400 + strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1 + strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400 ) quirkM |= eSatipQuirkSessionId; // These devices contain support for RTP over TCP: - if (strstr(*descriptionM, "minisatip") || // minisatip server - strstr(*descriptionM, "DVBViewer") || // DVBViewer Media Server - strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400 - strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1 - strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400 + if (strstr(*descriptionM, "minisatip") || // minisatip server + strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server ) quirkM |= eSatipQuirkRtpOverTcp; // These devices contain a play (add/delpids) parameter bug: - if (strstr(*descriptionM, "fritzdvbc") // Fritz!WLAN Repeater DVB-C + if (strstr(*descriptionM, "FRITZ!Box 6490 Cable") || // FRITZ!Box 6490 Cable + strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C + strstr(*descriptionM, "fritzdvbc") // FRITZ!WLAN Repeater DVB-C (old firmware) ) quirkM |= eSatipQuirkPlayPids; // These devices contain a frontend locking bug: - if (strstr(*descriptionM, "fritzdvbc") || // Fritz!WLAN Repeater DVB-C - strstr(*descriptionM, "Schwaiger Sat>IP Server") // Schwaiger MS41IP + if (strstr(*descriptionM, "FRITZ!Box 6490 Cable") || // FRITZ!Box 6490 Cable + strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C + strstr(*descriptionM, "fritzdvbc") || // FRITZ!WLAN Repeater DVB-C (old firmware) + strstr(*descriptionM, "Schwaiger Sat>IP Server") // Schwaiger MS41IP ) quirkM |= eSatipQuirkForceLock; // These devices support the X_PMT protocol extension - if (strstr(*descriptionM, "OctopusNet") || // Digital Devices OctopusNet - strstr(*descriptionM, "minisatip") // minisatip server + if (strstr(*descriptionM, "OctopusNet") || // Digital Devices OctopusNet + strstr(*descriptionM, "minisatip") // minisatip server ) quirkM |= eSatipQuirkCiXpmt; // These devices support the TNR protocol extension - if (strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server + if (strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server ) quirkM |= eSatipQuirkCiTnr; // These devices don't support auto-detection of pilot tones - if (strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400 - strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1 - strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400 - // Kathrein ExIP 414/E + if (strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400 + strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1 + strstr(*descriptionM, "Triax SatIP Converter") || // Triax TSS 400 + strstr(*descriptionM, "KATHREIN SatIP Server") // Kathrein ExIP 414/E ) quirkM |= eSatipQuirkForcePilot; } @@ -446,6 +448,18 @@ } } +cString cSatipServers::GetSrcAddress(cSatipServer *serverP) +{ + cString address = ""; + for (cSatipServer *s = First(); s; s = Next(s)) { + if (s == serverP) { + address = s->SrcAddress(); + break; + } + } + return address; +} + cString cSatipServers::GetAddress(cSatipServer *serverP) { cString address = ""; @@ -486,7 +500,10 @@ { cString list = ""; for (cSatipServer *s = First(); s; s = Next(s)) - list = cString::sprintf("%s%c %s|%s|%s\n", *list, s->IsActive() ? '+' : '-', s->Address(), s->Model(), s->Description()); + if (isempty(s->SrcAddress())) + list = cString::sprintf("%s%c %s|%s|%s\n", *list, s->IsActive() ? '+' : '-', s->Address(), s->Model(), s->Description()); + else + list = cString::sprintf("%s%c %s@%s|%s|%s\n", *list, s->IsActive() ? '+' : '-', s->SrcAddress(), s->Address(), s->Model(), s->Description()); return list; } diff -Nru vdr-plugin-satip-2.3.0/server.h vdr-plugin-satip-2.4.0/server.h --- vdr-plugin-satip-2.3.0/server.h 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/server.h 2018-04-15 18:30:59.000000000 +0000 @@ -57,6 +57,7 @@ enum { eSatipMaxSourceFilters = 16 }; + cString srcAddressM; cString addressM; cString modelM; cString filtersM; @@ -84,7 +85,7 @@ eSatipQuirkForcePilot = 0x40, eSatipQuirkMask = 0xFF }; - cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP); + cSatipServer(const char *srcAddressP, const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP); virtual ~cSatipServer(); virtual int Compare(const cListObject &listObjectP) const; bool Assign(int deviceIdP, int sourceP, int systemP, int transponderP); @@ -98,6 +99,7 @@ int GetModulesDVBC(void); int GetModulesDVBC2(void); void Activate(bool onOffP) { activeM = onOffP; } + const char *SrcAddress(void) { return *srcAddressM; } const char *Address(void) { return *addressM; } const char *Model(void) { return *modelM; } const char *Filters(void) { return *filtersM; } @@ -128,6 +130,7 @@ bool HasCI(cSatipServer *serverP); void Cleanup(uint64_t intervalMsP = 0); cString GetAddress(cSatipServer *serverP); + cString GetSrcAddress(cSatipServer *serverP); cString GetString(cSatipServer *serverP); int GetPort(cSatipServer *serverP); cString List(void); diff -Nru vdr-plugin-satip-2.3.0/setup.c vdr-plugin-satip-2.4.0/setup.c --- vdr-plugin-satip-2.3.0/setup.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/setup.c 2018-04-15 18:30:59.000000000 +0000 @@ -105,7 +105,7 @@ : cOsdMenu(tr("SAT>IP Server"), 20), serverM(serverP), activeM(serverP && serverP->IsActive()), - addressM(serverP ? serverP->Address() : "---"), + addressM(serverP ? (isempty(serverP->SrcAddress()) ? serverP->Address() : *cString::sprintf("%s@%s", serverP->SrcAddress(), serverP->Address())) : "---"), modelM(serverP ? serverP->Model() : "---"), descriptionM(serverP ? serverP->Description() : "---"), ciExtensionM(serverP && serverP->HasCI() ? trVDR("yes") : trVDR("no")), @@ -167,7 +167,7 @@ { SetSelectable(true); // Must begin with a '#' character! - SetText(*cString::sprintf("%s %s (%s)\t%s", serverM->IsActive() ? "+" : "-", serverM->Address(), serverM->Model(), serverM->Description())); + SetText(*cString::sprintf("%s %s (%s)\t%s", serverM->IsActive() ? "+" : "-", isempty(serverM->SrcAddress()) ? serverM->Address() : *cString::sprintf("%s@%s", serverM->SrcAddress(), serverM->Address()), serverM->Model(), serverM->Description())); } void cSatipServerItem::SetMenuItem(cSkinDisplayMenu *displayMenuP, int indexP, bool currentP, bool selectableP) diff -Nru vdr-plugin-satip-2.3.0/socket.c vdr-plugin-satip-2.4.0/socket.c --- vdr-plugin-satip-2.3.0/socket.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/socket.c 2018-04-15 18:30:59.000000000 +0000 @@ -19,13 +19,35 @@ #include "log.h" #include "socket.h" +#if defined(__GLIBC__) + #if defined(__GLIBC_PREREQ) + #if !__GLIBC_PREREQ(2,12) + #define __SATIP_DISABLE_RECVMMSG__ + #endif + #endif +#endif + cSatipSocket::cSatipSocket() : socketPortM(0), socketDescM(-1), isMulticastM(false), useSsmM(false), streamAddrM(htonl(INADDR_ANY)), - sourceAddrM(htonl(INADDR_ANY)) + sourceAddrM(htonl(INADDR_ANY)), + rcvBufSizeM(0) +{ + debug1("%s", __PRETTY_FUNCTION__); + memset(&sockAddrM, 0, sizeof(sockAddrM)); +} + +cSatipSocket::cSatipSocket(size_t rcvBufSizeP) +: socketPortM(0), + socketDescM(-1), + isMulticastM(false), + useSsmM(false), + streamAddrM(htonl(INADDR_ANY)), + sourceAddrM(htonl(INADDR_ANY)), + rcvBufSizeM(rcvBufSizeP) { debug1("%s", __PRETTY_FUNCTION__); memset(&sockAddrM, 0, sizeof(sockAddrM)); @@ -70,6 +92,11 @@ ERROR_IF_FUNC(setsockopt(socketDescM, SOL_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0, "setsockopt(IP_PKTINFO)", Close(), return false); #endif // __FreeBSD__ + // Tweak receive buffer size if requested + if (rcvBufSizeM > 0) { + ERROR_IF_FUNC(setsockopt(socketDescM, SOL_SOCKET, SO_RCVBUF, &rcvBufSizeM, sizeof(rcvBufSizeM)) < 0, + "setsockopt(SO_RCVBUF)", Close(), return false); + } // Bind socket memset(&sockAddrM, 0, sizeof(sockAddrM)); sockAddrM.sin_family = AF_INET; @@ -101,7 +128,7 @@ void cSatipSocket::Close(void) { - debug1("%s sockerPort=%d", __PRETTY_FUNCTION__, socketPortM); + debug1("%s socketPort=%d", __PRETTY_FUNCTION__, socketPortM); // Check if socket exists if (socketDescM >= 0) { Leave(); @@ -289,7 +316,7 @@ error("%s Invalid parameter(s)", __PRETTY_FUNCTION__); return -1; } -#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,12) +#ifndef __SATIP_DISABLE_RECVMMSG__ // Initialize iov and msgh structures struct mmsghdr mmsgh[elementCountP]; struct iovec iov[elementCountP]; diff -Nru vdr-plugin-satip-2.3.0/socket.h vdr-plugin-satip-2.4.0/socket.h --- vdr-plugin-satip-2.3.0/socket.h 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/socket.h 2018-04-15 18:30:59.000000000 +0000 @@ -19,12 +19,15 @@ bool useSsmM; in_addr_t streamAddrM; in_addr_t sourceAddrM; + size_t rcvBufSizeM; + bool CheckAddress(const char *addrP, in_addr_t *inAddrP); bool Join(void); bool Leave(void); public: cSatipSocket(); + explicit cSatipSocket(size_t rcvBufSizeP); virtual ~cSatipSocket(); bool Open(const int portP = 0, const bool reuseP = false); bool OpenMulticast(const int portP, const char *streamAddrP, const char *sourceAddrP); diff -Nru vdr-plugin-satip-2.3.0/tuner.c vdr-plugin-satip-2.4.0/tuner.c --- vdr-plugin-satip-2.3.0/tuner.c 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/tuner.c 2018-04-15 18:30:59.000000000 +0000 @@ -40,6 +40,7 @@ externalStateM(), timeoutM(eMinKeepAliveIntervalMs), hasLockM(false), + signalStrengthDBmM(0.0), signalStrengthM(-1), signalQualityM(-1), frontendIdM(-1), @@ -126,6 +127,7 @@ break; case tsTuned: debug4("%s: tsTuned [device %d]", __PRETTY_FUNCTION__, deviceIdM); + deviceM->SetChannelTuned(); reConnectM.Set(eConnectTimeoutMs); idleCheck.Set(eIdleCheckTimeoutMs); lastIdleStatus = false; @@ -134,6 +136,7 @@ // Quirk for devices without valid reception data if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkForceLock)) { hasLockM = true; + signalStrengthDBmM = eDefaultSignalStrengthDBm; signalStrengthM = eDefaultSignalStrength; signalQualityM = eDefaultSignalQuality; } @@ -222,12 +225,14 @@ return true; } } - else if (rtspM.Options(*connectionUri)) { + else if (rtspM.SetInterface(nextServerM.IsValid() ? *nextServerM.GetSrcAddress() : NULL) && rtspM.Options(*connectionUri)) { cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM); bool useTcp = SatipConfig.IsTransportModeRtpOverTcp() && nextServerM.IsValid() && nextServerM.IsQuirk(cSatipServer::eSatipQuirkRtpOverTcp); // Flush any old content //rtpM.Flush(); //rtcpM.Flush(); + if (useTcp) + debug1("%s Requesting TCP [device %d]", __PRETTY_FUNCTION__, deviceIdM); if (rtspM.Setup(*uri, rtpM.Port(), rtcpM.Port(), useTcp)) { keepAliveM.Set(timeoutM); if (nextServerM.IsValid()) { @@ -261,6 +266,7 @@ // Reset signal parameters hasLockM = false; + signalStrengthDBmM = 0.0; signalStrengthM = -1; signalQualityM = -1; frontendIdM = -1; @@ -330,8 +336,9 @@ // No signal corresponds to 0 c = strstr(c, ","); value = min(atoi(++c), 255); + signalStrengthDBmM = (value >= 0) ? 40.0 * (value - 32) / 192.0 - 65.0 : 0.0; // Scale value to 0-100 - signalStrengthM = (value >= 0) ? (value * 100 / 255) : -1; + signalStrengthM = (value >= 0) ? value * 100 / 255 : -1; // lock: // lock Set to one of the following values: @@ -385,8 +392,8 @@ // Adapt RTP to any transport media change if (multicast != rtpM.IsMulticast() || rtpPortP != rtpM.Port()) { cSatipPoller::GetInstance()->Unregister(rtpM); - rtpM.Close(); if (rtpPortP >= 0) { + rtpM.Close(); if (multicast) rtpM.OpenMulticast(rtpPortP, streamAddrP, sourceAddrP); else @@ -397,12 +404,12 @@ // Adapt RTCP to any transport media change if (multicast != rtcpM.IsMulticast() || rtcpPortP != rtcpM.Port()) { cSatipPoller::GetInstance()->Unregister(rtcpM); - rtcpM.Close(); if (rtcpPortP >= 0) { + rtcpM.Close(); if (multicast) - rtcpM.OpenMulticast(rtpPortP, streamAddrP, sourceAddrP); + rtcpM.OpenMulticast(rtcpPortP, streamAddrP, sourceAddrP); else - rtcpM.Open(rtpPortP); + rtcpM.Open(rtcpPortP); cSatipPoller::GetInstance()->Register(rtcpM); } } @@ -667,6 +674,12 @@ return signalStrengthM; } +double cSatipTuner::SignalStrengthDBm(void) +{ + debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM); + return signalStrengthDBmM; +} + int cSatipTuner::SignalQuality(void) { debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM); diff -Nru vdr-plugin-satip-2.3.0/tuner.h vdr-plugin-satip-2.4.0/tuner.h --- vdr-plugin-satip-2.3.0/tuner.h 2016-12-18 10:18:00.000000000 +0000 +++ vdr-plugin-satip-2.4.0/tuner.h 2018-04-15 18:30:59.000000000 +0000 @@ -69,6 +69,7 @@ void Set(cSatipServer *serverP, const int transponderP) { serverM = serverP; transponderM = transponderP; } void Reset(void) { serverM = NULL; transponderM = 0; } cString GetAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerAddress(serverM) : ""; } + cString GetSrcAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetSourceAddress(serverM) : ""; } int GetPort(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerPort(serverM) : SATIP_DEFAULT_RTSP_PORT; } cString GetInfo(void) { return cString::sprintf("server=%s deviceid=%d transponder=%d", serverM ? "assigned" : "null", deviceIdM, transponderM); } }; @@ -77,16 +78,17 @@ { private: enum { - eDummyPid = 100, - eDefaultSignalStrength = 15, - eDefaultSignalQuality = 224, - eSleepTimeoutMs = 250, // in milliseconds - eStatusUpdateTimeoutMs = 1000, // in milliseconds - ePidUpdateIntervalMs = 250, // in milliseconds - eConnectTimeoutMs = 5000, // in milliseconds - eIdleCheckTimeoutMs = 15000, // in milliseconds - eTuningTimeoutMs = 20000, // in milliseconds - eMinKeepAliveIntervalMs = 30000 // in milliseconds + eDummyPid = 100, + eDefaultSignalStrengthDBm = -25, + eDefaultSignalStrength = 224, + eDefaultSignalQuality = 15, + eSleepTimeoutMs = 250, // in milliseconds + eStatusUpdateTimeoutMs = 1000, // in milliseconds + ePidUpdateIntervalMs = 250, // in milliseconds + eConnectTimeoutMs = 5000, // in milliseconds + eIdleCheckTimeoutMs = 15000, // in milliseconds + eTuningTimeoutMs = 20000, // in milliseconds + eMinKeepAliveIntervalMs = 30000 // in milliseconds }; enum eTunerState { tsIdle, tsRelease, tsSet, tsTuned, tsLocked }; enum eStateMode { smInternal, smExternal }; @@ -114,6 +116,7 @@ cVector externalStateM; int timeoutM; bool hasLockM; + double signalStrengthDBmM; int signalStrengthM; int signalQualityM; int frontendIdM; @@ -148,6 +151,7 @@ bool Close(void); int FrontendId(void); int SignalStrength(void); + double SignalStrengthDBm(void); int SignalQuality(void); bool HasLock(void); cString GetSignalStatus(void);