Hello community,

here is the log from the commit of package vdr-plugin-satip for 
openSUSE:Factory checked in at 2015-05-18 22:32:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/vdr-plugin-satip (Old)
 and      /work/SRC/openSUSE:Factory/.vdr-plugin-satip.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "vdr-plugin-satip"

Changes:
--------
--- /work/SRC/openSUSE:Factory/vdr-plugin-satip/vdr-plugin-satip.changes        
2015-03-11 09:57:48.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.vdr-plugin-satip.new/vdr-plugin-satip.changes   
2015-05-18 22:32:38.000000000 +0200
@@ -1,0 +2,18 @@
+Fri May 15 17:46:55 UTC 2015 - [email protected]
+
+- update to version 2.2.2 (2015-04-26)
+  * Added a more flexible OPER command in the SVDRP interface
+  * Added new ATTA and DETA SVDRP commands
+  * Set the default device count to two
+
+-------------------------------------------------------------------
+Tue Apr  7 14:23:17 UTC 2015 - [email protected]
+
+- update to version 2.2.1 (2015-04-04)
+  * Improved RTSP error checking
+  * Got rid of SATIP_DEBUG
+  * Robustify the server discovery
+  * Fixed a memory leak in TinyXML implementation
+  * Updated against SAT>IP protocol specification version 1.2.2
+
+-------------------------------------------------------------------

Old:
----
  vdr-satip-2.2.0.tgz

New:
----
  vdr-satip-2.2.2.tgz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ vdr-plugin-satip.spec ++++++
--- /var/tmp/diff_new_pack.qMa2nQ/_old  2015-05-18 22:32:38.000000000 +0200
+++ /var/tmp/diff_new_pack.qMa2nQ/_new  2015-05-18 22:32:38.000000000 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           vdr-plugin-satip
-Version:        2.2.0
+Version:        2.2.2
 Release:        0
 Summary:        SAT>IP Input Plugin for the Video Disc Recorder VDR
 License:        GPL-2.0
@@ -29,7 +29,7 @@
 BuildRequires:  pkg-config
 BuildRequires:  tinyxml-devel
 BuildRequires:  vdr-devel >= 2.0.0
-BuildRequires:  pkgconfig(libcurl)
+BuildRequires:  pkgconfig(libcurl) >= 7.36.0
 Requires(pre):  %{vdr_prereq}
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
@@ -48,7 +48,7 @@
 %build
 # use msgmerge wrapper
 export PATH=%{_datadir}/vdr:$PATH
-make %{?_smp_mflags} SATIP_USE_TINYXML=1 SATIP_DEBUG=1
+make %{?_smp_mflags} SATIP_USE_TINYXML=1
 
 %install
 make install DESTDIR=%{buildroot}

++++++ vdr-satip-2.2.0.tgz -> vdr-satip-2.2.2.tgz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/HISTORY new/satip-2.2.2/HISTORY
--- old/satip-2.2.0/HISTORY     2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/HISTORY     2015-04-26 03:20:00.000000000 +0200
@@ -120,3 +120,20 @@
 - Fixed memory deallocation errors.
 - Cleaned up all scan-build warnings.
 - Refactored the frontend handling.
+
+2015-04-04: Version 2.2.1
+
+- Improved RTSP error checking.
+- Got rid of SATIP_DEBUG.
+- Robustify the server discovery.
+- Fixed a memory leak in TinyXML implementation
+  (Thanks to Oliver Endriss).
+- Updated against SAT>IP protocol specification
+  version 1.2.2.
+
+2015-04-26: Version 2.2.2
+
+- Added a more flexible OPER command in the SVDRP
+  interface.
+- Added new ATTA and DETA SVDRP commands.
+- Set the default device count to two.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/Makefile new/satip-2.2.2/Makefile
--- old/satip-2.2.0/Makefile    2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/Makefile    2015-04-26 03:20:00.000000000 +0200
@@ -2,18 +2,10 @@
 # Makefile for SAT>IP plugin
 #
 
-# Debugging on/off
-
-#SATIP_DEBUG = 1
-
 # Use TinyXML instead of PugiXML
 
 #SATIP_USE_TINYXML = 1
 
-# Strip debug symbols?  Set eg. to /bin/true if not
-
-STRIP = strip
-
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
 # By default the main source file also carries this name.
@@ -40,6 +32,7 @@
 
 export CFLAGS   = $(call PKGCFG,cflags)
 export CXXFLAGS = $(call PKGCFG,cxxflags)
+STRIP           ?= /bin/true
 
 ### The version number of VDR's plugin API:
 
@@ -75,12 +68,6 @@
 LIBS += -lpugixml
 endif
 
-ifdef SATIP_DEBUG
-ifeq ($(SATIP_DEBUG),1)
-DEFINES += -DDEBUG
-endif
-endif
-
 ifneq ($(strip $(GITTAG)),)
 DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"'
 endif
@@ -142,9 +129,7 @@
 
 $(SOFILE): $(OBJS)
        $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
-ifndef SATIP_DEBUG
        @$(STRIP) $@
-endif
 
 install-lib: $(SOFILE)
        install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/README new/satip-2.2.2/README
--- old/satip-2.2.0/README      2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/README      2015-04-26 03:20:00.000000000 +0200
@@ -42,7 +42,7 @@
 Configuration:
 
 The plugin accepts a "--devices" (-d) command-line parameter defaulting
-to one. This parameter defines how many simultaneous transponders can
+to two. This parameter defines how many simultaneous transponders can
 be received, if there are available SAT>IP tuners.
 
 The plugin accepts also a "--server" (-s) command-line parameter, that
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/common.h new/satip-2.2.2/common.h
--- old/satip-2.2.0/common.h    2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/common.h    2015-04-26 03:20:00.000000000 +0200
@@ -35,7 +35,7 @@
 
 #define SATIP_CURL_EASY_GETINFO(X, Y, Z) \
   if ((res = curl_easy_getinfo((X), (Y), (Z))) != CURLE_OK) { \
-     error("curl_easy_getinfo(%s) [%s,%d] failed: %s (%d)", #Y,  __FILE__, 
__LINE__, curl_easy_strerror(res), res); \
+     esyslog("curl_easy_getinfo(%s) [%s,%d] failed: %s (%d)", #Y,  __FILE__, 
__LINE__, curl_easy_strerror(res), res); \
      }
 
 #define SATIP_CURL_EASY_SETOPT(X, Y, Z) \
