mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 11:37:42 +00:00
Compare commits
37 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6c4c8a10b7 | ||
|
8b43cdc634 | ||
|
fe010ab72c | ||
|
7bdc152f76 | ||
|
bd6774ba28 | ||
|
fbf7977853 | ||
|
19a6a4a5ee | ||
|
7b683dba8d | ||
|
942d3a936e | ||
|
748ea15d1d | ||
|
1d75da403a | ||
|
4d8263e8fd | ||
|
7019b719a5 | ||
|
39249ca2d5 | ||
|
68e0d1474e | ||
|
ad5c221e44 | ||
|
826e53e8ea | ||
|
f4dd02a9aa | ||
|
8184a785b7 | ||
|
1b4094696a | ||
|
4139e87f4a | ||
|
7196c9403b | ||
|
e1c896c1a6 | ||
|
6b63ad145f | ||
|
84dfc6701e | ||
|
653d9d659b | ||
|
26cd34f965 | ||
|
df258d127f | ||
|
3e4b1c0383 | ||
|
73ed299ed9 | ||
|
37e151b3e3 | ||
|
b1aad3fb80 | ||
|
a87dfc43f7 | ||
|
26be862d89 | ||
|
ab2a47e3e7 | ||
|
3d1efe7a80 | ||
|
c9898bfbfd |
29
HISTORY
29
HISTORY
@@ -108,3 +108,32 @@ VDR Plugin 'satip' Revision History
|
|||||||
- Updated Spanish and Catalan translations (Thanks to
|
- Updated Spanish and Catalan translations (Thanks to
|
||||||
Gabriel Bonich).
|
Gabriel Bonich).
|
||||||
- Updated German translations (Thanks to Frank Neumann).
|
- Updated German translations (Thanks to Frank Neumann).
|
||||||
|
|
||||||
|
|
||||||
|
===================================
|
||||||
|
VDR Plugin 'satip' Revision History
|
||||||
|
===================================
|
||||||
|
|
||||||
|
2015-02-19: Version 2.2.0
|
||||||
|
|
||||||
|
- Updated for vdr-2.2.0.
|
||||||
|
- 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
|
# Makefile for SAT>IP plugin
|
||||||
#
|
#
|
||||||
|
|
||||||
# Debugging on/off
|
|
||||||
|
|
||||||
#SATIP_DEBUG = 1
|
|
||||||
|
|
||||||
# Use TinyXML instead of PugiXML
|
# Use TinyXML instead of PugiXML
|
||||||
|
|
||||||
#SATIP_USE_TINYXML = 1
|
#SATIP_USE_TINYXML = 1
|
||||||
|
|
||||||
# Strip debug symbols? Set eg. to /bin/true if not
|
|
||||||
|
|
||||||
STRIP = strip
|
|
||||||
|
|
||||||
# The official name of this plugin.
|
# The official name of this plugin.
|
||||||
# This name will be used in the '-P...' option of VDR to load the 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.
|
# By default the main source file also carries this name.
|
||||||
@@ -40,6 +32,7 @@ TMPDIR ?= /tmp
|
|||||||
|
|
||||||
export CFLAGS = $(call PKGCFG,cflags)
|
export CFLAGS = $(call PKGCFG,cflags)
|
||||||
export CXXFLAGS = $(call PKGCFG,cxxflags)
|
export CXXFLAGS = $(call PKGCFG,cxxflags)
|
||||||
|
STRIP ?= /bin/true
|
||||||
|
|
||||||
### The version number of VDR's plugin API:
|
### The version number of VDR's plugin API:
|
||||||
|
|
||||||
@@ -75,12 +68,6 @@ else
|
|||||||
LIBS += -lpugixml
|
LIBS += -lpugixml
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef SATIP_DEBUG
|
|
||||||
ifeq ($(SATIP_DEBUG),1)
|
|
||||||
DEFINES += -DDEBUG
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(strip $(GITTAG)),)
|
ifneq ($(strip $(GITTAG)),)
|
||||||
DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"'
|
DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"'
|
||||||
endif
|
endif
|
||||||
@@ -142,9 +129,7 @@ install-i18n: $(I18Nmsgs)
|
|||||||
|
|
||||||
$(SOFILE): $(OBJS)
|
$(SOFILE): $(OBJS)
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
||||||
ifndef SATIP_DEBUG
|
|
||||||
@$(STRIP) $@
|
@$(STRIP) $@
|
||||||
endif
|
|
||||||
|
|
||||||
install-lib: $(SOFILE)
|
install-lib: $(SOFILE)
|
||||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||||
|
10
README
10
README
@@ -26,10 +26,6 @@ Requirements:
|
|||||||
- Glibc >= 2.12 - the GNU C library (recvmmsg)
|
- Glibc >= 2.12 - the GNU C library (recvmmsg)
|
||||||
http://www.gnu.org/software/libc/
|
http://www.gnu.org/software/libc/
|
||||||
|
|
||||||
- VDR >= 2.1.4 for scrambled channels
|
|
||||||
|
|
||||||
- VDR >= 2.1.7 for external CI
|
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
|
|
||||||
This plugin integrates SAT>IP network devices seamlessly into VDR.
|
This plugin integrates SAT>IP network devices seamlessly into VDR.
|
||||||
@@ -46,7 +42,7 @@ make -C satip-X.Y.Z install
|
|||||||
Configuration:
|
Configuration:
|
||||||
|
|
||||||
The plugin accepts a "--devices" (-d) command-line parameter defaulting
|
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.
|
be received, if there are available SAT>IP tuners.
|
||||||
|
|
||||||
The plugin accepts also a "--server" (-s) command-line parameter, that
|
The plugin accepts also a "--server" (-s) command-line parameter, that
|
||||||
@@ -136,8 +132,8 @@ Notes:
|
|||||||
your setup doesn't have firewalled the UDP port 1900.
|
your setup doesn't have firewalled the UDP port 1900.
|
||||||
|
|
||||||
- Stream decryption requires a separate CAM plugin that works without
|
- Stream decryption requires a separate CAM plugin that works without
|
||||||
direct access to any DVB card devices. The integrated CAM slot in
|
direct access to any DVB card devices. Also the integrated CAM slots
|
||||||
Octopus Net devices isn't supported.
|
in Octopus Net devices are supported.
|
||||||
|
|
||||||
- Tracing can be set on/off dynamically via command-line switch or
|
- Tracing can be set on/off dynamically via command-line switch or
|
||||||
SVDRP command.
|
SVDRP command.
|
||||||
|
64
common.h
64
common.h
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
#define SATIP_CURL_EASY_GETINFO(X, Y, Z) \
|
#define SATIP_CURL_EASY_GETINFO(X, Y, Z) \
|
||||||
if ((res = curl_easy_getinfo((X), (Y), (Z))) != CURLE_OK) { \
|
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) \
|
#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); \
|
esyslog("curl_easy_perform() [%s,%d] failed: %s (%d)", __FILE__, __LINE__, curl_easy_strerror(res), res); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ERROR_IF_FUNC(exp, errstr, func, ret) \
|
#define ERROR_IF_FUNC(exp, errstr, func, ret) \
|
||||||
do { \
|
do { \
|
||||||
if (exp) { \
|
if (exp) { \
|
||||||
char tmp[64]; \
|
char tmp[64]; \
|
||||||
esyslog("[%s,%d]: "errstr": %s", __FILE__, __LINE__, \
|
esyslog("[%s,%d]: "errstr": %s", __FILE__, __LINE__, \
|
||||||
strerror_r(errno, tmp, sizeof(tmp))); \
|
strerror_r(errno, tmp, sizeof(tmp))); \
|
||||||
func; \
|
func; \
|
||||||
ret; \
|
ret; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
@@ -84,6 +84,52 @@
|
|||||||
|
|
||||||
#define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
|
#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);
|
uint16_t ts_pid(const uint8_t *bufP);
|
||||||
uint8_t payload(const uint8_t *bufP);
|
uint8_t payload(const uint8_t *bufP);
|
||||||
const char *id_pid(const u_short pidP);
|
const char *id_pid(const u_short pidP);
|
||||||
|
1
config.c
1
config.c
@@ -17,6 +17,7 @@ cSatipConfig::cSatipConfig(void)
|
|||||||
ciExtensionM(0),
|
ciExtensionM(0),
|
||||||
eitScanM(1),
|
eitScanM(1),
|
||||||
useBytesM(1),
|
useBytesM(1),
|
||||||
|
detachedModeM(false),
|
||||||
disableServerQuirksM(false),
|
disableServerQuirksM(false),
|
||||||
useSingleModelServersM(false)
|
useSingleModelServersM(false)
|
||||||
{
|
{
|
||||||
|
39
config.h
39
config.h
@@ -19,6 +19,7 @@ private:
|
|||||||
unsigned int ciExtensionM;
|
unsigned int ciExtensionM;
|
||||||
unsigned int eitScanM;
|
unsigned int eitScanM;
|
||||||
unsigned int useBytesM;
|
unsigned int useBytesM;
|
||||||
|
bool detachedModeM;
|
||||||
bool disableServerQuirksM;
|
bool disableServerQuirksM;
|
||||||
bool useSingleModelServersM;
|
bool useSingleModelServersM;
|
||||||
int cicamsM[MAX_CICAM_COUNT];
|
int cicamsM[MAX_CICAM_COUNT];
|
||||||
@@ -34,24 +35,24 @@ public:
|
|||||||
eOperatingModeCount
|
eOperatingModeCount
|
||||||
};
|
};
|
||||||
enum eTraceMode {
|
enum eTraceMode {
|
||||||
eTraceModeNormal = 0x0000,
|
eTraceModeNormal = 0x0000,
|
||||||
eTraceModeDebug1 = 0x0001,
|
eTraceModeDebug1 = 0x0001,
|
||||||
eTraceModeDebug2 = 0x0002,
|
eTraceModeDebug2 = 0x0002,
|
||||||
eTraceModeDebug3 = 0x0004,
|
eTraceModeDebug3 = 0x0004,
|
||||||
eTraceModeDebug4 = 0x0008,
|
eTraceModeDebug4 = 0x0008,
|
||||||
eTraceModeDebug5 = 0x0010,
|
eTraceModeDebug5 = 0x0010,
|
||||||
eTraceModeDebug6 = 0x0020,
|
eTraceModeDebug6 = 0x0020,
|
||||||
eTraceModeDebug7 = 0x0040,
|
eTraceModeDebug7 = 0x0040,
|
||||||
eTraceModeDebug8 = 0x0080,
|
eTraceModeDebug8 = 0x0080,
|
||||||
eTraceModeDebug9 = 0x0100,
|
eTraceModeDebug9 = 0x0100,
|
||||||
eTraceModeDebug10 = 0x0200,
|
eTraceModeDebug10 = 0x0200,
|
||||||
eTraceModeDebug11 = 0x0400,
|
eTraceModeDebug11 = 0x0400,
|
||||||
eTraceModeDebug12 = 0x0800,
|
eTraceModeDebug12 = 0x0800,
|
||||||
eTraceModeDebug13 = 0x1000,
|
eTraceModeDebug13 = 0x1000,
|
||||||
eTraceModeDebug14 = 0x2000,
|
eTraceModeDebug14 = 0x2000,
|
||||||
eTraceModeDebug15 = 0x4000,
|
eTraceModeDebug15 = 0x4000,
|
||||||
eTraceModeDebug16 = 0x8000,
|
eTraceModeDebug16 = 0x8000,
|
||||||
eTraceModeMask = 0xFFFF
|
eTraceModeMask = 0xFFFF
|
||||||
};
|
};
|
||||||
cSatipConfig();
|
cSatipConfig();
|
||||||
unsigned int GetOperatingMode(void) const { return operatingModeM; }
|
unsigned int GetOperatingMode(void) const { return operatingModeM; }
|
||||||
@@ -66,6 +67,7 @@ public:
|
|||||||
int GetCICAM(unsigned int indexP) const;
|
int GetCICAM(unsigned int indexP) const;
|
||||||
unsigned int GetEITScan(void) const { return eitScanM; }
|
unsigned int GetEITScan(void) const { return eitScanM; }
|
||||||
unsigned int GetUseBytes(void) const { return useBytesM; }
|
unsigned int GetUseBytes(void) const { return useBytesM; }
|
||||||
|
bool GetDetachedMode(void) const { return detachedModeM; }
|
||||||
bool GetDisableServerQuirks(void) const { return disableServerQuirksM; }
|
bool GetDisableServerQuirks(void) const { return disableServerQuirksM; }
|
||||||
bool GetUseSingleModelServers(void) const { return useSingleModelServersM; }
|
bool GetUseSingleModelServers(void) const { return useSingleModelServersM; }
|
||||||
unsigned int GetDisabledSourcesCount(void) const;
|
unsigned int GetDisabledSourcesCount(void) const;
|
||||||
@@ -79,6 +81,7 @@ public:
|
|||||||
void SetCICAM(unsigned int indexP, int cicamP);
|
void SetCICAM(unsigned int indexP, int cicamP);
|
||||||
void SetEITScan(unsigned int onOffP) { eitScanM = onOffP; }
|
void SetEITScan(unsigned int onOffP) { eitScanM = onOffP; }
|
||||||
void SetUseBytes(unsigned int onOffP) { useBytesM = onOffP; }
|
void SetUseBytes(unsigned int onOffP) { useBytesM = onOffP; }
|
||||||
|
void SetDetachedMode(bool onOffP) { detachedModeM = onOffP; }
|
||||||
void SetDisableServerQuirks(bool onOffP) { disableServerQuirksM = onOffP; }
|
void SetDisableServerQuirks(bool onOffP) { disableServerQuirksM = onOffP; }
|
||||||
void SetUseSingleModelServers(bool onOffP) { useSingleModelServersM = onOffP; }
|
void SetUseSingleModelServers(bool onOffP) { useSingleModelServersM = onOffP; }
|
||||||
void SetDisabledSources(unsigned int indexP, int sourceP);
|
void SetDisabledSources(unsigned int indexP, int sourceP);
|
||||||
|
18
device.c
18
device.c
@@ -219,6 +219,8 @@ bool cSatipDevice::ProvidesSource(int sourceP) const
|
|||||||
{
|
{
|
||||||
cSource *s = Sources.Get(sourceP);
|
cSource *s = Sources.Get(sourceP);
|
||||||
debug9("%s (%c) desc='%s' [device %u]", __PRETTY_FUNCTION__, cSource::ToChar(sourceP), s ? s->Description() : "", deviceIndexM);
|
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
|
// source descriptions starting with '0' are disabled
|
||||||
if (s && s->Description() && (*(s->Description()) == '0'))
|
if (s && s->Description() && (*(s->Description()) == '0'))
|
||||||
return false;
|
return false;
|
||||||
@@ -328,20 +330,19 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cString address;
|
cString address;
|
||||||
cSatipServer *server = cSatipDiscover::GetInstance()->GetServer(channelP->Source(), channelP->Transponder(), dtp.System());
|
cSatipServer *server = cSatipDiscover::GetInstance()->AssignServer(deviceIndexM, channelP->Source(), channelP->Transponder(), dtp.System());
|
||||||
if (!server) {
|
if (!server) {
|
||||||
debug9("%s No suitable server found [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug9("%s No suitable server found [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cSatipDiscover::GetInstance()->SetTransponder(server, channelP->Transponder());
|
if (pTunerM && pTunerM->SetSource(server, channelP->Transponder(), *params, deviceIndexM)) {
|
||||||
if (pTunerM && pTunerM->SetSource(server, *params, deviceIndexM)) {
|
|
||||||
channelM = *channelP;
|
channelM = *channelP;
|
||||||
deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server));
|
deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pTunerM) {
|
else if (pTunerM) {
|
||||||
pTunerM->SetSource(NULL, NULL, deviceIndexM);
|
pTunerM->SetSource(NULL, 0, NULL, deviceIndexM);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -434,10 +435,7 @@ int cSatipDevice::GetId(void)
|
|||||||
|
|
||||||
int cSatipDevice::GetPmtPid(void)
|
int cSatipDevice::GetPmtPid(void)
|
||||||
{
|
{
|
||||||
int pid = 0;
|
int pid = channelM.Ca() ? ::GetPmtPid(channelM.Source(), channelM.Transponder(), channelM.Sid()) : 0;
|
||||||
#if defined(APIVERSNUM) && APIVERSNUM >= 20107
|
|
||||||
pid = channelM.Ca() ? ::GetPmtPid(channelM.Source(), channelM.Transponder(), channelM.Sid()) : 0;
|
|
||||||
#endif
|
|
||||||
debug11("%s pmtpid=%d source=%c transponder=%d sid=%d name=%s [device %u]", __PRETTY_FUNCTION__, pid, cSource::ToChar(channelM.Source()), channelM.Transponder(), channelM.Sid(), channelM.Name(), deviceIndexM);
|
debug11("%s pmtpid=%d source=%c transponder=%d sid=%d name=%s [device %u]", __PRETTY_FUNCTION__, pid, cSource::ToChar(channelM.Source()), channelM.Transponder(), channelM.Sid(), channelM.Name(), deviceIndexM);
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
@@ -505,8 +503,9 @@ void cSatipDevice::SkipData(int countP)
|
|||||||
bool cSatipDevice::GetTSPacket(uchar *&dataP)
|
bool cSatipDevice::GetTSPacket(uchar *&dataP)
|
||||||
{
|
{
|
||||||
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
|
if (SatipConfig.GetDetachedMode())
|
||||||
|
return false;
|
||||||
if (tsBufferM) {
|
if (tsBufferM) {
|
||||||
#if defined(APIVERSNUM) && APIVERSNUM >= 20104
|
|
||||||
if (cCamSlot *cs = CamSlot()) {
|
if (cCamSlot *cs = CamSlot()) {
|
||||||
if (cs->WantsTsData()) {
|
if (cs->WantsTsData()) {
|
||||||
int available;
|
int available;
|
||||||
@@ -518,7 +517,6 @@ bool cSatipDevice::GetTSPacket(uchar *&dataP)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
dataP = GetData();
|
dataP = GetData();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
128
discover.c
128
discover.c
@@ -47,43 +47,14 @@ void cSatipDiscover::Destroy(void)
|
|||||||
instanceS->Deactivate();
|
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);
|
cSatipDiscover *obj = reinterpret_cast<cSatipDiscover *>(dataP);
|
||||||
size_t len = sizeP * nmembP;
|
size_t len = sizeP * nmembP;
|
||||||
debug16("%s len=%zu", __PRETTY_FUNCTION__, len);
|
debug16("%s len=%zu", __PRETTY_FUNCTION__, len);
|
||||||
|
|
||||||
if (obj) {
|
if (obj && (len > 0))
|
||||||
CURLcode res = CURLE_OK;
|
obj->dataBufferM.Add(ptrP, len);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@@ -120,6 +91,7 @@ int cSatipDiscover::DebugCallback(CURL *handleP, curl_infotype typeP, char *data
|
|||||||
cSatipDiscover::cSatipDiscover()
|
cSatipDiscover::cSatipDiscover()
|
||||||
: cThread("SATIP discover"),
|
: cThread("SATIP discover"),
|
||||||
mutexM(),
|
mutexM(),
|
||||||
|
dataBufferM(),
|
||||||
msearchM(*this),
|
msearchM(*this),
|
||||||
probeUrlListM(),
|
probeUrlListM(),
|
||||||
handleM(curl_easy_init()),
|
handleM(curl_easy_init()),
|
||||||
@@ -170,7 +142,7 @@ void cSatipDiscover::Action(void)
|
|||||||
probeIntervalM.Set(eProbeIntervalMs);
|
probeIntervalM.Set(eProbeIntervalMs);
|
||||||
msearchM.Probe();
|
msearchM.Probe();
|
||||||
mutexM.Lock();
|
mutexM.Lock();
|
||||||
serversM.Cleanup(eProbeIntervalMs * 2);
|
serversM.Cleanup(eCleanupTimeoutMs);
|
||||||
mutexM.Unlock();
|
mutexM.Unlock();
|
||||||
}
|
}
|
||||||
mutexM.Lock();
|
mutexM.Lock();
|
||||||
@@ -195,6 +167,7 @@ void cSatipDiscover::Fetch(const char *urlP)
|
|||||||
{
|
{
|
||||||
debug1("%s (%s)", __PRETTY_FUNCTION__, urlP);
|
debug1("%s (%s)", __PRETTY_FUNCTION__, urlP);
|
||||||
if (handleM && !isempty(urlP)) {
|
if (handleM && !isempty(urlP)) {
|
||||||
|
const char *addr = NULL;
|
||||||
long rc = 0;
|
long rc = 0;
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
|
|
||||||
@@ -204,7 +177,7 @@ void cSatipDiscover::Fetch(const char *urlP)
|
|||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_DEBUGDATA, this);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_DEBUGDATA, this);
|
||||||
|
|
||||||
// Set callback
|
// 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);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
|
||||||
|
|
||||||
// No progress meter and no signaling
|
// No progress meter and no signaling
|
||||||
@@ -224,16 +197,49 @@ void cSatipDiscover::Fetch(const char *urlP)
|
|||||||
// Fetch the data
|
// Fetch the data
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
SATIP_CURL_EASY_PERFORM(handleM);
|
||||||
SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc);
|
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);
|
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)
|
void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char * descP)
|
||||||
{
|
{
|
||||||
debug1("%s (%s, %s, %s)", __PRETTY_FUNCTION__, addrP, modelP, descP);
|
debug1("%s (%s, %s, %s)", __PRETTY_FUNCTION__, addrP, modelP, descP);
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
if (SatipConfig.GetUseSingleModelServers()) {
|
if (SatipConfig.GetUseSingleModelServers() && modelP && !isempty(modelP)) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
char *s, *p = strdup(modelP);
|
char *s, *p = strdup(modelP);
|
||||||
char *r = strtok_r(p, ",", &s);
|
char *r = strtok_r(p, ",", &s);
|
||||||
@@ -242,7 +248,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char
|
|||||||
cString desc = cString::sprintf("%s #%d", !isempty(descP) ? descP : "MyBrokenHardware", n++);
|
cString desc = cString::sprintf("%s #%d", !isempty(descP) ? descP : "MyBrokenHardware", n++);
|
||||||
cSatipServer *tmp = new cSatipServer(addrP, r, desc);
|
cSatipServer *tmp = new cSatipServer(addrP, r, desc);
|
||||||
if (!serversM.Update(tmp)) {
|
if (!serversM.Update(tmp)) {
|
||||||
info("Adding server '%s|%s|%s'", tmp->Address(), tmp->Model(), tmp->Description());
|
info("Adding server '%s|%s|%s' CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
|
||||||
serversM.Add(tmp);
|
serversM.Add(tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -254,7 +260,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char
|
|||||||
else {
|
else {
|
||||||
cSatipServer *tmp = new cSatipServer(addrP, modelP, descP);
|
cSatipServer *tmp = new cSatipServer(addrP, modelP, descP);
|
||||||
if (!serversM.Update(tmp)) {
|
if (!serversM.Update(tmp)) {
|
||||||
info("Adding server '%s|%s|%s'", tmp->Address(), tmp->Model(), tmp->Description());
|
info("Adding server '%s|%s|%s' CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
|
||||||
serversM.Add(tmp);
|
serversM.Add(tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -269,11 +275,18 @@ int cSatipDiscover::GetServerCount(void)
|
|||||||
return serversM.Count();
|
return serversM.Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
cSatipServer *cSatipDiscover::GetServer(int sourceP, int transponderP, int systemP)
|
cSatipServer *cSatipDiscover::AssignServer(int deviceIdP, int sourceP, int transponderP, int systemP)
|
||||||
{
|
{
|
||||||
debug16("%s (%d, %d, %d)", __PRETTY_FUNCTION__, sourceP, transponderP, systemP);
|
debug16("%s (%d, %d, %d, %d)", __PRETTY_FUNCTION__, deviceIdP, sourceP, transponderP, systemP);
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
return serversM.Find(sourceP, transponderP, systemP);
|
return serversM.Assign(deviceIdP, sourceP, transponderP, systemP);
|
||||||
|
}
|
||||||
|
|
||||||
|
cSatipServer *cSatipDiscover::GetServer(int sourceP)
|
||||||
|
{
|
||||||
|
debug16("%s (%d)", __PRETTY_FUNCTION__, sourceP);
|
||||||
|
cMutexLock MutexLock(&mutexM);
|
||||||
|
return serversM.Find(sourceP);
|
||||||
}
|
}
|
||||||
|
|
||||||
cSatipServer *cSatipDiscover::GetServer(cSatipServer *serverP)
|
cSatipServer *cSatipDiscover::GetServer(cSatipServer *serverP)
|
||||||
@@ -304,18 +317,39 @@ cString cSatipDiscover::GetServerList(void)
|
|||||||
return serversM.List();
|
return serversM.List();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipDiscover::SetTransponder(cSatipServer *serverP, int transponderP)
|
void cSatipDiscover::AttachServer(cSatipServer *serverP, int deviceIdP, int transponderP)
|
||||||
{
|
{
|
||||||
debug16("%s (, %d)", __PRETTY_FUNCTION__, transponderP);
|
debug16("%s (, %d, %d)", __PRETTY_FUNCTION__, deviceIdP, transponderP);
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
serversM.SetTransponder(serverP, transponderP);
|
serversM.Attach(serverP, deviceIdP, transponderP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipDiscover::UseServer(cSatipServer *serverP, bool onOffP)
|
void cSatipDiscover::DetachServer(cSatipServer *serverP, int deviceIdP, int transponderP)
|
||||||
{
|
{
|
||||||
debug16("%s (, %d)", __PRETTY_FUNCTION__, onOffP);
|
debug16("%s (, %d, %d)", __PRETTY_FUNCTION__, deviceIdP, transponderP);
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
serversM.Use(serverP, onOffP);
|
serversM.Detach(serverP, deviceIdP, transponderP);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipDiscover::IsServerQuirk(cSatipServer *serverP, int quirkP)
|
||||||
|
{
|
||||||
|
debug16("%s (, %d)", __PRETTY_FUNCTION__, quirkP);
|
||||||
|
cMutexLock MutexLock(&mutexM);
|
||||||
|
return serversM.IsQuirk(serverP, quirkP);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipDiscover::HasServerCI(cSatipServer *serverP)
|
||||||
|
{
|
||||||
|
debug16("%s", __PRETTY_FUNCTION__);
|
||||||
|
cMutexLock MutexLock(&mutexM);
|
||||||
|
return serversM.HasCI(serverP);
|
||||||
|
}
|
||||||
|
|
||||||
|
cString cSatipDiscover::GetServerAddress(cSatipServer *serverP)
|
||||||
|
{
|
||||||
|
debug16("%s", __PRETTY_FUNCTION__);
|
||||||
|
cMutexLock MutexLock(&mutexM);
|
||||||
|
return serversM.GetAddress(serverP);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipDiscover::NumProvidedSystems(void)
|
int cSatipDiscover::NumProvidedSystems(void)
|
||||||
|
24
discover.h
24
discover.h
@@ -13,6 +13,7 @@
|
|||||||
#include <vdr/thread.h>
|
#include <vdr/thread.h>
|
||||||
#include <vdr/tools.h>
|
#include <vdr/tools.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "discoverif.h"
|
#include "discoverif.h"
|
||||||
#include "msearch.h"
|
#include "msearch.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
@@ -39,15 +40,17 @@ class cSatipDiscoverServers : public cList<cSatipDiscoverServer> {
|
|||||||
class cSatipDiscover : public cThread, public cSatipDiscoverIf {
|
class cSatipDiscover : public cThread, public cSatipDiscoverIf {
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
eSleepTimeoutMs = 500, // in milliseconds
|
eSleepTimeoutMs = 500, // in milliseconds
|
||||||
eConnectTimeoutMs = 1500, // in milliseconds
|
eConnectTimeoutMs = 1500, // in milliseconds
|
||||||
eProbeTimeoutMs = 2000, // in milliseconds
|
eProbeTimeoutMs = 2000, // in milliseconds
|
||||||
eProbeIntervalMs = 60000 // in milliseconds
|
eProbeIntervalMs = 60000, // in milliseconds
|
||||||
|
eCleanupTimeoutMs = 124000 // in milliseoonds
|
||||||
};
|
};
|
||||||
static cSatipDiscover *instanceS;
|
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);
|
static int DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP);
|
||||||
cMutex mutexM;
|
cMutex mutexM;
|
||||||
|
cSatipMemoryBuffer dataBufferM;
|
||||||
cSatipMsearch msearchM;
|
cSatipMsearch msearchM;
|
||||||
cStringList probeUrlListM;
|
cStringList probeUrlListM;
|
||||||
CURL *handleM;
|
CURL *handleM;
|
||||||
@@ -56,6 +59,7 @@ private:
|
|||||||
cSatipServers serversM;
|
cSatipServers serversM;
|
||||||
void Activate(void);
|
void Activate(void);
|
||||||
void Deactivate(void);
|
void Deactivate(void);
|
||||||
|
void ParseDeviceInfo(const char *addrP);
|
||||||
void AddServer(const char *addrP, const char *modelP, const char *descP);
|
void AddServer(const char *addrP, const char *modelP, const char *descP);
|
||||||
void Fetch(const char *urlP);
|
void Fetch(const char *urlP);
|
||||||
// constructor
|
// constructor
|
||||||
@@ -74,12 +78,16 @@ public:
|
|||||||
virtual ~cSatipDiscover();
|
virtual ~cSatipDiscover();
|
||||||
void TriggerScan(void) { probeIntervalM.Set(0); }
|
void TriggerScan(void) { probeIntervalM.Set(0); }
|
||||||
int GetServerCount(void);
|
int GetServerCount(void);
|
||||||
cSatipServer *GetServer(int sourceP, int transponderP = 0, int systemP = -1);
|
cSatipServer *AssignServer(int deviceIdP, int sourceP, int transponderP, int systemP);
|
||||||
|
cSatipServer *GetServer(int sourceP);
|
||||||
cSatipServer *GetServer(cSatipServer *serverP);
|
cSatipServer *GetServer(cSatipServer *serverP);
|
||||||
cSatipServers *GetServers(void);
|
cSatipServers *GetServers(void);
|
||||||
cString GetServerString(cSatipServer *serverP);
|
cString GetServerString(cSatipServer *serverP);
|
||||||
void SetTransponder(cSatipServer *serverP, int transponderP);
|
void AttachServer(cSatipServer *serverP, int deviceIdP, int transponderP);
|
||||||
void UseServer(cSatipServer *serverP, bool onOffP);
|
void DetachServer(cSatipServer *serverP, int deviceIdP, int transponderP);
|
||||||
|
bool IsServerQuirk(cSatipServer *serverP, int quirkP);
|
||||||
|
bool HasServerCI(cSatipServer *serverP);
|
||||||
|
cString GetServerAddress(cSatipServer *serverP);
|
||||||
cString GetServerList(void);
|
cString GetServerList(void);
|
||||||
int NumProvidedSystems(void);
|
int NumProvidedSystems(void);
|
||||||
|
|
||||||
|
5
log.h
5
log.h
@@ -34,9 +34,9 @@
|
|||||||
#define debug10(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug10) ? dsyslog("SATIP10: " x) : void() )
|
#define debug10(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug10) ? dsyslog("SATIP10: " x) : void() )
|
||||||
// 0x0400: CI
|
// 0x0400: CI
|
||||||
#define debug11(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug11) ? dsyslog("SATIP11: " x) : void() )
|
#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() )
|
#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() )
|
#define debug13(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug13) ? dsyslog("SATIP13: " x) : void() )
|
||||||
// 0x2000: TBD
|
// 0x2000: TBD
|
||||||
#define debug14(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug14) ? dsyslog("SATIP14: " x) : void() )
|
#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() )
|
#define debug16(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug16) ? dsyslog("SATIP16: " x) : void() )
|
||||||
|
|
||||||
#endif // __SATIP_LOG_H
|
#endif // __SATIP_LOG_H
|
||||||
|
|
||||||
|
10
msearch.c
10
msearch.c
@@ -35,6 +35,7 @@ cSatipMsearch::cSatipMsearch(cSatipDiscoverIf &discoverP)
|
|||||||
|
|
||||||
cSatipMsearch::~cSatipMsearch()
|
cSatipMsearch::~cSatipMsearch()
|
||||||
{
|
{
|
||||||
|
FREE_POINTER(bufferM);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipMsearch::Probe(void)
|
void cSatipMsearch::Probe(void)
|
||||||
@@ -44,6 +45,9 @@ void cSatipMsearch::Probe(void)
|
|||||||
cSatipPoller::GetInstance()->Register(*this);
|
cSatipPoller::GetInstance()->Register(*this);
|
||||||
registeredM = true;
|
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));
|
Write(bcastAddressS, reinterpret_cast<const unsigned char *>(bcastMessageS), strlen(bcastMessageS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,12 +63,12 @@ void cSatipMsearch::Process(void)
|
|||||||
int length;
|
int length;
|
||||||
while ((length = Read(bufferM, bufferLenM)) > 0) {
|
while ((length = Read(bufferM, bufferLenM)) > 0) {
|
||||||
bufferM[min(length, int(bufferLenM - 1))] = 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;
|
bool status = false, valid = false;
|
||||||
char *s, *p = reinterpret_cast<char *>(bufferM), *location = NULL;
|
char *s, *p = reinterpret_cast<char *>(bufferM), *location = NULL;
|
||||||
char *r = strtok_r(p, "\r\n", &s);
|
char *r = strtok_r(p, "\r\n", &s);
|
||||||
while (r) {
|
while (r) {
|
||||||
debug12("%s r=%s", __PRETTY_FUNCTION__, r);
|
debug13("%s r=%s", __PRETTY_FUNCTION__, r);
|
||||||
// Check the status code
|
// Check the status code
|
||||||
// HTTP/1.1 200 OK
|
// HTTP/1.1 200 OK
|
||||||
if (!status && startswith(r, "HTTP/1.1 200 OK"))
|
if (!status && startswith(r, "HTTP/1.1 200 OK"))
|
||||||
@@ -93,8 +97,6 @@ void cSatipMsearch::Process(void)
|
|||||||
r = strtok_r(NULL, "\r\n", &s);
|
r = strtok_r(NULL, "\r\n", &s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
|
||||||
error("Error %d reading in %s", errno, *ToString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
param.c
26
param.c
@@ -147,15 +147,6 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
|
|||||||
cDvbTransponderParameters dtp(channelP->Parameters());
|
cDvbTransponderParameters dtp(channelP->Parameters());
|
||||||
int DataSlice = 0;
|
int DataSlice = 0;
|
||||||
int C2TuningFrequencyType = 0;
|
int C2TuningFrequencyType = 0;
|
||||||
#if defined(APIVERSNUM) && APIVERSNUM < 20106
|
|
||||||
int Pilot = PILOT_AUTO;
|
|
||||||
int T2SystemId = 0;
|
|
||||||
int SisoMiso = 0;
|
|
||||||
#else
|
|
||||||
int Pilot = dtp.Pilot();
|
|
||||||
int T2SystemId = dtp.T2SystemId();
|
|
||||||
int SisoMiso = dtp.SisoMiso();
|
|
||||||
#endif
|
|
||||||
float freq = channelP->Frequency();
|
float freq = channelP->Frequency();
|
||||||
char type = cSource::ToChar(channelP->Source());
|
char type = cSource::ToChar(channelP->Source());
|
||||||
cSource *source = Sources.Get(channelP->Source());
|
cSource *source = Sources.Get(channelP->Source());
|
||||||
@@ -167,32 +158,37 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
|
|||||||
freq /= 1000L;
|
freq /= 1000L;
|
||||||
#define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*')))
|
#define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*')))
|
||||||
#define STBUFLEFT (sizeof(buffer) - (q - buffer))
|
#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"));
|
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, "&src=%d", ((src > 0) && (src <= 255)) ? src : 1);
|
||||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
ST(" S *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
||||||
ST("C 1") 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(" S *") q += snprintf(q, STBUFLEFT, "&pol=%c", tolower(dtp.Polarization()));
|
||||||
ST("C T2") q += snprintf(q, STBUFLEFT, "&plp=%d", dtp.StreamId());
|
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, "&c2tft=%d", C2TuningFrequencyType);
|
||||||
ST("C 2") q += snprintf(q, STBUFLEFT, "&ds=%d", DataSlice);
|
ST("C 2") q += snprintf(q, STBUFLEFT, "&ds=%d", DataSlice);
|
||||||
ST("C 1") q += PrintUrlString(q, STBUFLEFT, dtp.Inversion(), SatipInversionValues);
|
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(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Bandwidth(), SatipBandwidthValues);
|
||||||
ST("C 2") 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(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Guard(), SatipGuardValues);
|
||||||
ST("CST*") q += PrintUrlString(q, STBUFLEFT, dtp.CoderateH(), SatipCodeRateValues);
|
ST("CST*") q += PrintUrlString(q, STBUFLEFT, dtp.CoderateH(), SatipCodeRateValues);
|
||||||
ST(" S 2") q += PrintUrlString(q, STBUFLEFT, Pilot, SatipPilotValues);
|
ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Pilot(), SatipPilotValues);
|
||||||
ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
||||||
ST(" T*") 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("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(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesSat);
|
||||||
ST("C *") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesCable);
|
ST("C *") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesCable);
|
||||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesTerrestrial);
|
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesTerrestrial);
|
||||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Transmission(), SatipTransmissionValues);
|
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Transmission(), SatipTransmissionValues);
|
||||||
if ((channelP->Rid() % 100) > 0)
|
if ((channelP->Rid() % 100) > 0)
|
||||||
q += snprintf(q, STBUFLEFT, "&fe=%d", channelP->Rid() % 100);
|
snprintf(q, STBUFLEFT, "&fe=%d", channelP->Rid() % 100);
|
||||||
#undef ST
|
#undef ST
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@@ -5,10 +5,10 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 1.0.2\n"
|
"Project-Id-Version: vdr-satip 2.2.2\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
|
"POT-Creation-Date: 2015-04-26 04:26+0300\n"
|
||||||
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
|
"PO-Revision-Date: 2015-04-26 04:26+0300\n"
|
||||||
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
||||||
"Language-Team: Catalan <vdr@linuxtv.org>\n"
|
"Language-Team: Catalan <vdr@linuxtv.org>\n"
|
||||||
"Language: ca\n"
|
"Language: ca\n"
|
||||||
|
@@ -5,10 +5,10 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 1.0.2\n"
|
"Project-Id-Version: vdr-satip 2.2.2\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
|
"POT-Creation-Date: 2015-04-26 04:26+0300\n"
|
||||||
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
|
"PO-Revision-Date: 2015-04-26 04:26+0300\n"
|
||||||
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
|
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
|
||||||
"Language-Team: German <vdr@linuxtv.org>\n"
|
"Language-Team: German <vdr@linuxtv.org>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
|
@@ -5,10 +5,10 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 1.0.2\n"
|
"Project-Id-Version: vdr-satip 2.2.2\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
|
"POT-Creation-Date: 2015-04-26 04:26+0300\n"
|
||||||
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
|
"PO-Revision-Date: 2015-04-26 04:26+0300\n"
|
||||||
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
||||||
"Language-Team: Spanish <vdr@linuxtv.org>\n"
|
"Language-Team: Spanish <vdr@linuxtv.org>\n"
|
||||||
"Language: es\n"
|
"Language: es\n"
|
||||||
|
@@ -5,10 +5,10 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 1.0.2\n"
|
"Project-Id-Version: vdr-satip 2.2.2\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
|
"POT-Creation-Date: 2015-04-26 04:26+0300\n"
|
||||||
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
|
"PO-Revision-Date: 2015-04-26 04:26+0300\n"
|
||||||
"Last-Translator: Rolf Ahrenberg\n"
|
"Last-Translator: Rolf Ahrenberg\n"
|
||||||
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
||||||
"Language: fi\n"
|
"Language: fi\n"
|
||||||
|
4
rtcp.c
4
rtcp.c
@@ -25,7 +25,7 @@ cSatipRtcp::cSatipRtcp(cSatipTunerIf &tunerP)
|
|||||||
cSatipRtcp::~cSatipRtcp()
|
cSatipRtcp::~cSatipRtcp()
|
||||||
{
|
{
|
||||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
||||||
DELETE_POINTER(bufferM);
|
FREE_POINTER(bufferM);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipRtcp::GetFd(void)
|
int cSatipRtcp::GetFd(void)
|
||||||
@@ -89,8 +89,6 @@ void cSatipRtcp::Process(void)
|
|||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
tunerM.ProcessApplicationData(bufferM + offset, length);
|
tunerM.ProcessApplicationData(bufferM + offset, length);
|
||||||
}
|
}
|
||||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
|
||||||
error("Error %d reading in %s", errno, *ToString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
rtp.c
5
rtp.c
@@ -29,7 +29,7 @@ cSatipRtp::cSatipRtp(cSatipTunerIf &tunerP)
|
|||||||
cSatipRtp::~cSatipRtp()
|
cSatipRtp::~cSatipRtp()
|
||||||
{
|
{
|
||||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
||||||
DELETE_POINTER(bufferM);
|
FREE_POINTER(bufferM);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipRtp::GetFd(void)
|
int cSatipRtp::GetFd(void)
|
||||||
@@ -136,9 +136,6 @@ void cSatipRtp::Process(void)
|
|||||||
}
|
}
|
||||||
} while (count >= eRtpPacketReadCount);
|
} while (count >= eRtpPacketReadCount);
|
||||||
|
|
||||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
|
||||||
error("Error %d reading in %s [device %d]", errno, *ToString(), tunerM.GetId());
|
|
||||||
|
|
||||||
elapsed = processing.Elapsed();
|
elapsed = processing.Elapsed();
|
||||||
if (elapsed > 1)
|
if (elapsed > 1)
|
||||||
debug6("%s %d read(s) took %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, count, elapsed, tunerM.GetId());
|
debug6("%s %d read(s) took %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, count, elapsed, tunerM.GetId());
|
||||||
|
201
rtsp.c
201
rtsp.c
@@ -15,9 +15,14 @@
|
|||||||
|
|
||||||
cSatipRtsp::cSatipRtsp(cSatipTunerIf &tunerP)
|
cSatipRtsp::cSatipRtsp(cSatipTunerIf &tunerP)
|
||||||
: tunerM(tunerP),
|
: tunerM(tunerP),
|
||||||
|
headerBufferM(),
|
||||||
|
dataBufferM(),
|
||||||
modeM(cmUnicast),
|
modeM(cmUnicast),
|
||||||
handleM(NULL),
|
handleM(NULL),
|
||||||
headerListM(NULL)
|
headerListM(NULL),
|
||||||
|
errorNoMoreM(""),
|
||||||
|
errorOutOfRangeM(""),
|
||||||
|
errorCheckSyntaxM("")
|
||||||
{
|
{
|
||||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
||||||
Create();
|
Create();
|
||||||
@@ -29,46 +34,26 @@ cSatipRtsp::~cSatipRtsp()
|
|||||||
Destroy();
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t cSatipRtsp::WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP)
|
|
||||||
{
|
{
|
||||||
cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(dataP);
|
cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(dataP);
|
||||||
size_t len = sizeP * nmembP;
|
size_t len = sizeP * nmembP;
|
||||||
debug16("%s len=%zu", __PRETTY_FUNCTION__, len);
|
debug16("%s len=%zu", __PRETTY_FUNCTION__, len);
|
||||||
|
|
||||||
if (obj && (len > 0))
|
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;
|
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
|
// Set header callback for catching the session and timeout
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, cSatipRtsp::HeaderCallback);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, cSatipRtsp::HeaderCallback);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this);
|
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);
|
SATIP_CURL_EASY_PERFORM(handleM);
|
||||||
// Session id is now known - disable header parsing
|
// Session id is now known - disable header parsing
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, NULL);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, NULL);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, 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);
|
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());
|
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_STREAM_URI, uriP);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_DESCRIBE);
|
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_SETOPT(handleM, CURLOPT_WRITEDATA, this);
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
SATIP_CURL_EASY_PERFORM(handleM);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, 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);
|
result = ValidateLatestResponse(&rc);
|
||||||
debug5("%s (%s) Response %ld in %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, uriP, rc, processing.Elapsed(), tunerM.GetId());
|
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_STREAM_URI, uriP);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
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_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);
|
result = ValidateLatestResponse(&rc);
|
||||||
debug5("%s (%s) Response %ld in %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, uriP, rc, processing.Elapsed(), tunerM.GetId());
|
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_STREAM_URI, uriP);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN);
|
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_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_CLIENT_CSEQ, 1L);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, NULL);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, NULL);
|
||||||
@@ -311,24 +328,122 @@ bool cSatipRtsp::Teardown(const char *uriP)
|
|||||||
return result;
|
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 cSatipRtsp::ValidateLatestResponse(long *rcP)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if (handleM) {
|
if (handleM) {
|
||||||
|
char *url = NULL;
|
||||||
long rc = 0;
|
long rc = 0;
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc);
|
SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc);
|
||||||
if (rc == 200)
|
switch (rc) {
|
||||||
result = true;
|
case 200:
|
||||||
else if (rc != 0) {
|
result = true;
|
||||||
char *url = NULL;
|
break;
|
||||||
SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url);
|
case 400:
|
||||||
error("Detected invalid status code %ld: %s [device %d]", rc, url, tunerM.GetId());
|
// 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)
|
if (rcP)
|
||||||
*rcP = rc;
|
*rcP = rc;
|
||||||
}
|
}
|
||||||
|
errorNoMoreM = "";
|
||||||
|
errorOutOfRangeM = "";
|
||||||
|
errorCheckSyntaxM = "";
|
||||||
debug1("%s result=%s [device %d]", __PRETTY_FUNCTION__, result ? "ok" : "failed", tunerM.GetId());
|
debug1("%s result=%s [device %d]", __PRETTY_FUNCTION__, result ? "ok" : "failed", tunerM.GetId());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
12
rtsp.h
12
rtsp.h
@@ -15,12 +15,13 @@
|
|||||||
#error "libcurl is missing required RTSP support"
|
#error "libcurl is missing required RTSP support"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "tunerif.h"
|
#include "tunerif.h"
|
||||||
|
|
||||||
class cSatipRtsp {
|
class cSatipRtsp {
|
||||||
private:
|
private:
|
||||||
static size_t HeaderCallback(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 WriteCallback(void *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);
|
static int DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -29,12 +30,19 @@ private:
|
|||||||
enum eCommunicationMode { cmUnicast, cmMulticast };
|
enum eCommunicationMode { cmUnicast, cmMulticast };
|
||||||
|
|
||||||
cSatipTunerIf &tunerM;
|
cSatipTunerIf &tunerM;
|
||||||
|
cSatipMemoryBuffer headerBufferM;
|
||||||
|
cSatipMemoryBuffer dataBufferM;
|
||||||
eCommunicationMode modeM;
|
eCommunicationMode modeM;
|
||||||
CURL *handleM;
|
CURL *handleM;
|
||||||
struct curl_slist *headerListM;
|
struct curl_slist *headerListM;
|
||||||
|
cString errorNoMoreM;
|
||||||
|
cString errorOutOfRangeM;
|
||||||
|
cString errorCheckSyntaxM;
|
||||||
|
|
||||||
void Create(void);
|
void Create(void);
|
||||||
void Destroy(void);
|
void Destroy(void);
|
||||||
|
void ParseHeader(void);
|
||||||
|
void ParseData(void);
|
||||||
bool ValidateLatestResponse(long *rcP);
|
bool ValidateLatestResponse(long *rcP);
|
||||||
|
|
||||||
// to prevent copy constructor and assignment
|
// to prevent copy constructor and assignment
|
||||||
|
50
satip.c
50
satip.c
@@ -19,15 +19,15 @@
|
|||||||
#warning "CURL version >= 7.36.0 is recommended"
|
#warning "CURL version >= 7.36.0 is recommended"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(APIVERSNUM) && APIVERSNUM < 20000
|
#if defined(APIVERSNUM) && APIVERSNUM < 20200
|
||||||
#error "VDR-2.0.0 API version or greater is required!"
|
#error "VDR-2.2.0 API version or greater is required!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GITVERSION
|
#ifndef GITVERSION
|
||||||
#define GITVERSION ""
|
#define GITVERSION ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char VERSION[] = "1.0.2" GITVERSION;
|
const char VERSION[] = "2.2.2" GITVERSION;
|
||||||
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
||||||
|
|
||||||
class cPluginSatip : public cPlugin {
|
class cPluginSatip : public cPlugin {
|
||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
cPluginSatip::cPluginSatip(void)
|
cPluginSatip::cPluginSatip(void)
|
||||||
: deviceCountM(1),
|
: deviceCountM(2),
|
||||||
serversM(NULL)
|
serversM(NULL)
|
||||||
{
|
{
|
||||||
debug16("%s", __PRETTY_FUNCTION__);
|
debug16("%s", __PRETTY_FUNCTION__);
|
||||||
@@ -84,7 +84,8 @@ const char *cPluginSatip::CommandLineHelp(void)
|
|||||||
return " -d <num>, --devices=<number> set number of devices to be created\n"
|
return " -d <num>, --devices=<number> set number of devices to be created\n"
|
||||||
" -t <mode>, --trace=<mode> set the tracing mode\n"
|
" -t <mode>, --trace=<mode> set the tracing mode\n"
|
||||||
" -s <ipaddr>|<model>|<desc>, --server=<ipaddr1>|<model1>|<desc1>;<ipaddr2>|<model2>|<desc2>\n"
|
" -s <ipaddr>|<model>|<desc>, --server=<ipaddr1>|<model1>|<desc1>;<ipaddr2>|<model2>|<desc2>\n"
|
||||||
" define hard-coded SAT>IP server(s)"
|
" 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"
|
" -S, --single set the single model server mode on\n"
|
||||||
" -n, --noquirks disable all the server quirks\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' },
|
{ "devices", required_argument, NULL, 'd' },
|
||||||
{ "trace", required_argument, NULL, 't' },
|
{ "trace", required_argument, NULL, 't' },
|
||||||
{ "server", required_argument, NULL, 's' },
|
{ "server", required_argument, NULL, 's' },
|
||||||
|
{ "detach", no_argument, NULL, 'D' },
|
||||||
{ "single", no_argument, NULL, 'S' },
|
{ "single", no_argument, NULL, 'S' },
|
||||||
{ "noquirks", no_argument, NULL, 'n' },
|
{ "noquirks", no_argument, NULL, 'n' },
|
||||||
{ NULL, no_argument, NULL, 0 }
|
{ NULL, no_argument, NULL, 0 }
|
||||||
@@ -104,7 +106,7 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
|||||||
|
|
||||||
cString server;
|
cString server;
|
||||||
int c;
|
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) {
|
switch (c) {
|
||||||
case 'd':
|
case 'd':
|
||||||
deviceCountM = strtol(optarg, NULL, 0);
|
deviceCountM = strtol(optarg, NULL, 0);
|
||||||
@@ -115,6 +117,9 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
|||||||
case 's':
|
case 's':
|
||||||
server = optarg;
|
server = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
SatipConfig.SetDetachedMode(true);
|
||||||
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
SatipConfig.SetUseSingleModelServers(true);
|
SatipConfig.SetUseSingleModelServers(true);
|
||||||
break;
|
break;
|
||||||
@@ -366,8 +371,12 @@ const char **cPluginSatip::SVDRPHelpPages(void)
|
|||||||
" Lists status information of SAT>IP devices.\n",
|
" Lists status information of SAT>IP devices.\n",
|
||||||
"CONT\n"
|
"CONT\n"
|
||||||
" Shows SAT>IP device count.\n",
|
" Shows SAT>IP device count.\n",
|
||||||
"OPER\n"
|
"OPER [ off | low | normal | high ]\n"
|
||||||
" Toggles operating mode of SAT>IP devices.\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"
|
"TRAC [ <mode> ]\n"
|
||||||
" Gets and/or sets used tracing mode.\n",
|
" Gets and/or sets used tracing mode.\n",
|
||||||
NULL
|
NULL
|
||||||
@@ -434,8 +443,19 @@ cString cPluginSatip::SVDRPCommand(const char *commandP, const char *optionP, in
|
|||||||
}
|
}
|
||||||
else if (strcasecmp(commandP, "OPER") == 0) {
|
else if (strcasecmp(commandP, "OPER") == 0) {
|
||||||
cString mode;
|
cString mode;
|
||||||
SatipConfig.ToggleOperatingMode();
|
unsigned int oper = SatipConfig.GetOperatingMode();
|
||||||
switch (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:
|
case cSatipConfig::eOperatingModeOff:
|
||||||
mode = "off";
|
mode = "off";
|
||||||
break;
|
break;
|
||||||
@@ -454,6 +474,16 @@ cString cPluginSatip::SVDRPCommand(const char *commandP, const char *optionP, in
|
|||||||
}
|
}
|
||||||
return cString::sprintf("SATIP operating mode: %s\n", *mode);
|
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) {
|
else if (strcasecmp(commandP, "TRAC") == 0) {
|
||||||
if (optionP && *optionP)
|
if (optionP && *optionP)
|
||||||
SatipConfig.SetTraceMode(strtol(optionP, NULL, 0));
|
SatipConfig.SetTraceMode(strtol(optionP, NULL, 0));
|
||||||
|
342
server.c
342
server.c
@@ -12,73 +12,140 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
|
// --- cSatipFrontend ---------------------------------------------------------
|
||||||
|
|
||||||
|
cSatipFrontend::cSatipFrontend(const int indexP, const char *descriptionP)
|
||||||
|
: indexM(indexP),
|
||||||
|
transponderM(0),
|
||||||
|
deviceIdM(-1),
|
||||||
|
descriptionM(descriptionP)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cSatipFrontend::~cSatipFrontend()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSatipFrontends --------------------------------------------------------
|
||||||
|
|
||||||
|
bool cSatipFrontends::Matches(int deviceIdP, int transponderP)
|
||||||
|
{
|
||||||
|
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||||
|
if (f->Attached() && (f->DeviceId() == deviceIdP) && (f->Transponder() == transponderP))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipFrontends::Assign(int deviceIdP, int transponderP)
|
||||||
|
{
|
||||||
|
cSatipFrontend *tmp = NULL;
|
||||||
|
// Prefer any unused one
|
||||||
|
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||||
|
if (!f->Attached() || (f->DeviceId() == deviceIdP)) {
|
||||||
|
tmp = f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tmp) {
|
||||||
|
tmp->SetTransponder(transponderP);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipFrontends::Attach(int deviceIdP, int transponderP)
|
||||||
|
{
|
||||||
|
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||||
|
if (f->Transponder() == transponderP) {
|
||||||
|
f->Attach(deviceIdP);
|
||||||
|
debug9("%s (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipFrontends::Detach(int deviceIdP, int transponderP)
|
||||||
|
{
|
||||||
|
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||||
|
if (f->Transponder() == transponderP) {
|
||||||
|
f->Detach(deviceIdP);
|
||||||
|
debug9("%s (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cSatipServer -----------------------------------------------------------
|
// --- cSatipServer -----------------------------------------------------------
|
||||||
|
|
||||||
cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char *descriptionP)
|
cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char *descriptionP)
|
||||||
: addressM((addressP && *addressP) ? addressP : "0.0.0.0"),
|
: addressM((addressP && *addressP) ? addressP : "0.0.0.0"),
|
||||||
modelM((modelP && *modelP) ? modelP : "DVBS-1"),
|
modelM((modelP && *modelP) ? modelP : "DVBS-1"),
|
||||||
descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"),
|
descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"),
|
||||||
modelTypeM(eSatipModelTypeNone),
|
quirksM(""),
|
||||||
quirkM(eSatipQuirkNone),
|
quirkM(eSatipQuirkNone),
|
||||||
useCountM(0),
|
hasCiM(false),
|
||||||
transponderM(0),
|
|
||||||
createdM(time(NULL)),
|
createdM(time(NULL)),
|
||||||
lastSeenM(0)
|
lastSeenM(0)
|
||||||
{
|
{
|
||||||
memset(modelCountM, 0, sizeof(modelCountM));
|
|
||||||
if (!SatipConfig.GetDisableServerQuirks()) {
|
if (!SatipConfig.GetDisableServerQuirks()) {
|
||||||
debug3("%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM);
|
|
||||||
// These devices contain a session id bug:
|
// These devices contain a session id bug:
|
||||||
// Inverto Airscreen Server IDL 400 ?
|
// Inverto Airscreen Server IDL 400 ?
|
||||||
// Elgato EyeTV Netstream 4Sat ?
|
// Elgato EyeTV Netstream 4Sat ?
|
||||||
if (strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400
|
if (strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400
|
||||||
strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1
|
strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1
|
||||||
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
||||||
)
|
) {
|
||||||
quirkM |= eSatipQuirkSessionId;
|
quirkM |= eSatipQuirkSessionId;
|
||||||
|
quirksM = cString::sprintf("%s%sSessionId", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
|
}
|
||||||
// These devices contain a play (add/delpids) parameter bug:
|
// These devices contain a play (add/delpids) parameter bug:
|
||||||
if (strstr(*descriptionM, "fritzdvbc")) // Fritz!WLAN Repeater DVB-C
|
if (strstr(*descriptionM, "fritzdvbc") // Fritz!WLAN Repeater DVB-C
|
||||||
|
) {
|
||||||
quirkM |= eSatipQuirkPlayPids;
|
quirkM |= eSatipQuirkPlayPids;
|
||||||
|
quirksM = cString::sprintf("%s%sPlayPids", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
|
}
|
||||||
// These devices contain a frontend locking bug:
|
// These devices contain a frontend locking bug:
|
||||||
if (strstr(*descriptionM, "fritzdvbc")) // Fritz!WLAN Repeater DVB-C
|
if (strstr(*descriptionM, "fritzdvbc") // Fritz!WLAN Repeater DVB-C
|
||||||
|
) {
|
||||||
quirkM |= eSatipQuirkForceLock;
|
quirkM |= eSatipQuirkForceLock;
|
||||||
if (quirkM != eSatipQuirkNone)
|
quirksM = cString::sprintf("%s%sForceLock", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
info("Malfunctioning '%s' server detected! Please, fix the firmware.", *descriptionM);
|
}
|
||||||
|
debug3("%s description=%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM, *quirksM);
|
||||||
}
|
}
|
||||||
// These devices support the X_PMT protocol extension
|
// These devices support the X_PMT protocol extension
|
||||||
if (strstr(*descriptionM, "OctopusNet")) // Digital Devices OctopusNet
|
if (strstr(*descriptionM, "OctopusNet")) // Digital Devices OctopusNet
|
||||||
quirkM |= eSatipQuirkUseXCI;
|
hasCiM = true;
|
||||||
char *s, *p = strdup(*modelM);
|
char *s, *p = strdup(*modelM);
|
||||||
char *r = strtok_r(p, ",", &s);
|
char *r = strtok_r(p, ",", &s);
|
||||||
while (r) {
|
while (r) {
|
||||||
if (strstr(r, "DVBS2-")) {
|
char *c;
|
||||||
modelTypeM |= eSatipModelTypeDVBS2;
|
if (c = strstr(r, "DVBS2-")) {
|
||||||
if (char *c = strstr(r, "-"))
|
int count = atoi(c + 6);
|
||||||
modelCountM[eSatipModuleDVBS2] = atoi(++c);
|
for (int i = 1; i <= count; ++i)
|
||||||
|
frontendsM[eSatipFrontendDVBS2].Add(new cSatipFrontend(i, "DVB-S2"));
|
||||||
}
|
}
|
||||||
else if (strstr(r, "DVBT2-")) {
|
else if (c = strstr(r, "DVBT-")) {
|
||||||
modelTypeM |= eSatipModelTypeDVBT2;
|
int count = atoi(c + 5);
|
||||||
if (char *c = strstr(r, "-"))
|
for (int i = 1; i <= count; ++i)
|
||||||
modelCountM[eSatipModuleDVBT2] = atoi(++c);
|
frontendsM[eSatipFrontendDVBT].Add(new cSatipFrontend(i, "DVB-T"));
|
||||||
modelTypeM |= eSatipModelTypeDVBT;
|
|
||||||
modelCountM[eSatipModuleDVBT] = modelCountM[eSatipModuleDVBT2];
|
|
||||||
}
|
}
|
||||||
else if (strstr(r, "DVBT-")) {
|
else if (c = strstr(r, "DVBT2-")) {
|
||||||
modelTypeM |= eSatipModelTypeDVBT;
|
int count = atoi(c + 6);
|
||||||
if (char *c = strstr(r, "-"))
|
for (int i = 1; i <= count; ++i)
|
||||||
modelCountM[eSatipModuleDVBT] = atoi(++c);
|
frontendsM[eSatipFrontendDVBT2].Add(new cSatipFrontend(i, "DVB-T2"));
|
||||||
}
|
}
|
||||||
else if (strstr(r, "DVBC2-")) {
|
else if (c = strstr(r, "DVBC-")) {
|
||||||
modelTypeM |= eSatipModelTypeDVBC2;
|
int count = atoi(c + 5);
|
||||||
if (char *c = strstr(r, "-"))
|
for (int i = 1; i <= count; ++i)
|
||||||
modelCountM[eSatipModuleDVBC2] = atoi(++c);
|
frontendsM[eSatipFrontendDVBC].Add(new cSatipFrontend(i, "DVB-C"));
|
||||||
modelTypeM |= eSatipModelTypeDVBC;
|
|
||||||
modelCountM[eSatipModuleDVBC] = modelCountM[eSatipModuleDVBC2];
|
|
||||||
}
|
}
|
||||||
else if (strstr(r, "DVBC-")) {
|
else if (c = strstr(r, "DVBC2-")) {
|
||||||
modelTypeM |= eSatipModelTypeDVBC;
|
int count = atoi(c + 6);
|
||||||
if (char *c = strstr(r, "-"))
|
for (int i = 1; i <= count; ++i)
|
||||||
modelCountM[eSatipModuleDVBC] = atoi(++c);
|
frontendsM[eSatipFrontendDVBC2].Add(new cSatipFrontend(i, "DVB-C2"));
|
||||||
}
|
}
|
||||||
r = strtok_r(NULL, ",", &s);
|
r = strtok_r(NULL, ",", &s);
|
||||||
}
|
}
|
||||||
@@ -101,12 +168,96 @@ int cSatipServer::Compare(const cListObject &listObjectP) const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipServer::Use(bool onOffP)
|
bool cSatipServer::Assign(int deviceIdP, int sourceP, int systemP, int transponderP)
|
||||||
{
|
{
|
||||||
if (onOffP)
|
bool result = false;
|
||||||
++useCountM;
|
if (cSource::IsType(sourceP, 'S'))
|
||||||
else
|
result = frontendsM[eSatipFrontendDVBS2].Assign(deviceIdP, transponderP);
|
||||||
--useCountM;
|
else if (cSource::IsType(sourceP, 'T')) {
|
||||||
|
if (systemP)
|
||||||
|
result = frontendsM[eSatipFrontendDVBT2].Assign(deviceIdP, transponderP);
|
||||||
|
else
|
||||||
|
result = frontendsM[eSatipFrontendDVBT].Assign(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBT2].Assign(deviceIdP, transponderP);
|
||||||
|
}
|
||||||
|
else if (cSource::IsType(sourceP, 'C')) {
|
||||||
|
if (systemP)
|
||||||
|
result = frontendsM[eSatipFrontendDVBC2].Assign(deviceIdP, transponderP);
|
||||||
|
else
|
||||||
|
result = frontendsM[eSatipFrontendDVBC].Assign(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Assign(deviceIdP, transponderP);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipServer::Matches(int sourceP)
|
||||||
|
{
|
||||||
|
if (cSource::IsType(sourceP, 'S'))
|
||||||
|
return GetModulesDVBS2();
|
||||||
|
else if (cSource::IsType(sourceP, 'T'))
|
||||||
|
return GetModulesDVBT() || GetModulesDVBT2();
|
||||||
|
else if (cSource::IsType(sourceP, 'C'))
|
||||||
|
return GetModulesDVBC() || GetModulesDVBC2();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipServer::Matches(int deviceIdP, int sourceP, int systemP, int transponderP)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (cSource::IsType(sourceP, 'S'))
|
||||||
|
result = frontendsM[eSatipFrontendDVBS2].Matches(deviceIdP, transponderP);
|
||||||
|
else if (cSource::IsType(sourceP, 'T')) {
|
||||||
|
if (systemP)
|
||||||
|
result = frontendsM[eSatipFrontendDVBT2].Matches(deviceIdP, transponderP);
|
||||||
|
else
|
||||||
|
result = frontendsM[eSatipFrontendDVBT].Matches(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBT2].Matches(deviceIdP, transponderP);
|
||||||
|
}
|
||||||
|
else if (cSource::IsType(sourceP, 'C')) {
|
||||||
|
if (systemP)
|
||||||
|
result = frontendsM[eSatipFrontendDVBC2].Matches(deviceIdP, transponderP);
|
||||||
|
else
|
||||||
|
result = frontendsM[eSatipFrontendDVBC].Matches(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Matches(deviceIdP, transponderP);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSatipServer::Attach(int deviceIdP, int transponderP)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < eSatipFrontendCount; ++i) {
|
||||||
|
if (frontendsM[i].Attach(deviceIdP, transponderP))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSatipServer::Detach(int deviceIdP, int transponderP)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < eSatipFrontendCount; ++i) {
|
||||||
|
if (frontendsM[i].Detach(deviceIdP, transponderP))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cSatipServer::GetModulesDVBS2(void)
|
||||||
|
{
|
||||||
|
return frontendsM[eSatipFrontendDVBS2].Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int cSatipServer::GetModulesDVBT(void)
|
||||||
|
{
|
||||||
|
return frontendsM[eSatipFrontendDVBT].Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int cSatipServer::GetModulesDVBT2(void)
|
||||||
|
{
|
||||||
|
return frontendsM[eSatipFrontendDVBT2].Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int cSatipServer::GetModulesDVBC(void)
|
||||||
|
{
|
||||||
|
return frontendsM[eSatipFrontendDVBC].Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int cSatipServer::GetModulesDVBC2(void)
|
||||||
|
{
|
||||||
|
return frontendsM[eSatipFrontendDVBC2].Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cSatipServers ----------------------------------------------------------
|
// --- cSatipServers ----------------------------------------------------------
|
||||||
@@ -114,49 +265,32 @@ void cSatipServer::Use(bool onOffP)
|
|||||||
cSatipServer *cSatipServers::Find(cSatipServer *serverP)
|
cSatipServer *cSatipServers::Find(cSatipServer *serverP)
|
||||||
{
|
{
|
||||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
if (s == serverP)
|
if (s->Compare(*serverP) == 0)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cSatipServer *cSatipServers::Find(int sourceP, int transponderP, int systemP)
|
cSatipServer *cSatipServers::Find(int sourceP)
|
||||||
{
|
{
|
||||||
cSatipServer *result = NULL;
|
|
||||||
int model = 0;
|
|
||||||
if (cSource::IsType(sourceP, 'S'))
|
|
||||||
model |= cSatipServer::eSatipModelTypeDVBS2;
|
|
||||||
else if (cSource::IsType(sourceP, 'T')) {
|
|
||||||
if (systemP < 0)
|
|
||||||
model |= cSatipServer::eSatipModelTypeDVBT2 | cSatipServer::eSatipModelTypeDVBT;
|
|
||||||
else
|
|
||||||
model |= systemP ? cSatipServer::eSatipModelTypeDVBT2 : cSatipServer::eSatipModelTypeDVBT;
|
|
||||||
}
|
|
||||||
else if (cSource::IsType(sourceP, 'C'))
|
|
||||||
model |= cSatipServer::eSatipModelTypeDVBC;
|
|
||||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
if (s->Match(model) && s->Used() && (s->Transponder() == transponderP))
|
if (s->Matches(sourceP))
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cSatipServer *cSatipServers::Assign(int deviceIdP, int sourceP, int transponderP, int systemP)
|
||||||
|
{
|
||||||
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
|
if (s->Matches(deviceIdP, sourceP, systemP, transponderP))
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
if (s->Match(model)) {
|
if (s->Assign(deviceIdP, sourceP, systemP, transponderP))
|
||||||
result = s;
|
return s;
|
||||||
if (!s->Used()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cSatipServers::SetTransponder(cSatipServer *serverP, int transponderP)
|
|
||||||
{
|
|
||||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
||||||
if (s == serverP) {
|
|
||||||
s->SetTransponder(transponderP);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cSatipServer *cSatipServers::Update(cSatipServer *serverP)
|
cSatipServer *cSatipServers::Update(cSatipServer *serverP)
|
||||||
@@ -170,16 +304,50 @@ cSatipServer *cSatipServers::Update(cSatipServer *serverP)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipServers::Use(cSatipServer *serverP, bool onOffP)
|
void cSatipServers::Attach(cSatipServer *serverP, int deviceIdP, int transponderP)
|
||||||
{
|
{
|
||||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
if (s == serverP) {
|
if (s == serverP) {
|
||||||
s->Use(onOffP);
|
s->Attach(deviceIdP, transponderP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cSatipServers::Detach(cSatipServer *serverP, int deviceIdP, int transponderP)
|
||||||
|
{
|
||||||
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
|
if (s == serverP) {
|
||||||
|
s->Detach(deviceIdP, transponderP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipServers::IsQuirk(cSatipServer *serverP, int quirkP)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
|
if (s == serverP) {
|
||||||
|
result = s->Quirk(quirkP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipServers::HasCI(cSatipServer *serverP)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
|
if (s == serverP) {
|
||||||
|
result = s->HasCI();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void cSatipServers::Cleanup(uint64_t intervalMsP)
|
void cSatipServers::Cleanup(uint64_t intervalMsP)
|
||||||
{
|
{
|
||||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
@@ -190,6 +358,18 @@ void cSatipServers::Cleanup(uint64_t intervalMsP)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cString cSatipServers::GetAddress(cSatipServer *serverP)
|
||||||
|
{
|
||||||
|
cString address = "";
|
||||||
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
|
if (s == serverP) {
|
||||||
|
address = s->Address();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
cString cSatipServers::GetString(cSatipServer *serverP)
|
cString cSatipServers::GetString(cSatipServer *serverP)
|
||||||
{
|
{
|
||||||
cString list = "";
|
cString list = "";
|
||||||
@@ -215,13 +395,15 @@ int cSatipServers::NumProvidedSystems(void)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
// DVB-S2: qpsk, 8psk, 16apsk, 32apsk
|
// DVB-S2: qpsk, 8psk, 16apsk, 32apsk
|
||||||
count += s->Satellite() * 4;
|
count += s->GetModulesDVBS2() * 4;
|
||||||
// DVB-T2: qpsk, qam16, qam64, qam256
|
|
||||||
// DVB-T: qpsk, qam16, qam64
|
// DVB-T: qpsk, qam16, qam64
|
||||||
count += s->Terrestrial2() ? s->Terrestrial2() * 4 : s->Terrestrial() * 3;
|
count += s->GetModulesDVBT() * 3;
|
||||||
// DVB-C2: qam16, qam32, qam64, qam128, qam256
|
// DVB-T2: qpsk, qam16, qam64, qam256
|
||||||
|
count += s->GetModulesDVBT2() * 4;
|
||||||
// DVB-C: qam64, qam128, qam256
|
// DVB-C: qam64, qam128, qam256
|
||||||
count += s->Cable2() ? s->Cable2() * 5 : s->Cable() * 3;
|
count += s->GetModulesDVBC() * 3;
|
||||||
|
// DVB-C2: qam16, qam32, qam64, qam128, qam256
|
||||||
|
count += s->GetModulesDVBC2() * 5;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
113
server.h
113
server.h
@@ -8,26 +8,59 @@
|
|||||||
#ifndef __SATIP_SERVER_H
|
#ifndef __SATIP_SERVER_H
|
||||||
#define __SATIP_SERVER_H
|
#define __SATIP_SERVER_H
|
||||||
|
|
||||||
|
class cSatipServer;
|
||||||
|
|
||||||
|
// --- cSatipFrontend ---------------------------------------------------------
|
||||||
|
|
||||||
|
class cSatipFrontend : public cListObject {
|
||||||
|
private:
|
||||||
|
int indexM;
|
||||||
|
int transponderM;
|
||||||
|
int deviceIdM;
|
||||||
|
cString descriptionM;
|
||||||
|
|
||||||
|
public:
|
||||||
|
cSatipFrontend(const int indexP, const char *descriptionP);
|
||||||
|
virtual ~cSatipFrontend();
|
||||||
|
void Attach(int deviceIdP) { deviceIdM = deviceIdP; }
|
||||||
|
void Detach(int deviceIdP) { if (deviceIdP == deviceIdM) deviceIdM = -1; }
|
||||||
|
cString Description(void) { return descriptionM; }
|
||||||
|
bool Attached(void) { return (deviceIdM >= 0); }
|
||||||
|
int Index(void) { return indexM; }
|
||||||
|
int Transponder(void) { return transponderM; }
|
||||||
|
int DeviceId(void) { return deviceIdM; }
|
||||||
|
void SetTransponder(int transponderP) { transponderM = transponderP; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- cSatipFrontends --------------------------------------------------------
|
||||||
|
|
||||||
|
class cSatipFrontends : public cList<cSatipFrontend> {
|
||||||
|
public:
|
||||||
|
bool Matches(int deviceIdP, int transponderP);
|
||||||
|
bool Assign(int deviceIdP, int transponderP);
|
||||||
|
bool Attach(int deviceIdP, int transponderP);
|
||||||
|
bool Detach(int deviceIdP, int transponderP);
|
||||||
|
};
|
||||||
|
|
||||||
// --- cSatipServer -----------------------------------------------------------
|
// --- cSatipServer -----------------------------------------------------------
|
||||||
|
|
||||||
class cSatipServer : public cListObject {
|
class cSatipServer : public cListObject {
|
||||||
private:
|
private:
|
||||||
enum eSatipModule {
|
enum eSatipFrontend {
|
||||||
eSatipModuleDVBS2 = 0,
|
eSatipFrontendDVBS2 = 0,
|
||||||
eSatipModuleDVBT,
|
eSatipFrontendDVBT,
|
||||||
eSatipModuleDVBT2,
|
eSatipFrontendDVBT2,
|
||||||
eSatipModuleDVBC,
|
eSatipFrontendDVBC,
|
||||||
eSatipModuleDVBC2,
|
eSatipFrontendDVBC2,
|
||||||
eSatipModuleCount
|
eSatipFrontendCount
|
||||||
};
|
};
|
||||||
cString addressM;
|
cString addressM;
|
||||||
cString modelM;
|
cString modelM;
|
||||||
cString descriptionM;
|
cString descriptionM;
|
||||||
int modelCountM[eSatipModuleCount];
|
cString quirksM;
|
||||||
int modelTypeM;
|
cSatipFrontends frontendsM[eSatipFrontendCount];
|
||||||
int quirkM;
|
int quirkM;
|
||||||
int useCountM;
|
bool hasCiM;
|
||||||
int transponderM;
|
|
||||||
time_t createdM;
|
time_t createdM;
|
||||||
cTimeMs lastSeenM;
|
cTimeMs lastSeenM;
|
||||||
|
|
||||||
@@ -37,39 +70,31 @@ public:
|
|||||||
eSatipQuirkSessionId = 0x01,
|
eSatipQuirkSessionId = 0x01,
|
||||||
eSatipQuirkPlayPids = 0x02,
|
eSatipQuirkPlayPids = 0x02,
|
||||||
eSatipQuirkForceLock = 0x04,
|
eSatipQuirkForceLock = 0x04,
|
||||||
eSatipQuirkUseXCI = 0x08,
|
|
||||||
eSatipQuirkMask = 0x0F
|
eSatipQuirkMask = 0x0F
|
||||||
};
|
};
|
||||||
enum eSatipModelType {
|
|
||||||
eSatipModelTypeNone = 0x00,
|
|
||||||
eSatipModelTypeDVBS2 = 0x01,
|
|
||||||
eSatipModelTypeDVBT = 0x02,
|
|
||||||
eSatipModelTypeDVBT2 = 0x04,
|
|
||||||
eSatipModelTypeDVBC = 0x08,
|
|
||||||
eSatipModelTypeDVBC2 = 0x10,
|
|
||||||
eSatipModelTypeMask = 0xFF
|
|
||||||
};
|
|
||||||
cSatipServer(const char *addressP, const char *modelP, const char *descriptionP);
|
cSatipServer(const char *addressP, const char *modelP, const char *descriptionP);
|
||||||
virtual ~cSatipServer();
|
virtual ~cSatipServer();
|
||||||
virtual int Compare(const cListObject &listObjectP) const;
|
virtual int Compare(const cListObject &listObjectP) const;
|
||||||
void Use(bool onOffP);
|
bool Assign(int deviceIdP, int sourceP, int systemP, int transponderP);
|
||||||
void SetTransponder(const int transponderP) { transponderM = transponderP; }
|
bool Matches(int sourceP);
|
||||||
int Transponder(void) { return transponderM; }
|
bool Matches(int deviceIdP, int sourceP, int systemP, int transponderP);
|
||||||
bool Used(void) { return !!useCountM; }
|
void Attach(int deviceIdP, int transponderP);
|
||||||
const char *Address() { return *addressM; }
|
void Detach(int deviceIdP, int transponderP);
|
||||||
const char *Model(void) { return *modelM; }
|
int GetModulesDVBS2(void);
|
||||||
const char *Description() { return *descriptionM; }
|
int GetModulesDVBT(void);
|
||||||
bool Quirk(int quirkP) { return ((quirkP & eSatipQuirkMask) & quirkM); }
|
int GetModulesDVBT2(void);
|
||||||
int ModelType(void) { return modelTypeM; }
|
int GetModulesDVBC(void);
|
||||||
bool Match(int modelP) { return ((modelP & eSatipModelTypeMask) & modelTypeM); }
|
int GetModulesDVBC2(void);
|
||||||
int Cable() { return Match(eSatipModelTypeDVBC) ? modelCountM[eSatipModuleDVBC] : 0; }
|
const char *Address(void) { return *addressM; }
|
||||||
int Cable2() { return Match(eSatipModelTypeDVBC2) ? modelCountM[eSatipModuleDVBC2] : 0; }
|
const char *Model(void) { return *modelM; }
|
||||||
int Satellite() { return Match(eSatipModelTypeDVBS2) ? modelCountM[eSatipModuleDVBS2] : 0; }
|
const char *Description(void) { return *descriptionM; }
|
||||||
int Terrestrial() { return Match(eSatipModelTypeDVBT) ? modelCountM[eSatipModuleDVBT] : 0; }
|
const char *Quirks(void) { return *quirksM; }
|
||||||
int Terrestrial2() { return Match(eSatipModelTypeDVBT2) ? modelCountM[eSatipModuleDVBT2] : 0; }
|
bool Quirk(int quirkP) { return ((quirkP & eSatipQuirkMask) & quirkM); }
|
||||||
void Update(void) { lastSeenM.Set(); }
|
bool HasQuirk(void) { return (quirkM != eSatipQuirkNone); }
|
||||||
uint64_t LastSeen(void) { return lastSeenM.Elapsed(); }
|
bool HasCI(void) { return hasCiM; }
|
||||||
time_t Created(void) { return createdM; }
|
void Update(void) { lastSeenM.Set(); }
|
||||||
|
uint64_t LastSeen(void) { return lastSeenM.Elapsed(); }
|
||||||
|
time_t Created(void) { return createdM; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- cSatipServers ----------------------------------------------------------
|
// --- cSatipServers ----------------------------------------------------------
|
||||||
@@ -77,11 +102,15 @@ public:
|
|||||||
class cSatipServers : public cList<cSatipServer> {
|
class cSatipServers : public cList<cSatipServer> {
|
||||||
public:
|
public:
|
||||||
cSatipServer *Find(cSatipServer *serverP);
|
cSatipServer *Find(cSatipServer *serverP);
|
||||||
cSatipServer *Find(int sourceP, int transponderP, int systemP);
|
cSatipServer *Find(int sourceP);
|
||||||
void SetTransponder(cSatipServer *serverP, int transponderP);
|
cSatipServer *Assign(int deviceIdP, int sourceP, int transponderP, int systemP);
|
||||||
cSatipServer *Update(cSatipServer *serverP);
|
cSatipServer *Update(cSatipServer *serverP);
|
||||||
void Use(cSatipServer *serverP, bool onOffP);
|
void Attach(cSatipServer *serverP, int deviceIdP, int transponderP);
|
||||||
|
void Detach(cSatipServer *serverP, int deviceIdP, int transponderP);
|
||||||
|
bool IsQuirk(cSatipServer *serverP, int quirkP);
|
||||||
|
bool HasCI(cSatipServer *serverP);
|
||||||
void Cleanup(uint64_t intervalMsP = 0);
|
void Cleanup(uint64_t intervalMsP = 0);
|
||||||
|
cString GetAddress(cSatipServer *serverP);
|
||||||
cString GetString(cSatipServer *serverP);
|
cString GetString(cSatipServer *serverP);
|
||||||
cString List(void);
|
cString List(void);
|
||||||
int NumProvidedSystems(void);
|
int NumProvidedSystems(void);
|
||||||
|
22
setup.c
22
setup.c
@@ -104,7 +104,7 @@ cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP)
|
|||||||
addressM(serverP ? serverP->Address() : "---"),
|
addressM(serverP ? serverP->Address() : "---"),
|
||||||
modelM(serverP ? serverP->Model() : "---"),
|
modelM(serverP ? serverP->Model() : "---"),
|
||||||
descriptionM(serverP ? serverP->Description() : "---"),
|
descriptionM(serverP ? serverP->Description() : "---"),
|
||||||
ciExtensionM(serverP && serverP->Quirk(cSatipServer::eSatipQuirkUseXCI) ? trVDR("yes") : trVDR("no")),
|
ciExtensionM(serverP && serverP->HasCI() ? trVDR("yes") : trVDR("no")),
|
||||||
createdM(serverP ? serverP->Created() : 0)
|
createdM(serverP ? serverP->Created() : 0)
|
||||||
{
|
{
|
||||||
SetMenuCategory(mcSetupPlugins);
|
SetMenuCategory(mcSetupPlugins);
|
||||||
@@ -330,7 +330,8 @@ eOSState cSatipMenuInfo::ProcessKey(eKeys keyP)
|
|||||||
// --- cSatipPluginSetup ------------------------------------------------------
|
// --- cSatipPluginSetup ------------------------------------------------------
|
||||||
|
|
||||||
cSatipPluginSetup::cSatipPluginSetup()
|
cSatipPluginSetup::cSatipPluginSetup()
|
||||||
: deviceCountM(0),
|
: detachedModeM(SatipConfig.GetDetachedMode()),
|
||||||
|
deviceCountM(0),
|
||||||
operatingModeM(SatipConfig.GetOperatingMode()),
|
operatingModeM(SatipConfig.GetOperatingMode()),
|
||||||
ciExtensionM(SatipConfig.GetCIExtension()),
|
ciExtensionM(SatipConfig.GetCIExtension()),
|
||||||
eitScanM(SatipConfig.GetEITScan()),
|
eitScanM(SatipConfig.GetEITScan()),
|
||||||
@@ -402,12 +403,15 @@ void cSatipPluginSetup::Setup(void)
|
|||||||
Add(new cOsdItem(tr("Active SAT>IP servers:"), osUnknown, false));
|
Add(new cOsdItem(tr("Active SAT>IP servers:"), osUnknown, false));
|
||||||
helpM.Append("");
|
helpM.Append("");
|
||||||
|
|
||||||
cSatipServers *servers = cSatipDiscover::GetInstance()->GetServers();
|
detachedModeM = SatipConfig.GetDetachedMode();
|
||||||
deviceCountM = servers->Count();
|
if (!detachedModeM) {
|
||||||
for (cSatipServer *s = servers->First(); s; s = servers->Next(s)) {
|
cSatipServers *servers = cSatipDiscover::GetInstance()->GetServers();
|
||||||
Add(new cSatipServerItem(s));
|
deviceCountM = servers->Count();
|
||||||
helpM.Append("");
|
for (cSatipServer *s = servers->First(); s; s = servers->Next(s)) {
|
||||||
}
|
Add(new cSatipServerItem(s));
|
||||||
|
helpM.Append("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SetCurrent(Get(current));
|
SetCurrent(Get(current));
|
||||||
Display();
|
Display();
|
||||||
@@ -480,7 +484,7 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
|
|||||||
if ((keyP == kNone) && (cSatipDiscover::GetInstance()->GetServers()->Count() != deviceCountM))
|
if ((keyP == kNone) && (cSatipDiscover::GetInstance()->GetServers()->Count() != deviceCountM))
|
||||||
Setup();
|
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))
|
while ((numDisabledSourcesM < oldNumDisabledSources) && (oldNumDisabledSources > 0))
|
||||||
disabledSourcesM[--oldNumDisabledSources] = cSource::stNone;
|
disabledSourcesM[--oldNumDisabledSources] = cSource::stNone;
|
||||||
while ((numDisabledFiltersM < oldNumDisabledFilters) && (oldNumDisabledFilters > 0))
|
while ((numDisabledFiltersM < oldNumDisabledFilters) && (oldNumDisabledFilters > 0))
|
||||||
|
1
setup.h
1
setup.h
@@ -15,6 +15,7 @@
|
|||||||
class cSatipPluginSetup : public cMenuSetupPage
|
class cSatipPluginSetup : public cMenuSetupPage
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
bool detachedModeM;
|
||||||
int deviceCountM;
|
int deviceCountM;
|
||||||
int operatingModeM;
|
int operatingModeM;
|
||||||
const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
|
const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
|
||||||
|
15
socket.c
15
socket.c
@@ -129,19 +129,24 @@ int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP)
|
|||||||
if (len > 0)
|
if (len > 0)
|
||||||
return len;
|
return len;
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
ERROR_IF_RET(len < 0 && errno != EAGAIN, "recvmsg()", return -1);
|
ERROR_IF_RET(len < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmsg()", return -1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRecvSizeP, unsigned int elementCountP, unsigned int elementBufferSizeP)
|
int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRecvSizeP, unsigned int elementCountP, unsigned int elementBufferSizeP)
|
||||||
{
|
{
|
||||||
debug16("%s (, , %d, %d)", __PRETTY_FUNCTION__, elementCountP, elementBufferSizeP);
|
debug16("%s (, , %d, %d)", __PRETTY_FUNCTION__, elementCountP, elementBufferSizeP);
|
||||||
#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,12)
|
int count = -1;
|
||||||
// Error out if socket not initialized
|
// Error out if socket not initialized
|
||||||
if (socketDescM <= 0) {
|
if (socketDescM <= 0) {
|
||||||
error("%s Invalid socket", __PRETTY_FUNCTION__);
|
error("%s Invalid socket", __PRETTY_FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (!bufferAddrP || !elementRecvSizeP || !elementCountP || !elementBufferSizeP) {
|
||||||
|
error("%s Invalid parameter(s)", __PRETTY_FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,12)
|
||||||
// Initialize iov and msgh structures
|
// Initialize iov and msgh structures
|
||||||
struct mmsghdr mmsgh[elementCountP];
|
struct mmsghdr mmsgh[elementCountP];
|
||||||
struct iovec iov[elementCountP];
|
struct iovec iov[elementCountP];
|
||||||
@@ -154,14 +159,12 @@ int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRec
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read data from socket as a set
|
// Read data from socket as a set
|
||||||
int count = -1;
|
count = (int)recvmmsg(socketDescM, mmsgh, elementCountP, MSG_DONTWAIT, NULL);
|
||||||
if (socketDescM && bufferAddrP && elementRecvSizeP && (elementCountP > 0) && (elementBufferSizeP > 0))
|
|
||||||
count = (int)recvmmsg(socketDescM, mmsgh, elementCountP, MSG_DONTWAIT, NULL);
|
|
||||||
ERROR_IF_RET(count < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmmsg()", return -1);
|
ERROR_IF_RET(count < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmmsg()", return -1);
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
elementRecvSizeP[i] = mmsgh[i].msg_len;
|
elementRecvSizeP[i] = mmsgh[i].msg_len;
|
||||||
#else
|
#else
|
||||||
int count = 0;
|
count = 0;
|
||||||
while (count < (int)elementCountP) {
|
while (count < (int)elementCountP) {
|
||||||
int len = Read(bufferAddrP + count * elementBufferSizeP, elementBufferSizeP);
|
int len = Read(bufferAddrP + count * elementBufferSizeP, elementBufferSizeP);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
|
48
tuner.c
48
tuner.c
@@ -25,8 +25,8 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
|||||||
rtcpM(*this),
|
rtcpM(*this),
|
||||||
streamAddrM(""),
|
streamAddrM(""),
|
||||||
streamParamM(""),
|
streamParamM(""),
|
||||||
currentServerM(NULL),
|
currentServerM(NULL, deviceP.GetId(), 0),
|
||||||
nextServerM(NULL),
|
nextServerM(NULL, deviceP.GetId(), 0),
|
||||||
mutexM(),
|
mutexM(),
|
||||||
reConnectM(),
|
reConnectM(),
|
||||||
keepAliveM(),
|
keepAliveM(),
|
||||||
@@ -40,6 +40,7 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
|||||||
hasLockM(false),
|
hasLockM(false),
|
||||||
signalStrengthM(-1),
|
signalStrengthM(-1),
|
||||||
signalQualityM(-1),
|
signalQualityM(-1),
|
||||||
|
frontendIdM(-1),
|
||||||
streamIdM(-1),
|
streamIdM(-1),
|
||||||
pmtPidM(-1),
|
pmtPidM(-1),
|
||||||
addPidsM(),
|
addPidsM(),
|
||||||
@@ -118,7 +119,7 @@ void cSatipTuner::Action(void)
|
|||||||
// Read reception statistics via DESCRIBE and RTCP
|
// Read reception statistics via DESCRIBE and RTCP
|
||||||
if (hasLockM || ReadReceptionStatus()) {
|
if (hasLockM || ReadReceptionStatus()) {
|
||||||
// Quirk for devices without valid reception data
|
// Quirk for devices without valid reception data
|
||||||
if (currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkForceLock)) {
|
if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkForceLock)) {
|
||||||
hasLockM = true;
|
hasLockM = true;
|
||||||
signalStrengthM = eDefaultSignalStrength;
|
signalStrengthM = eDefaultSignalStrength;
|
||||||
signalQualityM = eDefaultSignalQuality;
|
signalQualityM = eDefaultSignalQuality;
|
||||||
@@ -196,15 +197,15 @@ bool cSatipTuner::Connect(void)
|
|||||||
else if (rtspM.Options(*connectionUri)) {
|
else if (rtspM.Options(*connectionUri)) {
|
||||||
cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM);
|
cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM);
|
||||||
// Flush any old content
|
// Flush any old content
|
||||||
rtpM.Flush();
|
//rtpM.Flush();
|
||||||
rtcpM.Flush();
|
//rtcpM.Flush();
|
||||||
if (rtspM.Setup(*uri, rtpM.Port(), rtcpM.Port())) {
|
if (rtspM.Setup(*uri, rtpM.Port(), rtcpM.Port())) {
|
||||||
keepAliveM.Set(timeoutM);
|
keepAliveM.Set(timeoutM);
|
||||||
if (nextServerM) {
|
if (nextServerM.IsValid()) {
|
||||||
cSatipDiscover::GetInstance()->UseServer(nextServerM, true);
|
|
||||||
currentServerM = nextServerM;
|
currentServerM = nextServerM;
|
||||||
nextServerM = NULL;
|
nextServerM.Reset();
|
||||||
}
|
}
|
||||||
|
currentServerM.Attach();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,9 +235,9 @@ bool cSatipTuner::Disconnect(void)
|
|||||||
hasLockM = false;
|
hasLockM = false;
|
||||||
signalStrengthM = -1;
|
signalStrengthM = -1;
|
||||||
signalQualityM = -1;
|
signalQualityM = -1;
|
||||||
|
frontendIdM = -1;
|
||||||
|
|
||||||
if (currentServerM)
|
currentServerM.Detach();
|
||||||
cSatipDiscover::GetInstance()->UseServer(currentServerM, false);
|
|
||||||
statusUpdateM.Set(0);
|
statusUpdateM.Set(0);
|
||||||
timeoutM = eMinKeepAliveIntervalMs;
|
timeoutM = eMinKeepAliveIntervalMs;
|
||||||
pmtPidM = -1;
|
pmtPidM = -1;
|
||||||
@@ -285,6 +286,9 @@ void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP)
|
|||||||
if (c) {
|
if (c) {
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
|
// feID:
|
||||||
|
frontendIdM = atoi(c + 7);
|
||||||
|
|
||||||
// level:
|
// level:
|
||||||
// Numerical value between 0 and 255
|
// Numerical value between 0 and 255
|
||||||
// An incoming L-band satellite signal of
|
// An incoming L-band satellite signal of
|
||||||
@@ -330,7 +334,7 @@ void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
|
|||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
debug1("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, sessionP, timeoutP, deviceIdM);
|
debug1("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, sessionP, timeoutP, deviceIdM);
|
||||||
sessionM = sessionP;
|
sessionM = sessionP;
|
||||||
if (nextServerM && nextServerM->Quirk(cSatipServer::eSatipQuirkSessionId) && !isempty(*sessionM) && startswith(*sessionM, "0"))
|
if (nextServerM.IsQuirk(cSatipServer::eSatipQuirkSessionId) && !isempty(*sessionM) && startswith(*sessionM, "0"))
|
||||||
rtspM.SetSession(SkipZeroes(*sessionM));
|
rtspM.SetSession(SkipZeroes(*sessionM));
|
||||||
timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs;
|
timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs;
|
||||||
}
|
}
|
||||||
@@ -341,15 +345,15 @@ int cSatipTuner::GetId(void)
|
|||||||
return deviceIdM;
|
return deviceIdM;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const int indexP)
|
bool cSatipTuner::SetSource(cSatipServer *serverP, const int transponderP, const char *parameterP, const int indexP)
|
||||||
{
|
{
|
||||||
debug1("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, parameterP, indexP, deviceIdM);
|
debug1("%s (%d, %s, %d) [device %d]", __PRETTY_FUNCTION__, transponderP, parameterP, indexP, deviceIdM);
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
if (serverP) {
|
if (serverP) {
|
||||||
nextServerM = cSatipDiscover::GetInstance()->GetServer(serverP);
|
nextServerM.Set(serverP, transponderP);
|
||||||
if (nextServerM && !isempty(nextServerM->Address()) && !isempty(parameterP)) {
|
if (!isempty(*nextServerM.GetAddress()) && !isempty(parameterP)) {
|
||||||
// Update stream address and parameter
|
// Update stream address and parameter
|
||||||
streamAddrM = rtspM.RtspUnescapeString(nextServerM->Address());
|
streamAddrM = rtspM.RtspUnescapeString(*nextServerM.GetAddress());
|
||||||
streamParamM = rtspM.RtspUnescapeString(parameterP);
|
streamParamM = rtspM.RtspUnescapeString(parameterP);
|
||||||
// Reconnect
|
// Reconnect
|
||||||
RequestState(tsSet, smExternal);
|
RequestState(tsSet, smExternal);
|
||||||
@@ -390,8 +394,8 @@ bool cSatipTuner::UpdatePids(bool forceP)
|
|||||||
if (((forceP && pidsM.Size()) || (pidUpdateCacheM.TimedOut() && (addPidsM.Size() || delPidsM.Size()))) &&
|
if (((forceP && pidsM.Size()) || (pidUpdateCacheM.TimedOut() && (addPidsM.Size() || delPidsM.Size()))) &&
|
||||||
!isempty(*streamAddrM) && (streamIdM > 0)) {
|
!isempty(*streamAddrM) && (streamIdM > 0)) {
|
||||||
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||||
bool useci = (SatipConfig.GetCIExtension() && !!(currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkUseXCI)));
|
bool useci = (SatipConfig.GetCIExtension() && currentServerM.HasCI());
|
||||||
bool usedummy = !!(currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkPlayPids));
|
bool usedummy = currentServerM.IsQuirk(cSatipServer::eSatipQuirkPlayPids);
|
||||||
if (forceP || usedummy) {
|
if (forceP || usedummy) {
|
||||||
if (pidsM.Size())
|
if (pidsM.Size())
|
||||||
uri = cString::sprintf("%s?pids=%s", *uri, *pidsM.ListPids());
|
uri = cString::sprintf("%s?pids=%s", *uri, *pidsM.ListPids());
|
||||||
@@ -558,6 +562,12 @@ const char *cSatipTuner::TunerStateString(eTunerState stateP)
|
|||||||
return "---";
|
return "---";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cSatipTuner::FrontendId(void)
|
||||||
|
{
|
||||||
|
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
|
return frontendIdM;
|
||||||
|
}
|
||||||
|
|
||||||
int cSatipTuner::SignalStrength(void)
|
int cSatipTuner::SignalStrength(void)
|
||||||
{
|
{
|
||||||
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
@@ -579,7 +589,7 @@ bool cSatipTuner::HasLock(void)
|
|||||||
cString cSatipTuner::GetSignalStatus(void)
|
cString cSatipTuner::GetSignalStatus(void)
|
||||||
{
|
{
|
||||||
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
return cString::sprintf("lock=%d strength=%d quality=%d", HasLock(), SignalStrength(), SignalQuality());
|
return cString::sprintf("lock=%d strength=%d quality=%d frontend=%d", HasLock(), SignalStrength(), SignalQuality(), FrontendId());
|
||||||
}
|
}
|
||||||
|
|
||||||
cString cSatipTuner::GetInformation(void)
|
cString cSatipTuner::GetInformation(void)
|
||||||
|
60
tuner.h
60
tuner.h
@@ -8,11 +8,11 @@
|
|||||||
#ifndef __SATIP_TUNER_H
|
#ifndef __SATIP_TUNER_H
|
||||||
#define __SATIP_TUNER_H
|
#define __SATIP_TUNER_H
|
||||||
|
|
||||||
#include <vdr/config.h> // APIVERSNUM
|
|
||||||
#include <vdr/thread.h>
|
#include <vdr/thread.h>
|
||||||
#include <vdr/tools.h>
|
#include <vdr/tools.h>
|
||||||
|
|
||||||
#include "deviceif.h"
|
#include "deviceif.h"
|
||||||
|
#include "discover.h"
|
||||||
#include "rtp.h"
|
#include "rtp.h"
|
||||||
#include "rtcp.h"
|
#include "rtcp.h"
|
||||||
#include "rtsp.h"
|
#include "rtsp.h"
|
||||||
@@ -27,33 +27,6 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if defined(APIVERSNUM) && APIVERSNUM < 20107
|
|
||||||
int IndexOf(const int &pidP)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Size(); ++i) {
|
|
||||||
if (pidP == At(i))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
bool RemoveElement(const int &pidP)
|
|
||||||
{
|
|
||||||
int i = IndexOf(pidP);
|
|
||||||
if (i >= 0) {
|
|
||||||
Remove(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool AppendUnique(int pidP)
|
|
||||||
{
|
|
||||||
if (IndexOf(pidP) < 0) {
|
|
||||||
Append(pidP);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void RemovePid(const int &pidP)
|
void RemovePid(const int &pidP)
|
||||||
{
|
{
|
||||||
if (RemoveElement(pidP))
|
if (RemoveElement(pidP))
|
||||||
@@ -76,6 +49,29 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cSatipTunerServer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
cSatipServer *serverM;
|
||||||
|
int deviceIdM;
|
||||||
|
int transponderM;
|
||||||
|
|
||||||
|
public:
|
||||||
|
cSatipTunerServer(cSatipServer *serverP, const int deviceIdP, const int transponderP) : serverM(serverP), deviceIdM(deviceIdP), transponderM(transponderP) {}
|
||||||
|
~cSatipTunerServer() {}
|
||||||
|
cSatipTunerServer(const cSatipTunerServer &objP) { serverM = NULL; deviceIdM = -1; transponderM = 0; }
|
||||||
|
cSatipTunerServer& operator= (const cSatipTunerServer &objP) { serverM = objP.serverM; deviceIdM = objP.deviceIdM; transponderM = objP.transponderM; return *this; }
|
||||||
|
bool IsValid(void) { return !!serverM; }
|
||||||
|
bool IsQuirk(int quirkP) { return (serverM && cSatipDiscover::GetInstance()->IsServerQuirk(serverM, quirkP)); }
|
||||||
|
bool HasCI(void) { return (serverM && cSatipDiscover::GetInstance()->HasServerCI(serverM)); }
|
||||||
|
void Attach(void) { if (serverM) cSatipDiscover::GetInstance()->AttachServer(serverM, deviceIdM, transponderM); }
|
||||||
|
void Detach(void) { if (serverM) cSatipDiscover::GetInstance()->DetachServer(serverM, deviceIdM, transponderM); }
|
||||||
|
void Set(cSatipServer *serverP, const int transponderP) { serverM = serverP; transponderM = transponderP; }
|
||||||
|
void Reset(void) { serverM = NULL; transponderM = 0; }
|
||||||
|
cString GetAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerAddress(serverM) : ""; }
|
||||||
|
cString GetInfo(void) { return cString::sprintf("server=%s deviceid=%d transponder=%d", serverM ? "assigned" : "null", deviceIdM, transponderM); }
|
||||||
|
};
|
||||||
|
|
||||||
class cSatipTuner : public cThread, public cSatipTunerStatistics, public cSatipTunerIf
|
class cSatipTuner : public cThread, public cSatipTunerStatistics, public cSatipTunerIf
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -100,8 +96,8 @@ private:
|
|||||||
cSatipRtcp rtcpM;
|
cSatipRtcp rtcpM;
|
||||||
cString streamAddrM;
|
cString streamAddrM;
|
||||||
cString streamParamM;
|
cString streamParamM;
|
||||||
cSatipServer *currentServerM;
|
cSatipTunerServer currentServerM;
|
||||||
cSatipServer *nextServerM;
|
cSatipTunerServer nextServerM;
|
||||||
cMutex mutexM;
|
cMutex mutexM;
|
||||||
cTimeMs reConnectM;
|
cTimeMs reConnectM;
|
||||||
cTimeMs keepAliveM;
|
cTimeMs keepAliveM;
|
||||||
@@ -115,6 +111,7 @@ private:
|
|||||||
bool hasLockM;
|
bool hasLockM;
|
||||||
int signalStrengthM;
|
int signalStrengthM;
|
||||||
int signalQualityM;
|
int signalQualityM;
|
||||||
|
int frontendIdM;
|
||||||
int streamIdM;
|
int streamIdM;
|
||||||
int pmtPidM;
|
int pmtPidM;
|
||||||
cSatipPid addPidsM;
|
cSatipPid addPidsM;
|
||||||
@@ -139,10 +136,11 @@ public:
|
|||||||
cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP);
|
cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP);
|
||||||
virtual ~cSatipTuner();
|
virtual ~cSatipTuner();
|
||||||
bool IsTuned(void) const { return (currentStateM >= tsTuned); }
|
bool IsTuned(void) const { return (currentStateM >= tsTuned); }
|
||||||
bool SetSource(cSatipServer *serverP, const char *parameterP, const int indexP);
|
bool SetSource(cSatipServer *serverP, const int transponderP, const char *parameterP, const int indexP);
|
||||||
bool SetPid(int pidP, int typeP, bool onP);
|
bool SetPid(int pidP, int typeP, bool onP);
|
||||||
bool Open(void);
|
bool Open(void);
|
||||||
bool Close(void);
|
bool Close(void);
|
||||||
|
int FrontendId(void);
|
||||||
int SignalStrength(void);
|
int SignalStrength(void);
|
||||||
int SignalQuality(void);
|
int SignalQuality(void);
|
||||||
bool HasLock(void);
|
bool HasLock(void);
|
||||||
|
Reference in New Issue
Block a user