mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 11:37:42 +00:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6c4c8a10b7 | ||
|
8b43cdc634 | ||
|
fe010ab72c | ||
|
7bdc152f76 | ||
|
bd6774ba28 | ||
|
fbf7977853 | ||
|
19a6a4a5ee | ||
|
7b683dba8d | ||
|
942d3a936e | ||
|
748ea15d1d | ||
|
1d75da403a | ||
|
4d8263e8fd | ||
|
7019b719a5 | ||
|
39249ca2d5 | ||
|
68e0d1474e | ||
|
ad5c221e44 | ||
|
826e53e8ea | ||
|
f4dd02a9aa |
17
HISTORY
17
HISTORY
@@ -120,3 +120,20 @@ 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.
|
||||
|
||||
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.
|
||||
|
17
Makefile
17
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)
|
||||
|
2
README
2
README
@@ -42,7 +42,7 @@ make -C satip-X.Y.Z install
|
||||
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
|
||||
|
64
common.h
64
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);
|
||||
|
1
config.c
1
config.c
@@ -17,6 +17,7 @@ cSatipConfig::cSatipConfig(void)
|
||||
ciExtensionM(0),
|
||||
eitScanM(1),
|
||||
useBytesM(1),
|
||||
detachedModeM(false),
|
||||
disableServerQuirksM(false),
|
||||
useSingleModelServersM(false)
|
||||
{
|
||||
|
39
config.h
39
config.h
@@ -19,6 +19,7 @@ private:
|
||||
unsigned int ciExtensionM;
|
||||
unsigned int eitScanM;
|
||||
unsigned int useBytesM;
|
||||
bool detachedModeM;
|
||||
bool disableServerQuirksM;
|
||||
bool useSingleModelServersM;
|
||||
int cicamsM[MAX_CICAM_COUNT];
|
||||
@@ -34,24 +35,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; }
|
||||
@@ -66,6 +67,7 @@ public:
|
||||
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 @@ public:
|
||||
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);
|
||||
|
4
device.c
4
device.c
@@ -219,6 +219,8 @@ bool cSatipDevice::ProvidesSource(int sourceP) const
|
||||
{
|
||||
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 @@ void cSatipDevice::SkipData(int countP)
|
||||
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()) {
|
||||
|
76
discover.c
76
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);
|
||||
|
14
discover.h
14
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
|
||||
|
5
log.h
5
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
|
||||
|
||||
|
@@ -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"))
|
||||
|
18
param.c
18
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);
|
||||
|
@@ -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 <gbonich@gmail.com>\n"
|
||||
"Language-Team: Catalan <vdr@linuxtv.org>\n"
|
||||
"Language: ca\n"
|
||||
|
@@ -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 <fnu@yavdr.org>\n"
|
||||
"Language-Team: German <vdr@linuxtv.org>\n"
|
||||
"Language: de\n"
|
||||
|
@@ -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 <gbonich@gmail.com>\n"
|
||||
"Language-Team: Spanish <vdr@linuxtv.org>\n"
|
||||
"Language: es\n"
|
||||
|
@@ -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 <vdr@linuxtv.org>\n"
|
||||
"Language: fi\n"
|
||||
|
201
rtsp.c
201
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t cSatipRtsp::WriteCallback(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);
|
||||
|
||||
if (obj && (len > 0))
|
||||
obj->tunerM.ProcessApplicationData((u_char*)ptrP, len);
|
||||
obj->headerBufferM.Add(ptrP, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
|
12
rtsp.h
12
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
|
||||
|
44
satip.c
44
satip.c
@@ -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 @@ public:
|
||||
};
|
||||
|
||||
cPluginSatip::cPluginSatip(void)
|
||||
: deviceCountM(1),
|
||||
: deviceCountM(2),
|
||||
serversM(NULL)
|
||||
{
|
||||
debug16("%s", __PRETTY_FUNCTION__);
|
||||
@@ -85,6 +85,7 @@ const char *cPluginSatip::CommandLineHelp(void)
|
||||
" -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 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
||||
{ "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 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
||||
|
||||
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 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
||||
case 's':
|
||||
server = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
SatipConfig.SetDetachedMode(true);
|
||||
break;
|
||||
case 'S':
|
||||
SatipConfig.SetUseSingleModelServers(true);
|
||||
break;
|
||||
@@ -366,8 +371,12 @@ const char **cPluginSatip::SVDRPHelpPages(void)
|
||||
" 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 @@ cString cPluginSatip::SVDRPCommand(const char *commandP, const char *optionP, in
|
||||
}
|
||||
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 @@ cString cPluginSatip::SVDRPCommand(const char *commandP, const char *optionP, in
|
||||
}
|
||||
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));
|
||||
|
20
setup.c
20
setup.c
@@ -330,7 +330,8 @@ eOSState cSatipMenuInfo::ProcessKey(eKeys keyP)
|
||||
// --- cSatipPluginSetup ------------------------------------------------------
|
||||
|
||||
cSatipPluginSetup::cSatipPluginSetup()
|
||||
: deviceCountM(0),
|
||||
: detachedModeM(SatipConfig.GetDetachedMode()),
|
||||
deviceCountM(0),
|
||||
operatingModeM(SatipConfig.GetOperatingMode()),
|
||||
ciExtensionM(SatipConfig.GetCIExtension()),
|
||||
eitScanM(SatipConfig.GetEITScan()),
|
||||
@@ -402,12 +403,15 @@ void cSatipPluginSetup::Setup(void)
|
||||
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 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
|
||||
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))
|
||||
|
Reference in New Issue
Block a user