@@ -48,15 +48,15 @@
      esyslog("curl_easy_perform() [%s,%d] failed: %s (%d)",  __FILE__, 
__LINE__, curl_easy_strerror(res), res); \
      }
 
-#define ERROR_IF_FUNC(exp, errstr, func, ret)              \
-  do {                                                     \
-     if (exp) {                                            \
-        char tmp[64];                                      \
+#define ERROR_IF_FUNC(exp, errstr, func, ret)                \
+  do {                                                       \
+     if (exp) {                                              \
+        char tmp[64];                                        \
         esyslog("[%s,%d]: "errstr": %s", __FILE__, __LINE__, \
-              strerror_r(errno, tmp, sizeof(tmp)));        \
-        func;                                              \
-        ret;                                               \
-        }                                                  \
+                strerror_r(errno, tmp, sizeof(tmp)));        \
+        func;                                                \
+        ret;                                                 \
+        }                                                    \
   } while (0)
 
 
@@ -84,6 +84,52 @@
 
 #define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
 
+class cSatipMemoryBuffer {
+private:
+  enum {
+    eMaxDataSize = MEGABYTE(2)
+  };
+  char *dataM;
+  size_t sizeM;
+  void *AllocBuffer(void *ptrP, size_t sizeP)
+  {
+    // There might be a realloc() out there that doesn't like reallocing NULL 
pointers, so we take care of it here
+    if (ptrP)
+       return realloc(ptrP, sizeP);
+    else
+       return malloc(sizeP);
+  }
+  // to prevent copy constructor and assignment
+  cSatipMemoryBuffer(const cSatipMemoryBuffer&);
+  cSatipMemoryBuffer& operator=(const cSatipMemoryBuffer&);
+public:
+  cSatipMemoryBuffer() : dataM(NULL), sizeM(0) {}
+  ~cSatipMemoryBuffer() { Reset(); }
+  size_t Add(char *dataP, size_t sizeP)
+  {
+     if (sizeP > 0) {
+        size_t len = sizeM + sizeP + 1;
+        if (len < eMaxDataSize) {
+           dataM = (char *)AllocBuffer(dataM, len);
+           if (dataM) {
+              memcpy(&(dataM[sizeM]), dataP, sizeP);
+              sizeM += sizeP;
+              dataM[sizeM] = 0;
+              return sizeP;
+              }
+           else
+              esyslog("[%s,%d]: Failed to allocate memory", __FILE__, 
__LINE__);
+          }
+       else
+          esyslog("[%s,%d]: Buffer overflow", __FILE__, __LINE__);
+       }
+     return 0;
+  };
+  char *Data(void) { return dataM; }
+  size_t Size(void) { return sizeM; }
+  void Reset(void) { FREE_POINTER(dataM); sizeM = 0; };
+};
+
 uint16_t ts_pid(const uint8_t *bufP);
 uint8_t payload(const uint8_t *bufP);
 const char *id_pid(const u_short pidP);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/config.c new/satip-2.2.2/config.c
--- old/satip-2.2.0/config.c    2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/config.c    2015-04-26 03:20:00.000000000 +0200
@@ -17,6 +17,7 @@
   ciExtensionM(0),
   eitScanM(1),
   useBytesM(1),
+  detachedModeM(false),
   disableServerQuirksM(false),
   useSingleModelServersM(false)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/config.h new/satip-2.2.2/config.h
--- old/satip-2.2.0/config.h    2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/config.h    2015-04-26 03:20:00.000000000 +0200
@@ -19,6 +19,7 @@
   unsigned int ciExtensionM;
   unsigned int eitScanM;
   unsigned int useBytesM;
+  bool detachedModeM;
   bool disableServerQuirksM;
   bool useSingleModelServersM;
   int cicamsM[MAX_CICAM_COUNT];
@@ -34,24 +35,24 @@
     eOperatingModeCount
   };
   enum eTraceMode {
-   eTraceModeNormal  = 0x0000,
-   eTraceModeDebug1  = 0x0001,
-   eTraceModeDebug2  = 0x0002,
-   eTraceModeDebug3  = 0x0004,
-   eTraceModeDebug4  = 0x0008,
-   eTraceModeDebug5  = 0x0010,
-   eTraceModeDebug6  = 0x0020,
-   eTraceModeDebug7  = 0x0040,
-   eTraceModeDebug8  = 0x0080,
-   eTraceModeDebug9  = 0x0100,
-   eTraceModeDebug10 = 0x0200,
-   eTraceModeDebug11 = 0x0400,
-   eTraceModeDebug12 = 0x0800,
-   eTraceModeDebug13 = 0x1000,
-   eTraceModeDebug14 = 0x2000,
-   eTraceModeDebug15 = 0x4000,
-   eTraceModeDebug16 = 0x8000,
-   eTraceModeMask    = 0xFFFF
+    eTraceModeNormal  = 0x0000,
+    eTraceModeDebug1  = 0x0001,
+    eTraceModeDebug2  = 0x0002,
+    eTraceModeDebug3  = 0x0004,
+    eTraceModeDebug4  = 0x0008,
+    eTraceModeDebug5  = 0x0010,
+    eTraceModeDebug6  = 0x0020,
+    eTraceModeDebug7  = 0x0040,
+    eTraceModeDebug8  = 0x0080,
+    eTraceModeDebug9  = 0x0100,
+    eTraceModeDebug10 = 0x0200,
+    eTraceModeDebug11 = 0x0400,
+    eTraceModeDebug12 = 0x0800,
+    eTraceModeDebug13 = 0x1000,
+    eTraceModeDebug14 = 0x2000,
+    eTraceModeDebug15 = 0x4000,
+    eTraceModeDebug16 = 0x8000,
+    eTraceModeMask    = 0xFFFF
   };
   cSatipConfig();
   unsigned int GetOperatingMode(void) const { return operatingModeM; }
@@ -66,6 +67,7 @@
   int GetCICAM(unsigned int indexP) const;
   unsigned int GetEITScan(void) const { return eitScanM; }
   unsigned int GetUseBytes(void) const { return useBytesM; }
+  bool GetDetachedMode(void) const { return detachedModeM; }
   bool GetDisableServerQuirks(void) const { return disableServerQuirksM; }
   bool GetUseSingleModelServers(void) const { return useSingleModelServersM; }
   unsigned int GetDisabledSourcesCount(void) const;
