[vdr-plugin-satip] 01/03: Imported Upstream version 2.2.1
Frank Neumann
fnu-guest at moszumanska.debian.org
Sat Apr 25 19:47:11 UTC 2015
This is an automated email from the git hooks/post-receive script.
fnu-guest pushed a commit to branch master
in repository vdr-plugin-satip.
commit 866c02c43cf570199d71dae3d68b2c3c8d8d2367
Author: Frank Neumann <fnu at yavdr.org>
Date: Sat Apr 25 21:23:50 2015 +0200
Imported Upstream version 2.2.1
---
HISTORY | 10 ++++
Makefile | 17 +-----
common.h | 64 ++++++++++++++++++---
config.h | 36 ++++++------
discover.c | 76 +++++++++++++------------
discover.h | 14 +++--
log.h | 5 +-
msearch.c | 7 ++-
param.c | 18 +++---
po/ca_ES.po | 6 +-
po/de_DE.po | 6 +-
po/es_ES.po | 6 +-
po/fi_FI.po | 6 +-
rtsp.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++------------
rtsp.h | 12 +++-
satip.c | 2 +-
16 files changed, 324 insertions(+), 146 deletions(-)
diff --git a/HISTORY b/HISTORY
index 6ea4717..9cee659 100644
--- a/HISTORY
+++ b/HISTORY
@@ -120,3 +120,13 @@ VDR Plugin 'satip' Revision History
- 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.
diff --git a/Makefile b/Makefile
index 2ff1695..b4c3bec 100644
--- a/Makefile
+++ b/Makefile
@@ -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 @@ TMPDIR ?= /tmp
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 @@ else
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 @@ install-i18n: $(I18Nmsgs)
$(SOFILE): $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
-ifndef SATIP_DEBUG
@$(STRIP) $@
-endif
install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
diff --git a/common.h b/common.h
index 1cc713b..ac9ea20 100644
--- a/common.h
+++ b/common.h
@@ -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 --git a/config.h b/config.h
index 9dcd4fd..5b11614 100644
--- a/config.h
+++ b/config.h
@@ -34,24 +34,24 @@ public:
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; }
diff --git a/discover.c b/discover.c
index 2a77325..990af68 100644
--- a/discover.c
+++ b/discover.c
@@ -47,43 +47,14 @@ void cSatipDiscover::Destroy(void)
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 @@ int cSatipDiscover::DebugCallback(CURL *handleP, curl_infotype typeP, char *data
cSatipDiscover::cSatipDiscover()
: cThread("SATIP discover"),
mutexM(),
+ dataBufferM(),
msearchM(*this),
probeUrlListM(),
handleM(curl_easy_init()),
@@ -170,7 +142,7 @@ void cSatipDiscover::Action(void)
probeIntervalM.Set(eProbeIntervalMs);
msearchM.Probe();
mutexM.Lock();
- serversM.Cleanup(eProbeIntervalMs * 2);
+ serversM.Cleanup(eCleanupTimeoutMs);
mutexM.Unlock();
}
mutexM.Lock();
@@ -195,6 +167,7 @@ void cSatipDiscover::Fetch(const char *urlP)
{
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 @@ void cSatipDiscover::Fetch(const char *urlP)
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 @@ void cSatipDiscover::Fetch(const char *urlP)
// 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 --git a/discover.h b/discover.h
index 4984080..5942e42 100644
--- a/discover.h
+++ b/discover.h
@@ -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 cSatipDiscoverServers : public cList<cSatipDiscoverServer> {
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 @@ private:
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 --git a/log.h b/log.h
index 4d5ee67..546d13e 100644
--- a/log.h
+++ b/log.h
@@ -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 --git a/msearch.c b/msearch.c
index ab1fbad..f5edafc 100644
--- a/msearch.c
+++ b/msearch.c
@@ -45,6 +45,9 @@ void cSatipMsearch::Probe(void)
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 @@ void cSatipMsearch::Process(void)
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 --git a/param.c b/param.c
index 03caa48..c71902d 100644
--- a/param.c
+++ b/param.c
@@ -147,9 +147,6 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
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 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
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 --git a/po/ca_ES.po b/po/ca_ES.po
index e9ef289..a39cc70 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -5,10 +5,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: vdr-satip 2.2.0\n"
+"Project-Id-Version: vdr-satip 2.2.1\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-04 04:04+0300\n"
+"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"Last-Translator: Gabriel Bonich <gbonich at gmail.com>\n"
"Language-Team: Catalan <vdr at linuxtv.org>\n"
"Language: ca\n"
diff --git a/po/de_DE.po b/po/de_DE.po
index 9cd77ec..1f5be1e 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -5,10 +5,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: vdr-satip 2.2.0\n"
+"Project-Id-Version: vdr-satip 2.2.1\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-04 04:04+0300\n"
+"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"Last-Translator: Frank Neumann <fnu at yavdr.org>\n"
"Language-Team: German <vdr at linuxtv.org>\n"
"Language: de\n"
diff --git a/po/es_ES.po b/po/es_ES.po
index 724f5fb..4e0d772 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -5,10 +5,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: vdr-satip 2.2.0\n"
+"Project-Id-Version: vdr-satip 2.2.1\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-04 04:04+0300\n"
+"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"Last-Translator: Gabriel Bonich <gbonich at gmail.com>\n"
"Language-Team: Spanish <vdr at linuxtv.org>\n"
"Language: es\n"
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 0b27822..94608f5 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -5,10 +5,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: vdr-satip 2.2.0\n"
+"Project-Id-Version: vdr-satip 2.2.1\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-04 04:04+0300\n"
+"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"Last-Translator: Rolf Ahrenberg\n"
"Language-Team: Finnish <vdr at linuxtv.org>\n"
"Language: fi\n"
diff --git a/rtsp.c b/rtsp.c
index e437d6b..562626e 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -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 @@ cSatipRtsp::~cSatipRtsp()
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 @@ bool cSatipRtsp::Setup(const char *uriP, int rtpPortP, int rtcpPortP)
// 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 @@ bool cSatipRtsp::Describe(const char *uriP)
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 @@ bool cSatipRtsp::Play(const char *uriP)
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 @@ bool cSatipRtsp::Teardown(const char *uriP)
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 @@ bool cSatipRtsp::Teardown(const char *uriP)
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 --git a/rtsp.h b/rtsp.h
index 1d1be4d..3949524 100644
--- a/rtsp.h
+++ b/rtsp.h
@@ -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 @@ private:
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 --git a/satip.c b/satip.c
index b34da79..6b58e72 100644
--- a/satip.c
+++ b/satip.c
@@ -27,7 +27,7 @@
#define GITVERSION ""
#endif
- const char VERSION[] = "2.2.0" GITVERSION;
+ const char VERSION[] = "2.2.1" GITVERSION;
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
class cPluginSatip : public cPlugin {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr-plugin-satip.git
More information about the pkg-vdr-dvb-changes
mailing list