@@ -79,6 +81,7 @@
   void SetCICAM(unsigned int indexP, int cicamP);
   void SetEITScan(unsigned int onOffP) { eitScanM = onOffP; }
   void SetUseBytes(unsigned int onOffP) { useBytesM = onOffP; }
+  void SetDetachedMode(bool onOffP) { detachedModeM = onOffP; }
   void SetDisableServerQuirks(bool onOffP) { disableServerQuirksM = onOffP; }
   void SetUseSingleModelServers(bool onOffP) { useSingleModelServersM = 
onOffP; }
   void SetDisabledSources(unsigned int indexP, int sourceP);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/device.c new/satip-2.2.2/device.c
--- old/satip-2.2.0/device.c    2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/device.c    2015-04-26 03:20:00.000000000 +0200
@@ -219,6 +219,8 @@
 {
   cSource *s = Sources.Get(sourceP);
   debug9("%s (%c) desc='%s' [device %u]", __PRETTY_FUNCTION__, 
cSource::ToChar(sourceP), s ? s->Description() : "", deviceIndexM);
+  if (SatipConfig.GetDetachedMode())
+     return false;
   // source descriptions starting with '0' are disabled
   if (s && s->Description() && (*(s->Description()) == '0'))
      return false;
@@ -501,6 +503,8 @@
 bool cSatipDevice::GetTSPacket(uchar *&dataP)
 {
   debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
+  if (SatipConfig.GetDetachedMode())
+     return false;
   if (tsBufferM) {
      if (cCamSlot *cs = CamSlot()) {
         if (cs->WantsTsData()) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/discover.c new/satip-2.2.2/discover.c
--- old/satip-2.2.0/discover.c  2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/discover.c  2015-04-26 03:20:00.000000000 +0200
@@ -47,43 +47,14 @@
      instanceS->Deactivate();
 }
 
-size_t cSatipDiscover::WriteCallback(char *ptrP, size_t sizeP, size_t nmembP, 
void *dataP)
+size_t cSatipDiscover::DataCallback(char *ptrP, size_t sizeP, size_t nmembP, 
void *dataP)
 {
   cSatipDiscover *obj = reinterpret_cast<cSatipDiscover *>(dataP);
   size_t len = sizeP * nmembP;
   debug16("%s len=%zu", __PRETTY_FUNCTION__, len);
 
-  if (obj) {
-     CURLcode res = CURLE_OK;
-     const char *desc = NULL, *model = NULL, *addr = NULL;
-#ifdef USE_TINYXML
-     TiXmlDocument doc;
-     char *xml = MALLOC(char, len + 1);
-     memcpy(xml, ptrP, len);
-     *(xml + len + 1) = 0;
-     doc.Parse((const char *)xml);
-     TiXmlHandle docHandle(&doc);
-     TiXmlElement *descElement = 
docHandle.FirstChild("root").FirstChild("device").FirstChild("friendlyName").ToElement();
-     if (descElement)
-        desc = descElement->GetText() ? descElement->GetText() : 
"MyBrokenHardware";
-     TiXmlElement *modelElement = 
docHandle.FirstChild("root").FirstChild("device").FirstChild("satip:X_SATIPCAP").ToElement();
-     if (modelElement)
-        model = modelElement->GetText() ? modelElement->GetText() : "DVBS2-1";
-#else
-     pugi::xml_document doc;
-     pugi::xml_parse_result result = doc.load_buffer(ptrP, len);
-     if (result) {
-        pugi::xml_node descNode = 
doc.first_element_by_path("root/device/friendlyName");
-        if (descNode)
-           desc = descNode.text().as_string("MyBrokenHardware");
-        pugi::xml_node modelNode = 
doc.first_element_by_path("root/device/satip:X_SATIPCAP");
-        if (modelNode)
-           model = modelNode.text().as_string("DVBS2-1");
-        }
-#endif
-     SATIP_CURL_EASY_GETINFO(obj->handleM, CURLINFO_PRIMARY_IP, &addr);
-     obj->AddServer(addr, model, desc);
-     }
+  if (obj && (len > 0))
+     obj->dataBufferM.Add(ptrP, len);
 
   return len;
 }
@@ -120,6 +91,7 @@
 cSatipDiscover::cSatipDiscover()
 : cThread("SATIP discover"),
   mutexM(),
+  dataBufferM(),
   msearchM(*this),
   probeUrlListM(),
   handleM(curl_easy_init()),
@@ -170,7 +142,7 @@
            probeIntervalM.Set(eProbeIntervalMs);
            msearchM.Probe();
            mutexM.Lock();
-           serversM.Cleanup(eProbeIntervalMs * 2);
+           serversM.Cleanup(eCleanupTimeoutMs);
            mutexM.Unlock();
            }
         mutexM.Lock();
@@ -195,6 +167,7 @@
 {
   debug1("%s (%s)", __PRETTY_FUNCTION__, urlP);
   if (handleM && !isempty(urlP)) {
+     const char *addr = NULL;
      long rc = 0;
      CURLcode res = CURLE_OK;
 
@@ -204,7 +177,7 @@
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_DEBUGDATA, this);
 
      // Set callback
-     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, 
cSatipDiscover::WriteCallback);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, 
cSatipDiscover::DataCallback);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
 
      // No progress meter and no signaling
@@ -224,11 +197,44 @@
      // Fetch the data
      SATIP_CURL_EASY_PERFORM(handleM);
      SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc);
-     if (rc != 200)
+     SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_PRIMARY_IP, &addr);
+     if (rc == 200) {
+        ParseDeviceInfo(addr);
+        dataBufferM.Reset();
+        }
+     else
         error("Discovery detected invalid status code: %ld", rc);
      }
 }
 
+void cSatipDiscover::ParseDeviceInfo(const char *addrP)
+{
+  debug1("%s (%s)", __PRETTY_FUNCTION__, addrP);
+  const char *desc = NULL, *model = NULL;
+#ifdef USE_TINYXML
+  TiXmlDocument doc;
+  doc.Parse(dataBufferM.Data());
+  TiXmlHandle docHandle(&doc);
+  TiXmlElement *descElement = 
docHandle.FirstChild("root").FirstChild("device").FirstChild("friendlyName").ToElement();
+  if (descElement)
+     desc = descElement->GetText() ? descElement->GetText() : 
"MyBrokenHardware";
+  TiXmlElement *modelElement = 
docHandle.FirstChild("root").FirstChild("device").FirstChild("satip:X_SATIPCAP").ToElement();
+  if (modelElement)
+     model = modelElement->GetText() ? modelElement->GetText() : "DVBS2-1";
+#else
+  pugi::xml_document doc;
+  if (doc.load_buffer(dataBufferM.Data(), dataBufferM.Size())) {
+     pugi::xml_node descNode = 
doc.first_element_by_path("root/device/friendlyName");
+     if (descNode)
+        desc = descNode.text().as_string("MyBrokenHardware");
+     pugi::xml_node modelNode = 
doc.first_element_by_path("root/device/satip:X_SATIPCAP");
+     if (modelNode)
+        model = modelNode.text().as_string("DVBS2-1");
+     }
+#endif
+  AddServer(addrP, model, desc);
+}
+
 void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const 
char * descP)
 {
   debug1("%s (%s, %s, %s)", __PRETTY_FUNCTION__, addrP, modelP, descP);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/discover.h new/satip-2.2.2/discover.h
--- old/satip-2.2.0/discover.h  2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/discover.h  2015-04-26 03:20:00.000000000 +0200
@@ -13,6 +13,7 @@
 #include <vdr/thread.h>
 #include <vdr/tools.h>
 
+#include "common.h"
 #include "discoverif.h"
 #include "msearch.h"
 #include "server.h"
@@ -39,15 +40,17 @@
 class cSatipDiscover : public cThread, public cSatipDiscoverIf {
 private:
   enum {
-    eSleepTimeoutMs   = 500,  // in milliseconds
-    eConnectTimeoutMs = 1500, // in milliseconds
-    eProbeTimeoutMs   = 2000, // in milliseconds
-    eProbeIntervalMs  = 60000 // in milliseconds
+    eSleepTimeoutMs   = 500,   // in milliseconds
+    eConnectTimeoutMs = 1500,  // in milliseconds
+    eProbeTimeoutMs   = 2000,  // in milliseconds
+    eProbeIntervalMs  = 60000, // in milliseconds
+    eCleanupTimeoutMs = 124000 // in milliseoonds
   };
   static cSatipDiscover *instanceS;
-  static size_t WriteCallback(char *ptrP, size_t sizeP, size_t nmembP, void 
*dataP);
+  static size_t DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void 
*dataP);
   static int    DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, 
size_t sizeP, void *userPtrP);
   cMutex mutexM;
+  cSatipMemoryBuffer dataBufferM;
   cSatipMsearch msearchM;
   cStringList probeUrlListM;
   CURL *handleM;
@@ -56,6 +59,7 @@
   cSatipServers serversM;
   void Activate(void);
   void Deactivate(void);
+  void ParseDeviceInfo(const char *addrP);
   void AddServer(const char *addrP, const char *modelP, const char *descP);
   void Fetch(const char *urlP);
   // constructor
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/log.h new/satip-2.2.2/log.h
--- old/satip-2.2.0/log.h       2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/log.h       2015-04-26 03:20:00.000000000 +0200
@@ -34,9 +34,9 @@
 #define debug10(x...) void( 
SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug10) ? dsyslog("SATIP10: " 
x) : void() )
 // 0x0400: CI
 #define debug11(x...) void( 
SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug11) ? dsyslog("SATIP11: " 
x) : void() )
-// 0x0800: Discovery
+// 0x0800: Pids
 #define debug12(x...) void( 
SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug12) ? dsyslog("SATIP12: " 
x) : void() )
-// 0x1000: Pids
+// 0x1000: Discovery
 #define debug13(x...) void( 
SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug13) ? dsyslog("SATIP13: " 
x) : void() )
 // 0x2000: TBD
 #define debug14(x...) void( 
SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug14) ? dsyslog("SATIP14: " 
x) : void() )
@@ -46,4 +46,3 @@
 #define debug16(x...) void( 
SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug16) ? dsyslog("SATIP16: " 
x) : void() )
 
 #endif // __SATIP_LOG_H
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/msearch.c new/satip-2.2.2/msearch.c
--- old/satip-2.2.0/msearch.c   2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/msearch.c   2015-04-26 03:20:00.000000000 +0200
@@ -45,6 +45,9 @@
      cSatipPoller::GetInstance()->Register(*this);
      registeredM = true;
      }
+  // Send two queries with one second interval
+  Write(bcastAddressS, reinterpret_cast<const unsigned char *>(bcastMessageS), 
strlen(bcastMessageS));
+  cCondWait::SleepMs(1000);
   Write(bcastAddressS, reinterpret_cast<const unsigned char *>(bcastMessageS), 
strlen(bcastMessageS));
 }
 
@@ -60,12 +63,12 @@
      int length;
      while ((length = Read(bufferM, bufferLenM)) > 0) {
            bufferM[min(length, int(bufferLenM - 1))] = 0;
-           debug12("%s len=%d buf=%s", __PRETTY_FUNCTION__, length, bufferM);
+           debug13("%s len=%d buf=%s", __PRETTY_FUNCTION__, length, bufferM);
            bool status = false, valid = false;
            char *s, *p = reinterpret_cast<char *>(bufferM), *location = NULL;
            char *r = strtok_r(p, "\r\n", &s);
            while (r) {
-                 debug12("%s r=%s", __PRETTY_FUNCTION__, r);
+                 debug13("%s r=%s", __PRETTY_FUNCTION__, r);
                  // Check the status code
                  // HTTP/1.1 200 OK
                  if (!status && startswith(r, "HTTP/1.1 200 OK"))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/param.c new/satip-2.2.2/param.c
--- old/satip-2.2.0/param.c     2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/param.c     2015-04-26 03:20:00.000000000 +0200
@@ -147,9 +147,6 @@
      cDvbTransponderParameters dtp(channelP->Parameters());
      int DataSlice = 0;
      int C2TuningFrequencyType = 0;
-     int Pilot = dtp.Pilot();
-     int T2SystemId = dtp.T2SystemId();
-     int SisoMiso = dtp.SisoMiso();
      float freq = channelP->Frequency();
      char type = cSource::ToChar(channelP->Source());
      cSource *source = Sources.Get(channelP->Source());
@@ -161,26 +158,31 @@
            freq /= 1000L;
 #define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || 
strchr(s, '*')))
 #define STBUFLEFT (sizeof(buffer) - (q - buffer))
+     ST(" S 1") { // to comply with SAT>IP protocol specification 1.2.2
+       dtp.SetPilot(PILOT_OFF);
+       dtp.SetModulation(QPSK);
+       dtp.SetRollOff(ROLLOFF_35);
+       }
                 q += snprintf(q,       STBUFLEFT, "freq=%s",          
*dtoa(freq, "%lg"));
      ST(" S *") q += snprintf(q,       STBUFLEFT, "&src=%d",          ((src > 
0) && (src <= 255)) ? src : 1);
      ST(" S *") q += snprintf(q,       STBUFLEFT, "&sr=%d",           
channelP->Srate());
      ST("C  1") 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 += snprintf(q,       STBUFLEFT, "&t2id=%d",         
dtp.T2SystemId());
      ST("C  2") q += snprintf(q,       STBUFLEFT, "&c2tft=%d",        
C2TuningFrequencyType);
      ST("C  2") q += snprintf(q,       STBUFLEFT, "&ds=%d",           
DataSlice);
      ST("C  1") q += PrintUrlString(q, STBUFLEFT, dtp.Inversion(),    
SatipInversionValues);
-     ST("  T2") q += PrintUrlString(q, STBUFLEFT, SisoMiso,           
SatipSisoMisoValues);
+     ST("  T2") q += PrintUrlString(q, STBUFLEFT, dtp.SisoMiso(),     
SatipSisoMisoValues);
      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Bandwidth(),    
SatipBandwidthValues);
      ST("C  2") 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(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Pilot(),        
SatipPilotValues);
+     ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(),   
SatipModulationValues);
      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(),   
SatipModulationValues);
      ST("C  1") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(),   
SatipModulationValues);
-     ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.RollOff(),      
SatipRollOffValues);
+     ST(" S *") 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);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/po/ca_ES.po new/satip-2.2.2/po/ca_ES.po
--- old/satip-2.2.0/po/ca_ES.po 2015-02-20 20:17:42.000000000 +0100
+++ new/satip-2.2.2/po/ca_ES.po 2015-04-26 11:53:39.000000000 +0200
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: vdr-satip 2.2.0\n"
+"Project-Id-Version: vdr-satip 2.2.2\n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-02-19 02:19+0200\n"
-"PO-Revision-Date: 2015-02-19 02:19+0200\n"
+"POT-Creation-Date: 2015-04-26 04:26+0300\n"
+"PO-Revision-Date: 2015-04-26 04:26+0300\n"
 "Last-Translator: Gabriel Bonich <[email protected]>\n"
 "Language-Team: Catalan <[email protected]>\n"
 "Language: ca\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/po/de_DE.po new/satip-2.2.2/po/de_DE.po
--- old/satip-2.2.0/po/de_DE.po 2015-02-20 20:17:42.000000000 +0100
+++ new/satip-2.2.2/po/de_DE.po 2015-04-26 11:53:39.000000000 +0200
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: vdr-satip 2.2.0\n"
+"Project-Id-Version: vdr-satip 2.2.2\n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-02-19 02:19+0200\n"
-"PO-Revision-Date: 2015-02-19 02:19+0200\n"
+"POT-Creation-Date: 2015-04-26 04:26+0300\n"
+"PO-Revision-Date: 2015-04-26 04:26+0300\n"
 "Last-Translator: Frank Neumann <[email protected]>\n"
 "Language-Team: German <[email protected]>\n"
 "Language: de\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/po/es_ES.po new/satip-2.2.2/po/es_ES.po
--- old/satip-2.2.0/po/es_ES.po 2015-02-20 20:17:42.000000000 +0100
+++ new/satip-2.2.2/po/es_ES.po 2015-04-26 11:53:39.000000000 +0200
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: vdr-satip 2.2.0\n"
+"Project-Id-Version: vdr-satip 2.2.2\n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-02-19 02:19+0200\n"
-"PO-Revision-Date: 2015-02-19 02:19+0200\n"
+"POT-Creation-Date: 2015-04-26 04:26+0300\n"
+"PO-Revision-Date: 2015-04-26 04:26+0300\n"
 "Last-Translator: Gabriel Bonich <[email protected]>\n"
 "Language-Team: Spanish <[email protected]>\n"
 "Language: es\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/po/fi_FI.po new/satip-2.2.2/po/fi_FI.po
--- old/satip-2.2.0/po/fi_FI.po 2015-02-20 20:17:42.000000000 +0100
+++ new/satip-2.2.2/po/fi_FI.po 2015-04-26 11:53:39.000000000 +0200
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: vdr-satip 2.2.0\n"
+"Project-Id-Version: vdr-satip 2.2.2\n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-02-19 02:19+0200\n"
-"PO-Revision-Date: 2015-02-19 02:19+0200\n"
+"POT-Creation-Date: 2015-04-26 04:26+0300\n"
+"PO-Revision-Date: 2015-04-26 04:26+0300\n"
 "Last-Translator: Rolf Ahrenberg\n"
 "Language-Team: Finnish <[email protected]>\n"
 "Language: fi\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/rtsp.c new/satip-2.2.2/rtsp.c
--- old/satip-2.2.0/rtsp.c      2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/rtsp.c      2015-04-26 03:20:00.000000000 +0200
@@ -15,9 +15,14 @@
 
 cSatipRtsp::cSatipRtsp(cSatipTunerIf &tunerP)
 : tunerM(tunerP),
+  headerBufferM(),
+  dataBufferM(),
   modeM(cmUnicast),
   handleM(NULL),
-  headerListM(NULL)
+  headerListM(NULL),
+  errorNoMoreM(""),
+  errorOutOfRangeM(""),
+  errorCheckSyntaxM("")
 {
   debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
   Create();
@@ -29,46 +34,26 @@
   Destroy();
 }
 
-size_t cSatipRtsp::HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, 
void *dataP)
+size_t cSatipRtsp::HeaderCallback(char *ptrP, size_t sizeP, size_t nmembP, 
void *dataP)
 {
   cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(dataP);
   size_t len = sizeP * nmembP;
   debug16("%s len=%zu", __PRETTY_FUNCTION__, len);
 
-  char *s, *p = (char *)ptrP;
-  char *r = strtok_r(p, "\r\n", &s);
-
-  while (obj && r) {
-        debug16("%s (%zu): %s", __PRETTY_FUNCTION__, len, r);
-        r = skipspace(r);
-        if (strstr(r, "com.ses.streamID")) {
-           int streamid = -1;
-           if (sscanf(r, "com.ses.streamID:%11d", &streamid) == 1)
-              obj->tunerM.SetStreamId(streamid);
-           }
-        else if (strstr(r, "Session:")) {
-           int timeout = -1;
-           char *session = NULL;
-           if (sscanf(r, "Session:%m[^;];timeout=%11d", &session, &timeout) == 
2)
-              obj->tunerM.SetSessionTimeout(skipspace(session), timeout * 
1000);
-           else if (sscanf(r, "Session:%m[^;]", &session) == 1)
-              obj->tunerM.SetSessionTimeout(skipspace(session), -1);
-           FREE_POINTER(session);
-           }
-        r = strtok_r(NULL, "\r\n", &s);
-        }
+  if (obj && (len > 0))
+     obj->headerBufferM.Add(ptrP, len);
 
   return len;
 }
 
-size_t cSatipRtsp::WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, void 
*dataP)
+size_t cSatipRtsp::DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void 
*dataP)
 {
   cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(dataP);
   size_t len = sizeP * nmembP;
   debug16("%s len=%zu", __PRETTY_FUNCTION__, len);
 
-  if (obj && (len > 0))
-     obj->tunerM.ProcessApplicationData((u_char*)ptrP, len);
+  if (obj)
+     obj->dataBufferM.Add(ptrP, len);
 
   return len;
 }
@@ -216,10 +201,22 @@
      // Set header callback for catching the session and timeout
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, 
cSatipRtsp::HeaderCallback);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, 
cSatipRtsp::DataCallback);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
      SATIP_CURL_EASY_PERFORM(handleM);
      // Session id is now known - disable header parsing
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, NULL);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, NULL);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL);
+     if (headerBufferM.Size() > 0) {
+        ParseHeader();
+        headerBufferM.Reset();
+        }
+     if (dataBufferM.Size() > 0) {
+        ParseData();
+        dataBufferM.Reset();
+        }
 
      result = ValidateLatestResponse(&rc);
      debug5("%s (%s, %d, %d) Response %ld in %" PRIu64 " ms [device %d]", 
__PRETTY_FUNCTION__, uriP, rtpPortP, rtcpPortP, rc, processing.Elapsed(), 
tunerM.GetId());
@@ -253,11 +250,15 @@
 
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, 
(long)CURL_RTSPREQ_DESCRIBE);
-     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, 
cSatipRtsp::WriteCallback);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, 
cSatipRtsp::DataCallback);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
      SATIP_CURL_EASY_PERFORM(handleM);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL);
+     if (dataBufferM.Size() > 0) {
+        tunerM.ProcessApplicationData((u_char *)dataBufferM.Data(), 
dataBufferM.Size());
+        dataBufferM.Reset();
+        }
 
      result = ValidateLatestResponse(&rc);
      debug5("%s (%s) Response %ld in %" PRIu64 " ms [device %d]", 
__PRETTY_FUNCTION__, uriP, rc, processing.Elapsed(), tunerM.GetId());
@@ -278,7 +279,15 @@
 
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, 
(long)CURL_RTSPREQ_PLAY);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, 
cSatipRtsp::DataCallback);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
      SATIP_CURL_EASY_PERFORM(handleM);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL);
+     if (dataBufferM.Size() > 0) {
+        ParseData();
+        dataBufferM.Reset();
+        }
 
      result = ValidateLatestResponse(&rc);
      debug5("%s (%s) Response %ld in %" PRIu64 " ms [device %d]", 
__PRETTY_FUNCTION__, uriP, rc, processing.Elapsed(), tunerM.GetId());
@@ -299,7 +308,15 @@
 
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, 
(long)CURL_RTSPREQ_TEARDOWN);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, 
cSatipRtsp::DataCallback);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
      SATIP_CURL_EASY_PERFORM(handleM);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL);
+     SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL);
+     if (dataBufferM.Size() > 0) {
+        ParseData();
+        dataBufferM.Reset();
+        }
 
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_CLIENT_CSEQ, 1L);
      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, NULL);
@@ -311,24 +328,122 @@
   return result;
 }
 
+void cSatipRtsp::ParseHeader(void)
+{
+  debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
+  char *s, *p = headerBufferM.Data();
+  char *r = strtok_r(p, "\r\n", &s);
+
+  while (r) {
+        debug16("%s (%zu): %s", __PRETTY_FUNCTION__, headerBufferM.Size(), r);
+        r = skipspace(r);
+        if (strstr(r, "com.ses.streamID")) {
+           int streamid = -1;
+           if (sscanf(r, "com.ses.streamID:%11d", &streamid) == 1)
+              tunerM.SetStreamId(streamid);
+           }
+        else if (strstr(r, "Session:")) {
+           int timeout = -1;
+           char *session = NULL;
+           if (sscanf(r, "Session:%m[^;];timeout=%11d", &session, &timeout) == 
2)
+              tunerM.SetSessionTimeout(skipspace(session), timeout * 1000);
+           else if (sscanf(r, "Session:%m[^;]", &session) == 1)
+              tunerM.SetSessionTimeout(skipspace(session), -1);
+           FREE_POINTER(session);
+           }
+        r = strtok_r(NULL, "\r\n", &s);
+        }
+}
+
+void cSatipRtsp::ParseData(void)
+{
+  debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
+  char *s, *p = dataBufferM.Data();
+  char *r = strtok_r(p, "\r\n", &s);
+
+  while (r) {
+        debug16("%s (%zu): %s", __PRETTY_FUNCTION__, dataBufferM.Size(), r);
+        r = skipspace(r);
+        if (strstr(r, "No-More:")) {
+           char *tmp = NULL;
+           if (sscanf(r, "No-More:%m[^;]", &tmp) == 1) {
+              errorNoMoreM = skipspace(tmp);
+              debug3("%s No-More: %s [device %d]", __PRETTY_FUNCTION__, 
*errorNoMoreM, tunerM.GetId());
+              }
+           FREE_POINTER(tmp);
+           }
+        else if (strstr(r, "Out-of-Range:")) {
+           char *tmp = NULL;
+           if (sscanf(r, "Out-of-Range:%m[^;]", &tmp) == 1) {
+              errorOutOfRangeM = skipspace(tmp);
+              debug3("%s Out-of-Range: %s [device %d]", __PRETTY_FUNCTION__, 
*errorOutOfRangeM, tunerM.GetId());
+              }
+           FREE_POINTER(tmp);
+           }
+        else if (strstr(r, "Check-Syntax:")) {
+           char *tmp = NULL;
+           if (sscanf(r, "Check-Syntax:%m[^;]", &tmp) == 1) {
+              errorCheckSyntaxM = skipspace(tmp);
+              debug3("%s Check-Syntax: %s [device %d]", __PRETTY_FUNCTION__, 
*errorCheckSyntaxM, tunerM.GetId());
+              }
+           FREE_POINTER(tmp);
+           }
+        r = strtok_r(NULL, "\r\n", &s);
+        }
+}
+
 bool cSatipRtsp::ValidateLatestResponse(long *rcP)
 {
   bool result = false;
 
   if (handleM) {
+     char *url = NULL;
      long rc = 0;
      CURLcode res = CURLE_OK;
      SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc);
-     if (rc == 200)
-        result = true;
-     else if (rc != 0) {
-        char *url = NULL;
-        SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url);
-        error("Detected invalid status code %ld: %s [device %d]", rc, url, 
tunerM.GetId());
-        }
+     switch (rc) {
+       case 200:
+            result = true;
+            break;
+       case 400:
+            // SETUP PLAY TEARDOWN
+            // The message body of the response may contain the 
"Check-Syntax:" parameter followed
+            // by the malformed syntax
+            if (!isempty(*errorCheckSyntaxM)) {
+               SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url);
+               error("Check syntax: %s (error code %ld: %s) [device %d]", 
*errorCheckSyntaxM, rc, url, tunerM.GetId());
+               break;
+               }
+       case 403:
+            // SETUP PLAY TEARDOWN
+            // The message body of the response may contain the 
"Out-of-Range:" parameter followed
+            // by a space-separated list of the attribute names that are not 
understood:
+            // "src" "fe" "freq" "pol" "msys" "mtype" "plts" "ro" "sr" "fec" 
"pids" "addpids" "delpids" "mcast
+            if (!isempty(*errorOutOfRangeM)) {
+               SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url);
+               error("Out of range: %s (error code %ld: %s) [device %d]", 
*errorOutOfRangeM, rc, url, tunerM.GetId());
+               break;
+               }
+       case 503:
+            // SETUP PLAY
+            // The message body of the response may contain the "No-More:" 
parameter followed
+            // by a space-separated list of the missing ressources: “sessions” 
"frontends" "pids
+            if (!isempty(*errorNoMoreM)) {
+               SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url);
+               error("No more: %s (error code %ld: %s) [device %d]", 
*errorNoMoreM, rc, url, tunerM.GetId());
+               break;
+               }
+       default:
+            SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url);
+            error("Detected invalid status code %ld: %s [device %d]", rc, url, 
tunerM.GetId());
+            break;
+       }
      if (rcP)
         *rcP = rc;
      }
+  errorNoMoreM = "";
+  errorOutOfRangeM = "";
+  errorCheckSyntaxM = "";
   debug1("%s result=%s [device %d]", __PRETTY_FUNCTION__, result ? "ok" : 
"failed", tunerM.GetId());
 
   return result;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/rtsp.h new/satip-2.2.2/rtsp.h
--- old/satip-2.2.0/rtsp.h      2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/rtsp.h      2015-04-26 03:20:00.000000000 +0200
@@ -15,12 +15,13 @@
 #error "libcurl is missing required RTSP support"
 #endif
 
+#include "common.h"
 #include "tunerif.h"
 
 class cSatipRtsp {
 private:
-  static size_t HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void 
*dataP);
-  static size_t WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, void 
*dataP);
+  static size_t HeaderCallback(char *ptrP, size_t sizeP, size_t nmembP, void 
*dataP);
+  static size_t DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void 
*dataP);
   static int    DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, 
size_t sizeP, void *userPtrP);
 
   enum {
@@ -29,12 +30,19 @@
   enum eCommunicationMode { cmUnicast, cmMulticast };
 
   cSatipTunerIf &tunerM;
+  cSatipMemoryBuffer headerBufferM;
+  cSatipMemoryBuffer dataBufferM;
   eCommunicationMode modeM;
   CURL *handleM;
   struct curl_slist *headerListM;
+  cString errorNoMoreM;
+  cString errorOutOfRangeM;
+  cString errorCheckSyntaxM;
 
   void Create(void);
   void Destroy(void);
+  void ParseHeader(void);
+  void ParseData(void);
   bool ValidateLatestResponse(long *rcP);
 
   // to prevent copy constructor and assignment
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/satip.c new/satip-2.2.2/satip.c
--- old/satip-2.2.0/satip.c     2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/satip.c     2015-04-26 03:20:00.000000000 +0200
@@ -27,7 +27,7 @@
 #define GITVERSION ""
 #endif
 
-       const char VERSION[]     = "2.2.0" GITVERSION;
+       const char VERSION[]     = "2.2.2" GITVERSION;
 static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
 
 class cPluginSatip : public cPlugin {
@@ -62,7 +62,7 @@
   };
 
 cPluginSatip::cPluginSatip(void)
-: deviceCountM(1),
+: deviceCountM(2),
   serversM(NULL)
 {
   debug16("%s", __PRETTY_FUNCTION__);
@@ -85,6 +85,7 @@
          "  -t <mode>, --trace=<mode>     set the tracing mode\n"
          "  -s <ipaddr>|<model>|<desc>, 
--server=<ipaddr1>|<model1>|<desc1>;<ipaddr2>|<model2>|<desc2>\n"
          "                                define hard-coded SAT>IP server(s)\n"
+         "  -D, --detach                  set the detached mode on\n"
          "  -S, --single                  set the single model server mode 
on\n"
          "  -n, --noquirks                disable all the server quirks\n";
 }
@@ -97,6 +98,7 @@
     { "devices",  required_argument, NULL, 'd' },
     { "trace",    required_argument, NULL, 't' },
     { "server",   required_argument, NULL, 's' },
+    { "detach",   no_argument,       NULL, 'D' },
     { "single",   no_argument,       NULL, 'S' },
     { "noquirks", no_argument,       NULL, 'n' },
     { NULL,       no_argument,       NULL,  0  }
@@ -104,7 +106,7 @@
 
   cString server;
   int c;
-  while ((c = getopt_long(argc, argv, "d:t:s:Sn", long_options, NULL)) != -1) {
+  while ((c = getopt_long(argc, argv, "d:t:s:DSn", long_options, NULL)) != -1) 
{
     switch (c) {
       case 'd':
            deviceCountM = strtol(optarg, NULL, 0);
@@ -115,6 +117,9 @@
       case 's':
            server = optarg;
            break;
+      case 'D':
+           SatipConfig.SetDetachedMode(true);
+           break;
       case 'S':
            SatipConfig.SetUseSingleModelServers(true);
            break;
@@ -366,8 +371,12 @@
     "    Lists status information of SAT>IP devices.\n",
     "CONT\n"
     "    Shows SAT>IP device count.\n",
-    "OPER\n"
-    "    Toggles operating mode of SAT>IP devices.\n",
+    "OPER [ off | low | normal | high ]\n"
+    "    Gets and(or sets operating mode of SAT>IP devices.\n",
+    "ATTA\n"
+    "    Attach active SAT>IP servers.\n",
+    "DETA\n"
+    "    Detachs active SAT>IP servers.\n",
     "TRAC [ <mode> ]\n"
     "    Gets and/or sets used tracing mode.\n",
     NULL
@@ -434,8 +443,19 @@
      }
   else if (strcasecmp(commandP, "OPER") == 0) {
      cString mode;
-     SatipConfig.ToggleOperatingMode();
-     switch (SatipConfig.GetOperatingMode()) {
+     unsigned int oper = SatipConfig.GetOperatingMode();
+     if (optionP && *optionP) {
+        if (strcasecmp(optionP, "off") == 0)
+           oper = cSatipConfig::eOperatingModeOff;
+        else if (strcasecmp(optionP, "low") == 0)
+           oper = cSatipConfig::eOperatingModeLow;
+        else if (strcasecmp(optionP, "normal") == 0)
+           oper = cSatipConfig::eOperatingModeNormal;
+        else if (strcasecmp(optionP, "high") == 0)
+           oper = cSatipConfig::eOperatingModeHigh;
+        SatipConfig.SetOperatingMode(oper);
+     }
+     switch (oper) {
        case cSatipConfig::eOperatingModeOff:
             mode = "off";
             break;
@@ -454,6 +474,16 @@
        }
      return cString::sprintf("SATIP operating mode: %s\n", *mode);
      }
+  else if (strcasecmp(commandP, "ATTA") == 0) {
+     SatipConfig.SetDetachedMode(false);
+     info("SATIP servers attached");
+     return cString("SATIP servers attached");
+     }
+  else if (strcasecmp(commandP, "DETA") == 0) {
+     SatipConfig.SetDetachedMode(true);
+     info("SATIP servers detached");
+     return cString("SATIP servers detached");
+     }
   else if (strcasecmp(commandP, "TRAC") == 0) {
      if (optionP && *optionP)
         SatipConfig.SetTraceMode(strtol(optionP, NULL, 0));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/setup.c new/satip-2.2.2/setup.c
--- old/satip-2.2.0/setup.c     2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/setup.c     2015-04-26 03:20:00.000000000 +0200
@@ -330,7 +330,8 @@
 // --- cSatipPluginSetup ------------------------------------------------------
 
 cSatipPluginSetup::cSatipPluginSetup()
-: deviceCountM(0),
+: detachedModeM(SatipConfig.GetDetachedMode()),
+  deviceCountM(0),
   operatingModeM(SatipConfig.GetOperatingMode()),
   ciExtensionM(SatipConfig.GetCIExtension()),
   eitScanM(SatipConfig.GetEITScan()),
@@ -402,12 +403,15 @@
   Add(new cOsdItem(tr("Active SAT>IP servers:"), osUnknown, false));
   helpM.Append("");
 
-  cSatipServers *servers = cSatipDiscover::GetInstance()->GetServers();
-  deviceCountM = servers->Count();
-  for (cSatipServer *s = servers->First(); s; s = servers->Next(s)) {
-      Add(new cSatipServerItem(s));
-      helpM.Append("");
-      }
+  detachedModeM = SatipConfig.GetDetachedMode();
+  if (!detachedModeM) {
+     cSatipServers *servers = cSatipDiscover::GetInstance()->GetServers();
+     deviceCountM = servers->Count();
+     for (cSatipServer *s = servers->First(); s; s = servers->Next(s)) {
+         Add(new cSatipServerItem(s));
+         helpM.Append("");
+         }
+     }
 
   SetCurrent(Get(current));
   Display();
@@ -480,7 +484,7 @@
   if ((keyP == kNone) && (cSatipDiscover::GetInstance()->GetServers()->Count() 
!= deviceCountM))
      Setup();
 
-  if ((keyP != kNone) && ((numDisabledSourcesM != oldNumDisabledSources) || 
(numDisabledFiltersM != oldNumDisabledFilters) || (operatingModeM != 
oldOperatingMode) || (ciExtensionM != oldCiExtension))) {
+  if ((keyP != kNone) && ((numDisabledSourcesM != oldNumDisabledSources) || 
(numDisabledFiltersM != oldNumDisabledFilters) || (operatingModeM != 
oldOperatingMode) || (ciExtensionM != oldCiExtension) || (detachedModeM != 
SatipConfig.GetDetachedMode()))) {
      while ((numDisabledSourcesM < oldNumDisabledSources) && 
(oldNumDisabledSources > 0))
            disabledSourcesM[--oldNumDisabledSources] = cSource::stNone;
      while ((numDisabledFiltersM < oldNumDisabledFilters) && 
(oldNumDisabledFilters > 0))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/satip-2.2.0/setup.h new/satip-2.2.2/setup.h
--- old/satip-2.2.0/setup.h     2015-02-19 03:20:00.000000000 +0100
+++ new/satip-2.2.2/setup.h     2015-04-26 03:20:00.000000000 +0200
@@ -15,6 +15,7 @@
 class cSatipPluginSetup : public cMenuSetupPage
 {
 private:
+  bool detachedModeM;
   int deviceCountM;
   int operatingModeM;
   const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];


Reply via email to