mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 11:37:42 +00:00
Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6573c38fb6 | ||
|
581ac4966d | ||
|
99e366b261 | ||
|
3b89dd4b01 | ||
|
ee6ac0d48a | ||
|
e6c9776ec9 | ||
|
7aef2a3dff | ||
|
61b56db909 | ||
|
4c45787541 | ||
|
f65dca2910 | ||
|
db0c18ba33 | ||
|
0f9e0014df | ||
|
6bb7fb511b | ||
|
7815821824 | ||
|
bc481bcc4d | ||
|
7289da9f41 | ||
|
d5e0106d8e | ||
|
fe532e2248 | ||
|
b5483b9d77 | ||
|
fd23b0483a | ||
|
18c9b79533 | ||
|
e4f560c66e | ||
|
57ea119d03 | ||
|
ae8298d19a | ||
|
b755dbf318 | ||
|
8f12ce6f55 | ||
|
9d5f7cc703 | ||
|
c1a881ba94 | ||
|
165fd5b14a |
71
HISTORY
71
HISTORY
@ -156,74 +156,3 @@ VDR Plugin 'satip' Revision History
|
|||||||
- Added multicast and RTP-over-TCP support.
|
- Added multicast and RTP-over-TCP support.
|
||||||
- Added support for activating/deactivating server on-the-fly.
|
- Added support for activating/deactivating server on-the-fly.
|
||||||
- Extended command-line parameters for setting server quirks.
|
- Extended command-line parameters for setting server quirks.
|
||||||
|
|
||||||
2017-08-15: Version 2.2.5
|
|
||||||
|
|
||||||
- Added Polish translation (Thanks to Tomasz Nowak).
|
|
||||||
- Updated Catalan and Spanish translations (Thanks to Gabriel Bonich).
|
|
||||||
- Added support for KATHREIN SatIP Server (Thanks to kavanu).
|
|
||||||
- Added support for FRITZ!Box 6490 Cable (Thanks to 9000h).
|
|
||||||
- Updated FRITZ!WLAN Repeater DVB-C detection for the latest firmware (Thanks to 9000h).
|
|
||||||
- Added GCC7 compatibility (Thanks to Sascha Kuehndel).
|
|
||||||
|
|
||||||
|
|
||||||
===================================
|
|
||||||
VDR Plugin 'satip' Revision History
|
|
||||||
===================================
|
|
||||||
|
|
||||||
2016-12-18: Version 2.3.0
|
|
||||||
|
|
||||||
- Updated for vdr-2.3.1.
|
|
||||||
- Updated German translation (Thanks to Frank Neumann).
|
|
||||||
- Fixed Panasonic CXW804 support (Thanks to Tobias Grimm).
|
|
||||||
- Fixed C++11 support (Thanks to Tobias Grimm).
|
|
||||||
- Fixed server assigment with source validation (Thanks to Patrick Boettcher).
|
|
||||||
- Added configurable RTP/RTCP ports (Thanks to chriszero).
|
|
||||||
- Added support for X-SATIP-RTSP-Port header.
|
|
||||||
- Added multicast and RTP-over-TCP support.
|
|
||||||
- Added support for activating/deactivating server on-the-fly.
|
|
||||||
- Extended command-line parameters for setting server quirks.
|
|
||||||
|
|
||||||
2017-08-15: Version 2.3.1
|
|
||||||
|
|
||||||
- Updated for vdr-2.3.7 (Thanks to Klaus Schmidinger).
|
|
||||||
- Added Polish translation (Thanks to Tomasz Nowak).
|
|
||||||
- Updated Catalan and Spanish translations (Thanks to Gabriel Bonich).
|
|
||||||
- Added support for KATHREIN SatIP Server (Thanks to kavanu).
|
|
||||||
- Added support for FRITZ!Box 6490 Cable (Thanks to 9000h).
|
|
||||||
- Updated FRITZ!WLAN Repeater DVB-C detection for the latest firmware (Thanks to 9000h).
|
|
||||||
- Added GCC7 compatibility (Thanks to Sascha Kuehndel).
|
|
||||||
|
|
||||||
|
|
||||||
===================================
|
|
||||||
VDR Plugin 'satip' Revision History
|
|
||||||
===================================
|
|
||||||
|
|
||||||
2018-04-15: Version 2.4.0
|
|
||||||
|
|
||||||
- Updated for vdr-2.4.0.
|
|
||||||
- Removed speed limit.
|
|
||||||
- Fixed transport media changes.
|
|
||||||
- Fixed memory leak in cSatipSectionFilter (Thanks to Alexander Pipelka).
|
|
||||||
- Added more robust section filter handling (Thanks to Alexander Pipelka).
|
|
||||||
- Added a command line parameter for the RTP receive buffer size (Thanks to Stefan Rehm).
|
|
||||||
|
|
||||||
2021-06-01: Version 2.4.1
|
|
||||||
|
|
||||||
- Added an option to enable/disable frontend reuse.
|
|
||||||
- Added a preliminary ATSC support.
|
|
||||||
- Fixed a channel switching logic bug (Thanks to REELcoder).
|
|
||||||
- Added a workaround for detecting Panasonic devices.
|
|
||||||
- Removed quirks from FRITZ!Box 6490 Cable due to new firmware.
|
|
||||||
- Fixed RTP over TCP.
|
|
||||||
- Fixed URL parameter creation (Thanks to Martin Janser).
|
|
||||||
- Added an option to enable/disable frontend reuse.
|
|
||||||
- Added a preliminary ATSC support.
|
|
||||||
- Fixed a channel switching logic bug (Thanks to REELcoder).
|
|
||||||
- Added quirks for Inverto IDL-400s.
|
|
||||||
- Updated German translation (Thanks to Martin Dummer).
|
|
||||||
- Added a quirk for always teardown before play (Thanks to maazl).
|
|
||||||
- Updated for vdr-2.4.3 (Thanks to <Winfried Koehler).
|
|
||||||
- Added timeout for HasLock (Thanks to Winfried Koehler).
|
|
||||||
- Updated detectsatip script for Python 3.
|
|
||||||
- Fixed keepalive interval.
|
|
||||||
|
27
Makefile
27
Makefile
@ -88,15 +88,14 @@ all: $(SOFILE) i18n
|
|||||||
### Implicit rules:
|
### Implicit rules:
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
@echo CC $@
|
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
|
||||||
|
|
||||||
### Dependencies:
|
### Dependencies:
|
||||||
|
|
||||||
MAKEDEP = $(CXX) -MM -MG
|
MAKEDEP = $(CXX) -MM -MG
|
||||||
DEPFILE = .dependencies
|
DEPFILE = .dependencies
|
||||||
$(DEPFILE): Makefile
|
$(DEPFILE): Makefile
|
||||||
$(Q)$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
|
@$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
|
||||||
|
|
||||||
-include $(DEPFILE)
|
-include $(DEPFILE)
|
||||||
|
|
||||||
@ -109,21 +108,17 @@ I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLU
|
|||||||
I18Npot = $(PODIR)/$(PLUGIN).pot
|
I18Npot = $(PODIR)/$(PLUGIN).pot
|
||||||
|
|
||||||
%.mo: %.po
|
%.mo: %.po
|
||||||
@echo MO $@
|
msgfmt -c -o $@ $<
|
||||||
$(Q)msgfmt -c -o $@ $<
|
|
||||||
|
|
||||||
$(I18Npot): $(wildcard *.c)
|
$(I18Npot): $(wildcard *.c)
|
||||||
@echo GT $@
|
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
|
||||||
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
|
|
||||||
|
|
||||||
%.po: $(I18Npot)
|
%.po: $(I18Npot)
|
||||||
@echo PO $@
|
msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||||
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
|
||||||
@touch $@
|
@touch $@
|
||||||
|
|
||||||
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
|
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
|
||||||
@echo IN $@
|
install -D -m644 $< $@
|
||||||
$(Q)install -D -m644 $< $@
|
|
||||||
|
|
||||||
.PHONY: i18n
|
.PHONY: i18n
|
||||||
i18n: $(I18Nmo) $(I18Npot)
|
i18n: $(I18Nmo) $(I18Npot)
|
||||||
@ -133,13 +128,11 @@ install-i18n: $(I18Nmsgs)
|
|||||||
### Targets:
|
### Targets:
|
||||||
|
|
||||||
$(SOFILE): $(OBJS)
|
$(SOFILE): $(OBJS)
|
||||||
@echo LD $@
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
||||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
@$(STRIP) $@
|
||||||
$(Q)$(STRIP) $@
|
|
||||||
|
|
||||||
install-lib: $(SOFILE)
|
install-lib: $(SOFILE)
|
||||||
@echo IN $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||||
$(Q)install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
|
||||||
|
|
||||||
install-conf:
|
install-conf:
|
||||||
@mkdir -p $(DESTDIR)$(CFGDIR)/plugins/$(PLUGIN)
|
@mkdir -p $(DESTDIR)$(CFGDIR)/plugins/$(PLUGIN)
|
||||||
@ -160,4 +153,4 @@ clean:
|
|||||||
|
|
||||||
.PHONY: cppcheck
|
.PHONY: cppcheck
|
||||||
cppcheck:
|
cppcheck:
|
||||||
$(Q)cppcheck --language=c++ --enable=all -v -f $(OBJS:%.o=%.c)
|
@cppcheck --language=c++ --enable=all -v -f $(OBJS:%.o=%.c)
|
||||||
|
140
README
140
README
@ -3,9 +3,9 @@ This is an SAT>IP plugin for the Video Disk Recorder (VDR).
|
|||||||
Written by: Rolf Ahrenberg
|
Written by: Rolf Ahrenberg
|
||||||
< R o l f . A h r e n b e r g @ s c i . f i >
|
< R o l f . A h r e n b e r g @ s c i . f i >
|
||||||
|
|
||||||
Project's homepage: https://github.com/rofafor/vdr-plugin-satip
|
Project's homepage: http://www.saunalahti.fi/~rahrenbe/vdr/satip/
|
||||||
|
|
||||||
Latest version available at: https://github.com/rofafor/vdr-plugin-satip/releases
|
Latest version available at: http://www.saunalahti.fi/~rahrenbe/vdr/satip/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License version 2 as
|
it under the terms of the GNU General Public License version 2 as
|
||||||
@ -47,38 +47,12 @@ 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
|
||||||
can be used to manually configure static SAT>IP servers if autodetection
|
can be used to manually configure static SAT>IP servers if autodetection
|
||||||
via UPnP somehow can't be used. Multiple service entries can be given
|
via UPnP somehow can't be used. The parameter string is a semicolon
|
||||||
separated by a semicolon:
|
separated list of "<ipaddress>|<model>|<description>" entries. The model
|
||||||
|
consists of a DVB system (DVBS2,DVBT2,DVBT,DVBC) and number of available
|
||||||
[<srcaddress>@]<ipaddress>[:<port>]|<model>[:<filter>]|<description>[:<quirk>];...
|
frontends separated by a hyphen:
|
||||||
|
|
||||||
- srcaddress (Optional) Source address can be used to define used
|
|
||||||
networking interface on a host, e.g. 127.0.0.1.
|
|
||||||
- ipaddress IP address of SAT>IP server, e.g. 127.0.0.1.
|
|
||||||
- port (Optional) IP port number of SAT>IP server, e.g 443.
|
|
||||||
- model Model defines DVB modulation system (DVBS2,
|
|
||||||
DVBT2, DVBT, DVBC) and number of available
|
|
||||||
frontends separated by a hyphen, e.g. DVBT2-4.
|
|
||||||
- filter (Optional) Filter can be used to limit satellite frontends
|
|
||||||
to certain satellite position, e.g. S19.2E.
|
|
||||||
- description Friendly name of SAT>IP server. This is used
|
|
||||||
for autodetection of quirks.
|
|
||||||
- quirk (Optional) Quirks are non-standard compliant features and
|
|
||||||
bug fixes of SAT>IP server defined by a
|
|
||||||
hexadecimal number. Multiple quirks can be
|
|
||||||
defined by combining values by addition:
|
|
||||||
|
|
||||||
0x01: Fix session id bug
|
|
||||||
0x02: Fix play parameter (addpids/delpids) bug
|
|
||||||
0x04: Fix frontend locking bug
|
|
||||||
0x08: Support for RTP over TCP
|
|
||||||
0x10: Support the X_PMT protocol extension
|
|
||||||
0x20: Support the CI TNR protocol extension
|
|
||||||
0x40: Fix auto-detection of pilot tones bug
|
|
||||||
0x80: Fix re-tuning bug by teardowning a session
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
|
vdr -P 'satip -s <ipaddress>[:<port>]|<model>[:<filter>]|<description>[:<quirk>];...'
|
||||||
vdr -P 'satip -s 192.168.0.1|DVBS2-2,DVBT2-2|OctopusNet'
|
vdr -P 'satip -s 192.168.0.1|DVBS2-2,DVBT2-2|OctopusNet'
|
||||||
vdr -P 'satip -s 192.168.0.1|DVBS2-4|OctopusNet;192.168.0.2|DVBT2-4|minisatip:0x18'
|
vdr -P 'satip -s 192.168.0.1|DVBS2-4|OctopusNet;192.168.0.2|DVBT2-4|minisatip:0x18'
|
||||||
vdr -P 'satip -s 192.168.0.1:554|DVBS2-2:S19.2E|OctopusNet;192.168.0.2:8554|DVBS2-4:S19.2E,S1W|minisatip'
|
vdr -P 'satip -s 192.168.0.1:554|DVBS2-2:S19.2E|OctopusNet;192.168.0.2:8554|DVBS2-4:S19.2E,S1W|minisatip'
|
||||||
@ -112,50 +86,46 @@ Valid range: 1 ... 99
|
|||||||
|
|
||||||
Setup menu:
|
Setup menu:
|
||||||
|
|
||||||
- Operating mode = off If you want exclude all SAT>IP devices
|
- Operating mode = off If you want exclude all SAT>IP devices
|
||||||
low from VDR's device handling, set this
|
low from VDR's device handling, set this
|
||||||
normal option to "off". Otherwise, if you want
|
normal option to "off". Otherwise, if you want
|
||||||
high to keep SAT>IP at a low priority when
|
high to keep SAT>IP at a low priority when
|
||||||
selecting available devices, set this
|
selecting available devices, set this
|
||||||
option to "low". Similarly, the "high"
|
option to "low". Similarly, the "high"
|
||||||
value prefers the SAT>IP over the local
|
value prefers the SAT>IP over the local
|
||||||
DVB cards when selecting available devices.
|
DVB cards when selecting available devices.
|
||||||
- Use CI extension = no If you want to use the CI extension found
|
- Use CI extension = no If you want to use the CI extension found
|
||||||
in some SAT>IP hardware (e.g. Digital
|
in some SAT>IP hardware (e.g. Digital
|
||||||
Devices OctopusNet), set this option to
|
Devices OctopusNet), set this option to
|
||||||
"yes".
|
"yes".
|
||||||
- CICAM #<slot> = <system> If you want to assign a CA system into
|
- CICAM #<slot> = <system> If you want to assign a CA system into
|
||||||
a specific CI slot, set this option to
|
a specific CI slot, set this option to
|
||||||
a named one. Use "---" for autoselection.
|
a named one. Use "---" for autoselection.
|
||||||
- Enable EPG scanning = yes If you want exclude all SAT>IP devices
|
- Enable EPG scanning = yes If you want exclude all SAT>IP devices
|
||||||
from VDR's EIT background scanning, set
|
from VDR's EIT background scanning, set
|
||||||
this option to "no".
|
this option to "no".
|
||||||
- Disabled sources = none If your SAT>IP servers don't have certain
|
- Disabled sources = none If your SAT>IP servers don't have certain
|
||||||
satellite positions available you can
|
satellite positions available you can
|
||||||
disable them via this option.
|
disable them via this option.
|
||||||
- Disabled filters = none Certain section filters might cause some
|
- Disabled filters = none Certain section filters might cause some
|
||||||
unwanted behaviour to VDR such as time
|
unwanted behaviour to VDR such as time
|
||||||
being falsely synchronized etc. This option
|
being falsely synchronized etc. This option
|
||||||
allows creation of blacklists of ill-behaving
|
allows creation of blacklists of ill-behaving
|
||||||
filters. If this option is set to a non-zero
|
filters. If this option is set to a non-zero
|
||||||
value, the menu page will contain that many
|
value, the menu page will contain that many
|
||||||
"Disable filter" options which allow you
|
"Disable filter" options which allow you
|
||||||
to disable the individual section filters.
|
to disable the individual section filters.
|
||||||
Valid range: "none" = 0 ... 7
|
Valid range: "none" = 0 ... 7
|
||||||
- Transport mode = unicast If you want to use the non-standard
|
- Transport mode = unicast If you want to use the non-standard
|
||||||
multicast RTP-over-TCP transport mode, set this option
|
multicast RTP-over-TCP transport mode, set this option
|
||||||
rtp-o-tcp accordingly. Otherwise, the transport
|
rtp-o-tcp accordingly. Otherwise, the transport
|
||||||
mode will be RTP-over-UDP via unicast or
|
mode will be RTP-over-UDP via unicast or
|
||||||
multicast.
|
multicast.
|
||||||
- Enable frontend reuse = yes Certain devices might have artifacts if
|
- [Red:Scan] Forces network scanning of SAT>IP hardware.
|
||||||
multiple channels are assigned to the same
|
- [Yellow:Devices] Opens SAT>IP device status menu.
|
||||||
frontend. If you want to avoid such a
|
- [Blue:Info] Opens SAT>IP information/statistics menu.
|
||||||
frontend assignment, set this option to "no".
|
- [Ok] Opens information menu of selected SAT>IP
|
||||||
- [Red:Scan] Forces network scanning of SAT>IP hardware.
|
device.
|
||||||
- [Yellow:Devices] Opens SAT>IP device status menu.
|
|
||||||
- [Blue:Info] Opens SAT>IP information/statistics menu.
|
|
||||||
- [Ok] Opens information menu of selected SAT>IP
|
|
||||||
device.
|
|
||||||
|
|
||||||
Information menu:
|
Information menu:
|
||||||
|
|
||||||
@ -189,22 +159,6 @@ Notes:
|
|||||||
from their webpage: http://www.inverto.tv/support/
|
from their webpage: http://www.inverto.tv/support/
|
||||||
An update to a newer firmware should be offered afterwards.
|
An update to a newer firmware should be offered afterwards.
|
||||||
|
|
||||||
- FRITZ!OS 7.00 or greater recommended for FRITZ!Box Cable devices.
|
|
||||||
Older firmware versions require both PlayPids and ForceLock quirks.
|
|
||||||
|
|
||||||
- If you are experiencing glitches in the video stream, one possible
|
|
||||||
reason can be buffer overflows in RTP receive sockets. You can verify
|
|
||||||
this by checking "receive buffer errors" counter by running "netstat -s"
|
|
||||||
command. If the counter increases every time a video glitch happens,
|
|
||||||
you should try to tweak the RTP receive buffer size with the "--rcvbuf"
|
|
||||||
(-r) plugin parameter.
|
|
||||||
A good starting point for the buffer size is to double the operating
|
|
||||||
system default value until errors disappear or the maximum value is
|
|
||||||
reached. You can check these values in Linux by checking the kernel
|
|
||||||
parameters:
|
|
||||||
$ cat /proc/sys/net/core/rmem_default
|
|
||||||
$ cat /proc/sys/net/core/rmem_max
|
|
||||||
|
|
||||||
Acknowledgements:
|
Acknowledgements:
|
||||||
|
|
||||||
- Big thanks to Digital Devices GmbH for providing the Octopus Net
|
- Big thanks to Digital Devices GmbH for providing the Octopus Net
|
||||||
|
4
config.c
4
config.c
@ -15,7 +15,6 @@ cSatipConfig::cSatipConfig(void)
|
|||||||
: operatingModeM(eOperatingModeLow),
|
: operatingModeM(eOperatingModeLow),
|
||||||
traceModeM(eTraceModeNormal),
|
traceModeM(eTraceModeNormal),
|
||||||
ciExtensionM(0),
|
ciExtensionM(0),
|
||||||
frontendReuseM(1),
|
|
||||||
eitScanM(1),
|
eitScanM(1),
|
||||||
useBytesM(1),
|
useBytesM(1),
|
||||||
portRangeStartM(0),
|
portRangeStartM(0),
|
||||||
@ -23,8 +22,7 @@ cSatipConfig::cSatipConfig(void)
|
|||||||
transportModeM(eTransportModeUnicast),
|
transportModeM(eTransportModeUnicast),
|
||||||
detachedModeM(false),
|
detachedModeM(false),
|
||||||
disableServerQuirksM(false),
|
disableServerQuirksM(false),
|
||||||
useSingleModelServersM(false),
|
useSingleModelServersM(false)
|
||||||
rtpRcvBufSizeM(0)
|
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < ELEMENTS(cicamsM); ++i)
|
for (unsigned int i = 0; i < ELEMENTS(cicamsM); ++i)
|
||||||
cicamsM[i] = 0;
|
cicamsM[i] = 0;
|
||||||
|
6
config.h
6
config.h
@ -17,7 +17,6 @@ private:
|
|||||||
unsigned int operatingModeM;
|
unsigned int operatingModeM;
|
||||||
unsigned int traceModeM;
|
unsigned int traceModeM;
|
||||||
unsigned int ciExtensionM;
|
unsigned int ciExtensionM;
|
||||||
unsigned int frontendReuseM;
|
|
||||||
unsigned int eitScanM;
|
unsigned int eitScanM;
|
||||||
unsigned int useBytesM;
|
unsigned int useBytesM;
|
||||||
unsigned int portRangeStartM;
|
unsigned int portRangeStartM;
|
||||||
@ -29,7 +28,6 @@ private:
|
|||||||
int cicamsM[MAX_CICAM_COUNT];
|
int cicamsM[MAX_CICAM_COUNT];
|
||||||
int disabledSourcesM[MAX_DISABLED_SOURCES_COUNT];
|
int disabledSourcesM[MAX_DISABLED_SOURCES_COUNT];
|
||||||
int disabledFiltersM[SECTION_FILTER_TABLE_SIZE];
|
int disabledFiltersM[SECTION_FILTER_TABLE_SIZE];
|
||||||
size_t rtpRcvBufSizeM;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum eOperatingMode {
|
enum eOperatingMode {
|
||||||
@ -75,7 +73,6 @@ public:
|
|||||||
unsigned int GetTraceMode(void) const { return traceModeM; }
|
unsigned int GetTraceMode(void) const { return traceModeM; }
|
||||||
bool IsTraceMode(eTraceMode modeP) const { return (traceModeM & modeP); }
|
bool IsTraceMode(eTraceMode modeP) const { return (traceModeM & modeP); }
|
||||||
unsigned int GetCIExtension(void) const { return ciExtensionM; }
|
unsigned int GetCIExtension(void) const { return ciExtensionM; }
|
||||||
unsigned int GetFrontendReuse(void) const { return frontendReuseM; }
|
|
||||||
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; }
|
||||||
@ -92,12 +89,10 @@ public:
|
|||||||
int GetDisabledFilters(unsigned int indexP) const;
|
int GetDisabledFilters(unsigned int indexP) const;
|
||||||
unsigned int GetPortRangeStart(void) const { return portRangeStartM; }
|
unsigned int GetPortRangeStart(void) const { return portRangeStartM; }
|
||||||
unsigned int GetPortRangeStop(void) const { return portRangeStopM; }
|
unsigned int GetPortRangeStop(void) const { return portRangeStopM; }
|
||||||
size_t GetRtpRcvBufSize(void) const { return rtpRcvBufSizeM; }
|
|
||||||
|
|
||||||
void SetOperatingMode(unsigned int operatingModeP) { operatingModeM = operatingModeP; }
|
void SetOperatingMode(unsigned int operatingModeP) { operatingModeM = operatingModeP; }
|
||||||
void SetTraceMode(unsigned int modeP) { traceModeM = (modeP & eTraceModeMask); }
|
void SetTraceMode(unsigned int modeP) { traceModeM = (modeP & eTraceModeMask); }
|
||||||
void SetCIExtension(unsigned int onOffP) { ciExtensionM = onOffP; }
|
void SetCIExtension(unsigned int onOffP) { ciExtensionM = onOffP; }
|
||||||
void SetFrontendReuse(unsigned int onOffP) { frontendReuseM = onOffP; }
|
|
||||||
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; }
|
||||||
@ -109,7 +104,6 @@ public:
|
|||||||
void SetDisabledFilters(unsigned int indexP, int numberP);
|
void SetDisabledFilters(unsigned int indexP, int numberP);
|
||||||
void SetPortRangeStart(unsigned int rangeStartP) { portRangeStartM = rangeStartP; }
|
void SetPortRangeStart(unsigned int rangeStartP) { portRangeStartM = rangeStartP; }
|
||||||
void SetPortRangeStop(unsigned int rangeStopP) { portRangeStopM = rangeStopP; }
|
void SetPortRangeStop(unsigned int rangeStopP) { portRangeStopM = rangeStopP; }
|
||||||
void SetRtpRcvBufSize(size_t sizeP) { rtpRcvBufSizeM = sizeP; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern cSatipConfig SatipConfig;
|
extern cSatipConfig SatipConfig;
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
""" Simple tool to detect SAT>IP devices as JSON.
|
|
||||||
"""
|
|
||||||
import json
|
|
||||||
import socket
|
|
||||||
import sys
|
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
import requests
|
|
||||||
|
|
||||||
SSDP_BIND = "0.0.0.0"
|
|
||||||
SSDP_ADDR = "239.255.255.250"
|
|
||||||
SSDP_PORT = 1900
|
|
||||||
SSDP_MX = 1
|
|
||||||
SSDP_ST = "urn:ses-com:device:SatIPServer:1"
|
|
||||||
SSDP_REQUEST = "\r\n".join(
|
|
||||||
[
|
|
||||||
"M-SEARCH * HTTP/1.1",
|
|
||||||
f"HOST: {SSDP_ADDR}:{SSDP_PORT}",
|
|
||||||
'MAN: "ssdp:discover"',
|
|
||||||
f"MX: {SSDP_MX}",
|
|
||||||
f"ST: {SSDP_ST}",
|
|
||||||
"USER-AGENT: vdr-detectsatip",
|
|
||||||
"\r\n",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_satip_xml(data):
|
|
||||||
"""Parse SAT>IP XML data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
data (str): XML input data..
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: Parsed SAT>IP device name and frontend information.
|
|
||||||
"""
|
|
||||||
result = {"name": "", "frontends": {}}
|
|
||||||
if data:
|
|
||||||
root = ET.fromstring(data)
|
|
||||||
name = root.find(".//*/{urn:schemas-upnp-org:device-1-0}friendlyName")
|
|
||||||
result["name"] = name.text
|
|
||||||
satipcap = root.find(".//*/{urn:ses-com:satip}X_SATIPCAP")
|
|
||||||
if satipcap is None:
|
|
||||||
# fallback for non-standard Panasonic
|
|
||||||
satipcap = root.find(".//*/{urn-ses-com:satip}X_SATIPCAP")
|
|
||||||
caps = {}
|
|
||||||
for system in satipcap.text.split(","):
|
|
||||||
cap = system.split("-")
|
|
||||||
if cap:
|
|
||||||
count = int(cap[1])
|
|
||||||
if cap[0] in caps:
|
|
||||||
count = count + caps[cap[0]]
|
|
||||||
caps[cap[0]] = count
|
|
||||||
result["frontends"] = caps
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def detect_satip_devices():
|
|
||||||
"""Detect available SAT>IP devices by sending a broadcast message.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: Found SAT>IP devices.
|
|
||||||
"""
|
|
||||||
urls = []
|
|
||||||
devices = []
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
sock.setblocking(0)
|
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
||||||
try:
|
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
|
|
||||||
except BaseException:
|
|
||||||
pass
|
|
||||||
sock.settimeout(1)
|
|
||||||
sock.bind((SSDP_BIND, SSDP_PORT))
|
|
||||||
sock.sendto(SSDP_REQUEST.encode("utf-8"), (SSDP_ADDR, SSDP_PORT))
|
|
||||||
try:
|
|
||||||
while 1:
|
|
||||||
data = sock.recv(1024).decode("utf-8")
|
|
||||||
if data:
|
|
||||||
for row in data.split("\r\n"):
|
|
||||||
if "LOCATION:" in row:
|
|
||||||
url = row.replace("LOCATION:", "").strip()
|
|
||||||
if url in urls:
|
|
||||||
continue
|
|
||||||
urls.append(url)
|
|
||||||
info = requests.get(url, timeout=2)
|
|
||||||
devices.append(parse_satip_xml(info.text))
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
except BaseException:
|
|
||||||
pass
|
|
||||||
sock.close()
|
|
||||||
return devices
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
json.dump(detect_satip_devices(), fp=sys.stdout, sort_keys=True, indent=2)
|
|
90
device.c
90
device.c
@ -15,17 +15,14 @@
|
|||||||
|
|
||||||
static cSatipDevice * SatipDevicesS[SATIP_MAX_DEVICES] = { NULL };
|
static cSatipDevice * SatipDevicesS[SATIP_MAX_DEVICES] = { NULL };
|
||||||
|
|
||||||
cMutex cSatipDevice::mutexS = cMutex();
|
|
||||||
|
|
||||||
cSatipDevice::cSatipDevice(unsigned int indexP)
|
cSatipDevice::cSatipDevice(unsigned int indexP)
|
||||||
: deviceIndexM(indexP),
|
: deviceIndexM(indexP),
|
||||||
bytesDeliveredM(0),
|
isPacketDeliveredM(false),
|
||||||
isOpenDvrM(false),
|
isOpenDvrM(false),
|
||||||
checkTsBufferM(false),
|
|
||||||
deviceNameM(*cString::sprintf("%s %d", *DeviceType(), deviceIndexM)),
|
deviceNameM(*cString::sprintf("%s %d", *DeviceType(), deviceIndexM)),
|
||||||
channelM(),
|
channelM(),
|
||||||
createdM(0),
|
createdM(0),
|
||||||
tunedM()
|
mutexM()
|
||||||
{
|
{
|
||||||
unsigned int bufsize = (unsigned int)SATIP_BUFFER_SIZE;
|
unsigned int bufsize = (unsigned int)SATIP_BUFFER_SIZE;
|
||||||
bufsize -= (bufsize % TS_SIZE);
|
bufsize -= (bufsize % TS_SIZE);
|
||||||
@ -45,8 +42,6 @@ cSatipDevice::cSatipDevice(unsigned int indexP)
|
|||||||
cSatipDevice::~cSatipDevice()
|
cSatipDevice::~cSatipDevice()
|
||||||
{
|
{
|
||||||
debug1("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug1("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
// Release immediately any pending conditional wait
|
|
||||||
tunedM.Broadcast();
|
|
||||||
// Stop section handler
|
// Stop section handler
|
||||||
StopSectionHandler();
|
StopSectionHandler();
|
||||||
DELETE_POINTER(pSectionFilterHandlerM);
|
DELETE_POINTER(pSectionFilterHandlerM);
|
||||||
@ -108,8 +103,12 @@ cString cSatipDevice::GetSatipStatus(void)
|
|||||||
bool live = (device == cDevice::ActualDevice());
|
bool live = (device == cDevice::ActualDevice());
|
||||||
bool lock = device->HasLock();
|
bool lock = device->HasLock();
|
||||||
const cChannel *channel = device->GetCurrentlyTunedTransponder();
|
const cChannel *channel = device->GetCurrentlyTunedTransponder();
|
||||||
|
#if defined(APIVERSNUM) && APIVERSNUM >= 20301
|
||||||
LOCK_TIMERS_READ;
|
LOCK_TIMERS_READ;
|
||||||
for (const cTimer *timer = Timers->First(); timer; timer = Timers->Next(timer)) {
|
for (const cTimer *timer = Timers->First(); timer; timer = Timers->Next(timer)) {
|
||||||
|
#else
|
||||||
|
for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) {
|
||||||
|
#endif
|
||||||
if (timer->Recording()) {
|
if (timer->Recording()) {
|
||||||
cRecordControl *control = cRecordControls::GetRecordControl(timer);
|
cRecordControl *control = cRecordControls::GetRecordControl(timer);
|
||||||
if (control && control->Device() == device)
|
if (control && control->Device() == device)
|
||||||
@ -138,14 +137,20 @@ cString cSatipDevice::GetSatipStatus(void)
|
|||||||
cString cSatipDevice::GetGeneralInformation(void)
|
cString cSatipDevice::GetGeneralInformation(void)
|
||||||
{
|
{
|
||||||
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
|
#if defined(APIVERSNUM) && APIVERSNUM >= 20301
|
||||||
LOCK_CHANNELS_READ;
|
LOCK_CHANNELS_READ;
|
||||||
|
#endif
|
||||||
return cString::sprintf("SAT>IP device: %d\nCardIndex: %d\nStream: %s\nSignal: %s\nStream bitrate: %s\n%sChannel: %s\n",
|
return cString::sprintf("SAT>IP device: %d\nCardIndex: %d\nStream: %s\nSignal: %s\nStream bitrate: %s\n%sChannel: %s\n",
|
||||||
deviceIndexM, CardIndex(),
|
deviceIndexM, CardIndex(),
|
||||||
pTunerM ? *pTunerM->GetInformation() : "",
|
pTunerM ? *pTunerM->GetInformation() : "",
|
||||||
pTunerM ? *pTunerM->GetSignalStatus() : "",
|
pTunerM ? *pTunerM->GetSignalStatus() : "",
|
||||||
pTunerM ? *pTunerM->GetTunerStatistic() : "",
|
pTunerM ? *pTunerM->GetTunerStatistic() : "",
|
||||||
*GetBufferStatistic(),
|
*GetBufferStatistic(),
|
||||||
|
#if defined(APIVERSNUM) && APIVERSNUM >= 20301
|
||||||
*Channels->GetByNumber(cDevice::CurrentChannel())->ToText());
|
*Channels->GetByNumber(cDevice::CurrentChannel())->ToText());
|
||||||
|
#else
|
||||||
|
*Channels.GetByNumber(cDevice::CurrentChannel())->ToText());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
cString cSatipDevice::GetPidsInformation(void)
|
cString cSatipDevice::GetPidsInformation(void)
|
||||||
@ -216,21 +221,6 @@ bool cSatipDevice::AvoidRecording(void) const
|
|||||||
return SatipConfig.IsOperatingModeLow();
|
return SatipConfig.IsOperatingModeLow();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipDevice::SignalStats(int &Valid, double *Strength, double *Cnr, double *BerPre, double *BerPost, double *Per, int *Status) const
|
|
||||||
{
|
|
||||||
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
|
||||||
Valid = DTV_STAT_VALID_NONE;
|
|
||||||
if (Strength && pTunerM) {
|
|
||||||
*Strength = pTunerM->SignalStrengthDBm();
|
|
||||||
Valid |= DTV_STAT_VALID_STRENGTH;
|
|
||||||
}
|
|
||||||
if (Status) {
|
|
||||||
*Status = HasLock() ? (DTV_STAT_HAS_SIGNAL | DTV_STAT_HAS_CARRIER | DTV_STAT_HAS_VITERBI | DTV_STAT_HAS_SYNC | DTV_STAT_HAS_LOCK) : DTV_STAT_HAS_NONE;
|
|
||||||
Valid |= DTV_STAT_VALID_STATUS;
|
|
||||||
}
|
|
||||||
return Valid != DTV_STAT_VALID_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cSatipDevice::SignalStrength(void) const
|
int cSatipDevice::SignalStrength(void) const
|
||||||
{
|
{
|
||||||
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
@ -295,10 +285,10 @@ bool cSatipDevice::ProvidesChannel(const cChannel *channelP, int priorityP, bool
|
|||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = !!SatipConfig.GetFrontendReuse();
|
result = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
needsDetachReceivers = true;
|
needsDetachReceivers = Receiving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,11 +299,7 @@ bool cSatipDevice::ProvidesChannel(const cChannel *channelP, int priorityP, bool
|
|||||||
|
|
||||||
bool cSatipDevice::ProvidesEIT(void) const
|
bool cSatipDevice::ProvidesEIT(void) const
|
||||||
{
|
{
|
||||||
#if defined(APIVERSNUM) && APIVERSNUM < 20403
|
|
||||||
return (SatipConfig.GetEITScan());
|
return (SatipConfig.GetEITScan());
|
||||||
#else
|
|
||||||
return (SatipConfig.GetEITScan()) && DeviceHooksProvidesEIT();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipDevice::NumProvidedSystems(void) const
|
int cSatipDevice::NumProvidedSystems(void) const
|
||||||
@ -353,7 +339,6 @@ bool cSatipDevice::MaySwitchTransponder(const cChannel *channelP) const
|
|||||||
|
|
||||||
bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
|
bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutexS); // Global lock to prevent any simultaneous zapping
|
|
||||||
debug9("%s (%d, %d) [device %u]", __PRETTY_FUNCTION__, channelP ? channelP->Number() : -1, liveViewP, deviceIndexM);
|
debug9("%s (%d, %d) [device %u]", __PRETTY_FUNCTION__, channelP ? channelP->Number() : -1, liveViewP, deviceIndexM);
|
||||||
if (channelP) {
|
if (channelP) {
|
||||||
cDvbTransponderParameters dtp(channelP->Parameters());
|
cDvbTransponderParameters dtp(channelP->Parameters());
|
||||||
@ -371,8 +356,6 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
|
|||||||
if (pTunerM && pTunerM->SetSource(server, channelP->Transponder(), *params, deviceIndexM)) {
|
if (pTunerM && pTunerM->SetSource(server, channelP->Transponder(), *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));
|
||||||
// Wait for actual channel tuning to prevent simultaneous frontend allocation failures
|
|
||||||
tunedM.TimedWait(mutexS, eTuningTimeoutMs);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -384,17 +367,10 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipDevice::SetChannelTuned(void)
|
|
||||||
{
|
|
||||||
debug9("%s () [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
|
||||||
// Release immediately any pending conditional wait
|
|
||||||
tunedM.Broadcast();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP)
|
bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP)
|
||||||
{
|
{
|
||||||
debug12("%s (%d, %d, %d) [device %u]", __PRETTY_FUNCTION__, handleP ? handleP->pid : -1, typeP, onP, deviceIndexM);
|
debug12("%s (%d, %d, %d) [device %u]", __PRETTY_FUNCTION__, handleP ? handleP->pid : -1, typeP, onP, deviceIndexM);
|
||||||
if (pTunerM && handleP && handleP->pid >= 0 && handleP->pid <= 8191) {
|
if (pTunerM && handleP && handleP->pid >= 0) {
|
||||||
if (onP)
|
if (onP)
|
||||||
return pTunerM->SetPid(handleP->pid, typeP, true);
|
return pTunerM->SetPid(handleP->pid, typeP, true);
|
||||||
else if (!handleP->used && pSectionFilterHandlerM && !pSectionFilterHandlerM->Exists(handleP->pid))
|
else if (!handleP->used && pSectionFilterHandlerM && !pSectionFilterHandlerM->Exists(handleP->pid))
|
||||||
@ -429,7 +405,7 @@ void cSatipDevice::CloseFilter(int handleP)
|
|||||||
bool cSatipDevice::OpenDvr(void)
|
bool cSatipDevice::OpenDvr(void)
|
||||||
{
|
{
|
||||||
debug9("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug9("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
bytesDeliveredM = 0;
|
isPacketDeliveredM = false;
|
||||||
tsBufferM->Clear();
|
tsBufferM->Clear();
|
||||||
if (pTunerM)
|
if (pTunerM)
|
||||||
pTunerM->Open();
|
pTunerM->Open();
|
||||||
@ -448,14 +424,6 @@ void cSatipDevice::CloseDvr(void)
|
|||||||
bool cSatipDevice::HasLock(int timeoutMsP) const
|
bool cSatipDevice::HasLock(int timeoutMsP) const
|
||||||
{
|
{
|
||||||
debug16("%s (%d) [device %d]", __PRETTY_FUNCTION__, timeoutMsP, deviceIndexM);
|
debug16("%s (%d) [device %d]", __PRETTY_FUNCTION__, timeoutMsP, deviceIndexM);
|
||||||
if (timeoutMsP > 0) {
|
|
||||||
cTimeMs timer(timeoutMsP);
|
|
||||||
while (!timer.TimedOut()) {
|
|
||||||
if (pTunerM && pTunerM->HasLock())
|
|
||||||
return true;
|
|
||||||
cCondWait::SleepMs(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (pTunerM && pTunerM->HasLock());
|
return (pTunerM && pTunerM->HasLock());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,17 +491,13 @@ bool cSatipDevice::IsIdle(void)
|
|||||||
return !Receiving();
|
return !Receiving();
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *cSatipDevice::GetData(int *availableP, bool checkTsBuffer)
|
uchar *cSatipDevice::GetData(int *availableP)
|
||||||
{
|
{
|
||||||
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
if (isOpenDvrM && tsBufferM) {
|
if (isOpenDvrM && tsBufferM) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
if (bytesDeliveredM) {
|
if (isPacketDeliveredM)
|
||||||
tsBufferM->Del(bytesDeliveredM);
|
SkipData(TS_SIZE);
|
||||||
bytesDeliveredM = 0;
|
|
||||||
}
|
|
||||||
if (checkTsBuffer && tsBufferM->Available() < TS_SIZE)
|
|
||||||
return NULL;
|
|
||||||
uchar *p = tsBufferM->Get(count);
|
uchar *p = tsBufferM->Get(count);
|
||||||
if (p && count >= TS_SIZE) {
|
if (p && count >= TS_SIZE) {
|
||||||
if (*p != TS_SYNC_BYTE) {
|
if (*p != TS_SYNC_BYTE) {
|
||||||
@ -547,7 +511,7 @@ uchar *cSatipDevice::GetData(int *availableP, bool checkTsBuffer)
|
|||||||
info("Skipped %d bytes to sync on TS packet", count);
|
info("Skipped %d bytes to sync on TS packet", count);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
bytesDeliveredM = TS_SIZE;
|
isPacketDeliveredM = true;
|
||||||
if (availableP)
|
if (availableP)
|
||||||
*availableP = count;
|
*availableP = count;
|
||||||
// Update pid statistics
|
// Update pid statistics
|
||||||
@ -561,7 +525,8 @@ uchar *cSatipDevice::GetData(int *availableP, bool checkTsBuffer)
|
|||||||
void cSatipDevice::SkipData(int countP)
|
void cSatipDevice::SkipData(int countP)
|
||||||
{
|
{
|
||||||
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
bytesDeliveredM = countP;
|
tsBufferM->Del(countP);
|
||||||
|
isPacketDeliveredM = false;
|
||||||
// Update buffer statistics
|
// Update buffer statistics
|
||||||
AddBufferStatistic(countP, tsBufferM->Available());
|
AddBufferStatistic(countP, tsBufferM->Available());
|
||||||
}
|
}
|
||||||
@ -575,12 +540,11 @@ bool cSatipDevice::GetTSPacket(uchar *&dataP)
|
|||||||
if (cCamSlot *cs = CamSlot()) {
|
if (cCamSlot *cs = CamSlot()) {
|
||||||
if (cs->WantsTsData()) {
|
if (cs->WantsTsData()) {
|
||||||
int available;
|
int available;
|
||||||
dataP = GetData(&available, checkTsBufferM);
|
dataP = GetData(&available);
|
||||||
if (!dataP)
|
if (dataP) {
|
||||||
available = 0;
|
dataP = cs->Decrypt(dataP, available);
|
||||||
dataP = cs->Decrypt(dataP, available);
|
SkipData(available);
|
||||||
SkipData(available);
|
}
|
||||||
checkTsBufferM = dataP != NULL;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
device.h
16
device.h
@ -18,7 +18,7 @@
|
|||||||
class cSatipDevice : public cDevice, public cSatipPidStatistics, public cSatipBufferStatistics, public cSatipDeviceIf {
|
class cSatipDevice : public cDevice, public cSatipPidStatistics, public cSatipBufferStatistics, public cSatipDeviceIf {
|
||||||
// static ones
|
// static ones
|
||||||
public:
|
public:
|
||||||
static cMutex mutexS;
|
static unsigned int deviceCount;
|
||||||
static bool Initialize(unsigned int DeviceCount);
|
static bool Initialize(unsigned int DeviceCount);
|
||||||
static void Shutdown(void);
|
static void Shutdown(void);
|
||||||
static unsigned int Count(void);
|
static unsigned int Count(void);
|
||||||
@ -28,20 +28,18 @@ public:
|
|||||||
// private parts
|
// private parts
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
eReadyTimeoutMs = 2000, // in milliseconds
|
eReadyTimeoutMs = 2000 // in milliseconds
|
||||||
eTuningTimeoutMs = 1000 // in milliseconds
|
|
||||||
};
|
};
|
||||||
unsigned int deviceIndexM;
|
unsigned int deviceIndexM;
|
||||||
int bytesDeliveredM;
|
bool isPacketDeliveredM;
|
||||||
bool isOpenDvrM;
|
bool isOpenDvrM;
|
||||||
bool checkTsBufferM;
|
|
||||||
cString deviceNameM;
|
cString deviceNameM;
|
||||||
cChannel channelM;
|
cChannel channelM;
|
||||||
cRingBufferLinear *tsBufferM;
|
cRingBufferLinear *tsBufferM;
|
||||||
cSatipTuner *pTunerM;
|
cSatipTuner *pTunerM;
|
||||||
cSatipSectionFilterHandler *pSectionFilterHandlerM;
|
cSatipSectionFilterHandler *pSectionFilterHandlerM;
|
||||||
cTimeMs createdM;
|
cTimeMs createdM;
|
||||||
cCondVar tunedM;
|
cMutex mutexM;
|
||||||
|
|
||||||
// constructor & destructor
|
// constructor & destructor
|
||||||
public:
|
public:
|
||||||
@ -65,7 +63,6 @@ public:
|
|||||||
virtual cString DeviceType(void) const;
|
virtual cString DeviceType(void) const;
|
||||||
virtual cString DeviceName(void) const;
|
virtual cString DeviceName(void) const;
|
||||||
virtual bool AvoidRecording(void) const;
|
virtual bool AvoidRecording(void) const;
|
||||||
virtual bool SignalStats(int &Valid, double *Strength = NULL, double *Cnr = NULL, double *BerPre = NULL, double *BerPost = NULL, double *Per = NULL, int *Status = NULL) const;
|
|
||||||
virtual int SignalStrength(void) const;
|
virtual int SignalStrength(void) const;
|
||||||
virtual int SignalQuality(void) const;
|
virtual int SignalQuality(void) const;
|
||||||
|
|
||||||
@ -85,7 +82,7 @@ protected:
|
|||||||
|
|
||||||
// for recording
|
// for recording
|
||||||
private:
|
private:
|
||||||
uchar *GetData(int *availableP = NULL, bool checkTsBuffer = false);
|
uchar *GetData(int *availableP = NULL);
|
||||||
void SkipData(int countP);
|
void SkipData(int countP);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -101,7 +98,7 @@ public:
|
|||||||
|
|
||||||
// for transponder lock
|
// for transponder lock
|
||||||
public:
|
public:
|
||||||
virtual bool HasLock(int timeoutMsP = 0) const;
|
virtual bool HasLock(int timeoutMsP) const;
|
||||||
|
|
||||||
// for common interface
|
// for common interface
|
||||||
public:
|
public:
|
||||||
@ -110,7 +107,6 @@ public:
|
|||||||
// for internal device interface
|
// for internal device interface
|
||||||
public:
|
public:
|
||||||
virtual void WriteData(u_char *bufferP, int lengthP);
|
virtual void WriteData(u_char *bufferP, int lengthP);
|
||||||
virtual void SetChannelTuned(void);
|
|
||||||
virtual int GetId(void);
|
virtual int GetId(void);
|
||||||
virtual int GetPmtPid(void);
|
virtual int GetPmtPid(void);
|
||||||
virtual int GetCISlot(void);
|
virtual int GetCISlot(void);
|
||||||
|
@ -13,7 +13,6 @@ public:
|
|||||||
cSatipDeviceIf() {}
|
cSatipDeviceIf() {}
|
||||||
virtual ~cSatipDeviceIf() {}
|
virtual ~cSatipDeviceIf() {}
|
||||||
virtual void WriteData(u_char *bufferP, int lengthP) = 0;
|
virtual void WriteData(u_char *bufferP, int lengthP) = 0;
|
||||||
virtual void SetChannelTuned(void) = 0;
|
|
||||||
virtual int GetId(void) = 0;
|
virtual int GetId(void) = 0;
|
||||||
virtual int GetPmtPid(void) = 0;
|
virtual int GetPmtPid(void) = 0;
|
||||||
virtual int GetCISlot(void) = 0;
|
virtual int GetCISlot(void) = 0;
|
||||||
|
29
discover.c
29
discover.c
@ -30,10 +30,10 @@ bool cSatipDiscover::Initialize(cSatipDiscoverServers *serversP)
|
|||||||
{
|
{
|
||||||
debug1("%s", __PRETTY_FUNCTION__);
|
debug1("%s", __PRETTY_FUNCTION__);
|
||||||
if (instanceS) {
|
if (instanceS) {
|
||||||
if (serversP) {
|
if (serversP) {
|
||||||
for (cSatipDiscoverServer *s = serversP->First(); s; s = serversP->Next(s))
|
for (cSatipDiscoverServer *s = serversP->First(); s; s = serversP->Next(s))
|
||||||
instanceS->AddServer(s->SrcAddress(), s->IpAddress(), s->IpPort(), s->Model(), s->Filters(), s->Description(), s->Quirk());
|
instanceS->AddServer(s->IpAddress(), s->IpPort(), s->Model(), s->Filters(), s->Description(), s->Quirk());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
instanceS->Activate();
|
instanceS->Activate();
|
||||||
}
|
}
|
||||||
@ -271,12 +271,12 @@ void cSatipDiscover::ParseDeviceInfo(const char *addrP, const int portP)
|
|||||||
model = modelNode.text().as_string("DVBS2-1");
|
model = modelNode.text().as_string("DVBS2-1");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
AddServer(NULL, addrP, portP, model, NULL, desc, cSatipServer::eSatipQuirkNone);
|
AddServer(addrP, portP, model, NULL, desc, cSatipServer::eSatipQuirkNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipDiscover::AddServer(const char *srcAddrP, const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP)
|
void cSatipDiscover::AddServer(const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP)
|
||||||
{
|
{
|
||||||
debug1("%s (%s, %s, %d, %s, %s, %s, %d)", __PRETTY_FUNCTION__, srcAddrP, addrP, portP, modelP, filtersP, descP, quirkP);
|
debug1("%s (%s, %d, %s, %s, %s, %d)", __PRETTY_FUNCTION__, addrP, portP, modelP, filtersP, descP, quirkP);
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
if (SatipConfig.GetUseSingleModelServers() && modelP && !isempty(modelP)) {
|
if (SatipConfig.GetUseSingleModelServers() && modelP && !isempty(modelP)) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@ -285,9 +285,9 @@ void cSatipDiscover::AddServer(const char *srcAddrP, const char *addrP, const in
|
|||||||
while (r) {
|
while (r) {
|
||||||
r = skipspace(r);
|
r = skipspace(r);
|
||||||
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(srcAddrP, addrP, portP, r, filtersP, desc, quirkP);
|
cSatipServer *tmp = new cSatipServer(addrP, portP, r, filtersP, desc, quirkP);
|
||||||
if (!serversM.Update(tmp)) {
|
if (!serversM.Update(tmp)) {
|
||||||
info("Adding server '%s|%s|%s' Bind: %s Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->SrcAddress()) ? tmp->SrcAddress() : "default", !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
|
info("Adding server '%s|%s|%s' Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
|
||||||
serversM.Add(tmp);
|
serversM.Add(tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -297,9 +297,9 @@ void cSatipDiscover::AddServer(const char *srcAddrP, const char *addrP, const in
|
|||||||
FREE_POINTER(p);
|
FREE_POINTER(p);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cSatipServer *tmp = new cSatipServer(srcAddrP, addrP, portP, modelP, filtersP, descP, quirkP);
|
cSatipServer *tmp = new cSatipServer(addrP, portP, modelP, filtersP, descP, quirkP);
|
||||||
if (!serversM.Update(tmp)) {
|
if (!serversM.Update(tmp)) {
|
||||||
info("Adding server '%s|%s|%s' Bind: %s Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->SrcAddress()) ? tmp->SrcAddress() : "default", !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
|
info("Adding server '%s|%s|%s' Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
|
||||||
serversM.Add(tmp);
|
serversM.Add(tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -391,13 +391,6 @@ bool cSatipDiscover::HasServerCI(cSatipServer *serverP)
|
|||||||
return serversM.HasCI(serverP);
|
return serversM.HasCI(serverP);
|
||||||
}
|
}
|
||||||
|
|
||||||
cString cSatipDiscover::GetSourceAddress(cSatipServer *serverP)
|
|
||||||
{
|
|
||||||
debug16("%s", __PRETTY_FUNCTION__);
|
|
||||||
cMutexLock MutexLock(&mutexM);
|
|
||||||
return serversM.GetSrcAddress(serverP);
|
|
||||||
}
|
|
||||||
|
|
||||||
cString cSatipDiscover::GetServerAddress(cSatipServer *serverP)
|
cString cSatipDiscover::GetServerAddress(cSatipServer *serverP)
|
||||||
{
|
{
|
||||||
debug16("%s", __PRETTY_FUNCTION__);
|
debug16("%s", __PRETTY_FUNCTION__);
|
||||||
|
@ -23,19 +23,17 @@ class cSatipDiscoverServer : public cListObject {
|
|||||||
private:
|
private:
|
||||||
int ipPortM;
|
int ipPortM;
|
||||||
int quirkM;
|
int quirkM;
|
||||||
cString srcAddressM;
|
|
||||||
cString ipAddressM;
|
cString ipAddressM;
|
||||||
cString descriptionM;
|
cString descriptionM;
|
||||||
cString modelM;
|
cString modelM;
|
||||||
cString filtersM;
|
cString filtersM;
|
||||||
public:
|
public:
|
||||||
cSatipDiscoverServer(const char *srcAddressP, const char *ipAddressP, const int ipPortP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP)
|
cSatipDiscoverServer(const char *ipAddressP, const int ipPortP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP)
|
||||||
{
|
{
|
||||||
srcAddressM = srcAddressP; ipAddressM = ipAddressP; ipPortM = ipPortP; modelM = modelP; filtersM = filtersP; descriptionM = descriptionP; quirkM = quirkP;
|
ipAddressM = ipAddressP; ipPortM = ipPortP; modelM = modelP; filtersM = filtersP; descriptionM = descriptionP; quirkM = quirkP;
|
||||||
}
|
}
|
||||||
int IpPort(void) { return ipPortM; }
|
int IpPort(void) { return ipPortM; }
|
||||||
int Quirk(void) { return quirkM; }
|
int Quirk(void) { return quirkM; }
|
||||||
const char *SrcAddress(void) { return *srcAddressM; }
|
|
||||||
const char *IpAddress(void) { return *ipAddressM; }
|
const char *IpAddress(void) { return *ipAddressM; }
|
||||||
const char *Model(void) { return *modelM; }
|
const char *Model(void) { return *modelM; }
|
||||||
const char *Filters(void) { return *filtersM; }
|
const char *Filters(void) { return *filtersM; }
|
||||||
@ -71,7 +69,7 @@ private:
|
|||||||
void Deactivate(void);
|
void Deactivate(void);
|
||||||
int ParseRtspPort(void);
|
int ParseRtspPort(void);
|
||||||
void ParseDeviceInfo(const char *addrP, const int portP);
|
void ParseDeviceInfo(const char *addrP, const int portP);
|
||||||
void AddServer(const char *srcAddrP, const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP);
|
void AddServer(const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP);
|
||||||
void Fetch(const char *urlP);
|
void Fetch(const char *urlP);
|
||||||
// constructor
|
// constructor
|
||||||
cSatipDiscover();
|
cSatipDiscover();
|
||||||
@ -100,7 +98,6 @@ public:
|
|||||||
bool IsServerQuirk(cSatipServer *serverP, int quirkP);
|
bool IsServerQuirk(cSatipServer *serverP, int quirkP);
|
||||||
bool HasServerCI(cSatipServer *serverP);
|
bool HasServerCI(cSatipServer *serverP);
|
||||||
cString GetServerAddress(cSatipServer *serverP);
|
cString GetServerAddress(cSatipServer *serverP);
|
||||||
cString GetSourceAddress(cSatipServer *serverP);
|
|
||||||
int GetServerPort(cSatipServer *serverP);
|
int GetServerPort(cSatipServer *serverP);
|
||||||
cString GetServerList(void);
|
cString GetServerList(void);
|
||||||
int NumProvidedSystems(void);
|
int NumProvidedSystems(void);
|
||||||
|
@ -76,13 +76,13 @@ void cSatipMsearch::Process(void)
|
|||||||
if (status) {
|
if (status) {
|
||||||
// Check the location data
|
// Check the location data
|
||||||
// LOCATION: http://192.168.0.115:8888/octonet.xml
|
// LOCATION: http://192.168.0.115:8888/octonet.xml
|
||||||
if (strcasestr(r, "LOCATION:") == r) {
|
if (startswith(r, "LOCATION:")) {
|
||||||
location = compactspace(r + 9);
|
location = compactspace(r + 9);
|
||||||
debug1("%s location='%s'", __PRETTY_FUNCTION__, location);
|
debug1("%s location='%s'", __PRETTY_FUNCTION__, location);
|
||||||
}
|
}
|
||||||
// Check the source type
|
// Check the source type
|
||||||
// ST: urn:ses-com:device:SatIPServer:1
|
// ST: urn:ses-com:device:SatIPServer:1
|
||||||
else if (strcasestr(r, "ST:") == r) {
|
else if (startswith(r, "ST:")) {
|
||||||
char *st = compactspace(r + 3);
|
char *st = compactspace(r + 3);
|
||||||
if (strstr(st, "urn:ses-com:device:SatIPServer:1"))
|
if (strstr(st, "urn:ses-com:device:SatIPServer:1"))
|
||||||
valid = true;
|
valid = true;
|
||||||
|
63
param.c
63
param.c
@ -59,10 +59,6 @@ static const tSatipParameterMap SatipCodeRateValues[] = {
|
|||||||
static const tSatipParameterMap SatipModulationValues[] = {
|
static const tSatipParameterMap SatipModulationValues[] = {
|
||||||
{ QPSK, "&mtype=qpsk" },
|
{ QPSK, "&mtype=qpsk" },
|
||||||
{ PSK_8, "&mtype=8psk" },
|
{ PSK_8, "&mtype=8psk" },
|
||||||
{ APSK_16, "&mtype=16apsk" },
|
|
||||||
{ APSK_32, "&mtype=32apsk" },
|
|
||||||
{ VSB_8, "&mtype=8vsb" },
|
|
||||||
{ VSB_16, "&mtype=16vsb" },
|
|
||||||
{ QAM_16, "&mtype=16qam" },
|
{ QAM_16, "&mtype=16qam" },
|
||||||
{ QAM_64, "&mtype=64qam" },
|
{ QAM_64, "&mtype=64qam" },
|
||||||
{ QAM_128, "&mtype=128qam" },
|
{ QAM_128, "&mtype=128qam" },
|
||||||
@ -89,11 +85,6 @@ static const tSatipParameterMap SatipSystemValuesCable[] = {
|
|||||||
{ -1, NULL }
|
{ -1, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const tSatipParameterMap SatipSystemValuesAtsc[] = {
|
|
||||||
{ 0, "&msys=atsc" },
|
|
||||||
{ -1, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const tSatipParameterMap SatipTransmissionValues[] = {
|
static const tSatipParameterMap SatipTransmissionValues[] = {
|
||||||
{ TRANSMISSION_MODE_1K, "&tmode=1k" },
|
{ TRANSMISSION_MODE_1K, "&tmode=1k" },
|
||||||
{ TRANSMISSION_MODE_2K, "&tmode=2k" },
|
{ TRANSMISSION_MODE_2K, "&tmode=2k" },
|
||||||
@ -174,36 +165,32 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
|
|||||||
}
|
}
|
||||||
if ((channelP->Rid() % 100) > 0)
|
if ((channelP->Rid() % 100) > 0)
|
||||||
q += snprintf(q, STBUFLEFT, "&fe=%d", channelP->Rid() % 100);
|
q += snprintf(q, STBUFLEFT, "&fe=%d", channelP->Rid() % 100);
|
||||||
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);
|
||||||
if (freq >= 0L)
|
q += snprintf(q, STBUFLEFT, "freq=%s", *dtoa(freq, "%lg"));
|
||||||
q += snprintf(q, STBUFLEFT, "&freq=%s", *dtoa(freq, "%lg"));
|
ST(" S *") q += snprintf(q, STBUFLEFT, "&pol=%c", tolower(dtp.Polarization()));
|
||||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&pol=%c", tolower(dtp.Polarization()));
|
ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.RollOff(), SatipRollOffValues);
|
||||||
ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.RollOff(), SatipRollOffValues);
|
ST("C 2") q += snprintf(q, STBUFLEFT, "&c2tft=%d", C2TuningFrequencyType);
|
||||||
ST(" C 2") q += snprintf(q, STBUFLEFT, "&c2tft=%d", C2TuningFrequencyType);
|
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(" 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("A *") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesAtsc);
|
ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
||||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Transmission(), SatipTransmissionValues);
|
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
||||||
ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
ST("C 1") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
||||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Pilot(), SatipPilotValues);
|
||||||
ST(" C 1") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
ST(" S *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
||||||
ST("A *") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
ST("C 1") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
||||||
ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Pilot(), SatipPilotValues);
|
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Guard(), SatipGuardValues);
|
||||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
ST("CST*") q += PrintUrlString(q, STBUFLEFT, dtp.CoderateH(), SatipCodeRateValues);
|
||||||
ST(" C 1") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
ST("C 2") q += snprintf(q, STBUFLEFT, "&ds=%d", DataSlice);
|
||||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Guard(), SatipGuardValues);
|
ST("C T2") q += snprintf(q, STBUFLEFT, "&plp=%d", dtp.StreamId());
|
||||||
ST(" CST*") q += PrintUrlString(q, STBUFLEFT, dtp.CoderateH(), SatipCodeRateValues);
|
ST(" T2") q += snprintf(q, STBUFLEFT, "&t2id=%d", dtp.T2SystemId());
|
||||||
ST(" C 2") q += snprintf(q, STBUFLEFT, "&ds=%d", DataSlice);
|
ST(" T2") q += PrintUrlString(q, STBUFLEFT, dtp.SisoMiso(), SatipSisoMisoValues);
|
||||||
ST(" C T2") q += snprintf(q, STBUFLEFT, "&plp=%d", dtp.StreamId());
|
ST("C 1") q += PrintUrlString(q, STBUFLEFT, dtp.Inversion(), SatipInversionValues);
|
||||||
ST(" T2") q += snprintf(q, STBUFLEFT, "&t2id=%d", dtp.T2SystemId());
|
|
||||||
ST(" T2") q += PrintUrlString(q, STBUFLEFT, dtp.SisoMiso(), SatipSisoMisoValues);
|
|
||||||
ST(" C 1") q += PrintUrlString(q, STBUFLEFT, dtp.Inversion(), SatipInversionValues);
|
|
||||||
ST("A *") q += PrintUrlString(q, STBUFLEFT, dtp.Inversion(), SatipInversionValues);
|
|
||||||
#undef ST
|
#undef ST
|
||||||
return &buffer[1];
|
return buffer;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
24
po/ca_ES.po
24
po/ca_ES.po
@ -1,14 +1,14 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2019 Rolf Ahrenberg
|
# Copyright (C) 2007-2016 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the satip package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Gabriel Bonich, 2014-2017
|
# Gabriel Bonich, 2014-2015
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 2.4.0\n"
|
"Project-Id-Version: vdr-satip 2.2.4\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
"POT-Creation-Date: 2016-12-18 12:18+0200\n"
|
||||||
"PO-Revision-Date: 2019-10-27 10:27+0200\n"
|
"PO-Revision-Date: 2016-12-18 12:18+0200\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"
|
||||||
@ -86,13 +86,13 @@ msgid "high"
|
|||||||
msgstr "Alt"
|
msgstr "Alt"
|
||||||
|
|
||||||
msgid "Unicast"
|
msgid "Unicast"
|
||||||
msgstr "Unicast"
|
msgstr ""
|
||||||
|
|
||||||
msgid "Multicast"
|
msgid "Multicast"
|
||||||
msgstr "Multicast"
|
msgstr ""
|
||||||
|
|
||||||
msgid "RTP-over-TCP"
|
msgid "RTP-over-TCP"
|
||||||
msgstr "RTP-per sobre-TCP"
|
msgstr ""
|
||||||
|
|
||||||
msgid "Button$Devices"
|
msgid "Button$Devices"
|
||||||
msgstr "Dispositius"
|
msgstr "Dispositius"
|
||||||
@ -188,7 +188,7 @@ msgid "Define an ill-behaving filter to be blacklisted."
|
|||||||
msgstr "Definir un filtre mal comportar a la llista negra."
|
msgstr "Definir un filtre mal comportar a la llista negra."
|
||||||
|
|
||||||
msgid "Transport mode"
|
msgid "Transport mode"
|
||||||
msgstr "Tipus de Transmissió"
|
msgstr ""
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Define which transport mode shall be used.\n"
|
"Define which transport mode shall be used.\n"
|
||||||
@ -196,12 +196,6 @@ msgid ""
|
|||||||
"Unicast, Multicast, RTP-over-TCP"
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Enable frontend reuse"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Define whether reusing a frontend for multiple channels in a transponder should be enabled."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Active SAT>IP servers:"
|
msgid "Active SAT>IP servers:"
|
||||||
msgstr "Activa SAT>IP servers:"
|
msgstr "Activa SAT>IP servers:"
|
||||||
|
|
||||||
|
24
po/de_DE.po
24
po/de_DE.po
@ -1,14 +1,14 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2019 Rolf Ahrenberg
|
# Copyright (C) 2007-2016 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the satip package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Frank Neumann, 2014-2017
|
# Frank Neumann, 2014-2016
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 2.4.0\n"
|
"Project-Id-Version: vdr-satip 2.2.4\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
"POT-Creation-Date: 2016-12-18 12:18+0200\n"
|
||||||
"PO-Revision-Date: 2019-10-27 10:27+0200\n"
|
"PO-Revision-Date: 2016-12-18 12:18+0200\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"
|
||||||
@ -56,7 +56,7 @@ msgid "Creation date"
|
|||||||
msgstr "Zeitpunkt der Erstellung"
|
msgstr "Zeitpunkt der Erstellung"
|
||||||
|
|
||||||
msgid "SAT>IP Device Status"
|
msgid "SAT>IP Device Status"
|
||||||
msgstr "SAT>IP Gerätestatus"
|
msgstr "SAT>IP Geräte Status"
|
||||||
|
|
||||||
msgid "SAT>IP Information"
|
msgid "SAT>IP Information"
|
||||||
msgstr "SAT>IP Informationen"
|
msgstr "SAT>IP Informationen"
|
||||||
@ -110,10 +110,10 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Bestimme die Betriebsart für alle SAT>IP Geräte:\n"
|
"Bestimme die Betriebsart für alle SAT>IP Geräte:\n"
|
||||||
"\n"
|
"\n"
|
||||||
"aus - Geräte sind deaktiviert\n"
|
"aus - Geräte sind abgeschaltet\n"
|
||||||
"niedrig - Geräte arbeiten mit geringster Priorität\n"
|
"niedrig - Geräte arbeiten mit geringster Priorität\n"
|
||||||
"normal - Geräte arbeiten innerhalb der gewöhnlichen Parameter\n"
|
"normal - Geräte arbeiten innerhalb der gewöhnlichen Parameter\n"
|
||||||
"hoch - Geräte arbeiten mit höchster Priorität"
|
"hoch - Geräte arbeiten mit höchste Priorität"
|
||||||
|
|
||||||
msgid "Enable CI extension"
|
msgid "Enable CI extension"
|
||||||
msgstr "Aktiviere CI Erweiterung"
|
msgstr "Aktiviere CI Erweiterung"
|
||||||
@ -149,7 +149,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Legt fest ob EPG im Hintergrund aktualisiert werden soll oder nicht.\n"
|
"Legt fest ob EPG im Hintergrund aktualisiert werden soll oder nicht.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Diese Einstellung schaltet die automatische EIT Aktualisierung für alle SAT>IP Geräte aus."
|
"Diese Einstellung schaltet die automatische EIT Aktualisierung für alle SAT>IP Geräte."
|
||||||
|
|
||||||
msgid "Disabled sources"
|
msgid "Disabled sources"
|
||||||
msgstr "Deaktivierte Quellen"
|
msgstr "Deaktivierte Quellen"
|
||||||
@ -199,12 +199,6 @@ msgstr ""
|
|||||||
"\n"
|
"\n"
|
||||||
"Unicast, Multicast, RTP-over-TCP"
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
|
|
||||||
msgid "Enable frontend reuse"
|
|
||||||
msgstr "Frontend Mehrfachnutzung aktivieren"
|
|
||||||
|
|
||||||
msgid "Define whether reusing a frontend for multiple channels in a transponder should be enabled."
|
|
||||||
msgstr "Festlegung ob ein Tuner-Frontend für mehrere Kanäle genutzt wird."
|
|
||||||
|
|
||||||
msgid "Active SAT>IP servers:"
|
msgid "Active SAT>IP servers:"
|
||||||
msgstr "Aktive SAT>IP Server:"
|
msgstr "Aktive SAT>IP Server:"
|
||||||
|
|
||||||
|
24
po/es_ES.po
24
po/es_ES.po
@ -1,14 +1,14 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2019 Rolf Ahrenberg
|
# Copyright (C) 2007-2016 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the satip package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Gabriel Bonich, 2014-2017
|
# Gabriel Bonich, 2014-2015
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 2.4.0\n"
|
"Project-Id-Version: vdr-satip 2.2.4\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
"POT-Creation-Date: 2016-12-18 12:18+0200\n"
|
||||||
"PO-Revision-Date: 2019-10-27 10:27+0200\n"
|
"PO-Revision-Date: 2016-12-18 12:18+0200\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"
|
||||||
@ -86,13 +86,13 @@ msgid "high"
|
|||||||
msgstr "Alto"
|
msgstr "Alto"
|
||||||
|
|
||||||
msgid "Unicast"
|
msgid "Unicast"
|
||||||
msgstr "Unicast"
|
msgstr ""
|
||||||
|
|
||||||
msgid "Multicast"
|
msgid "Multicast"
|
||||||
msgstr "Multicast"
|
msgstr ""
|
||||||
|
|
||||||
msgid "RTP-over-TCP"
|
msgid "RTP-over-TCP"
|
||||||
msgstr "RTP-antes que-TCP"
|
msgstr ""
|
||||||
|
|
||||||
msgid "Button$Devices"
|
msgid "Button$Devices"
|
||||||
msgstr "Dispositivos"
|
msgstr "Dispositivos"
|
||||||
@ -188,7 +188,7 @@ msgid "Define an ill-behaving filter to be blacklisted."
|
|||||||
msgstr "Define un filtro para poner en la lista negra."
|
msgstr "Define un filtro para poner en la lista negra."
|
||||||
|
|
||||||
msgid "Transport mode"
|
msgid "Transport mode"
|
||||||
msgstr "Tipo de Transmisión"
|
msgstr ""
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Define which transport mode shall be used.\n"
|
"Define which transport mode shall be used.\n"
|
||||||
@ -196,12 +196,6 @@ msgid ""
|
|||||||
"Unicast, Multicast, RTP-over-TCP"
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Enable frontend reuse"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Define whether reusing a frontend for multiple channels in a transponder should be enabled."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Active SAT>IP servers:"
|
msgid "Active SAT>IP servers:"
|
||||||
msgstr "Activa SAT>IP servers:"
|
msgstr "Activa SAT>IP servers:"
|
||||||
|
|
||||||
|
16
po/fi_FI.po
16
po/fi_FI.po
@ -1,14 +1,14 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2019 Rolf Ahrenberg
|
# Copyright (C) 2007-2016 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the satip package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Rolf Ahrenberg, 2015-2019
|
# Rolf Ahrenberg, 2015-2016
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 2.4.0\n"
|
"Project-Id-Version: vdr-satip 2.2.4\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
"POT-Creation-Date: 2016-12-18 12:18+0200\n"
|
||||||
"PO-Revision-Date: 2019-10-27 10:27+0200\n"
|
"PO-Revision-Date: 2016-12-18 12:18+0200\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"
|
||||||
@ -198,12 +198,6 @@ msgstr ""
|
|||||||
"\n"
|
"\n"
|
||||||
"Unicast, Multicast, RTP-over-TCP"
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
|
|
||||||
msgid "Enable frontend reuse"
|
|
||||||
msgstr "Uusiokäytä virittimiä"
|
|
||||||
|
|
||||||
msgid "Define whether reusing a frontend for multiple channels in a transponder should be enabled."
|
|
||||||
msgstr "Määrittele virittien uusiokäyttö kanaville, jotka ovat samalla transponderilla."
|
|
||||||
|
|
||||||
msgid "Active SAT>IP servers:"
|
msgid "Active SAT>IP servers:"
|
||||||
msgstr "Aktiiviset SAT>IP-palvelimet:"
|
msgstr "Aktiiviset SAT>IP-palvelimet:"
|
||||||
|
|
||||||
|
212
po/pl_PL.po
212
po/pl_PL.po
@ -1,212 +0,0 @@
|
|||||||
# VDR plugin language source file.
|
|
||||||
# Copyright (C) 2007-2019 Rolf Ahrenberg
|
|
||||||
# This file is distributed under the same license as the vdr-satip package.
|
|
||||||
# Tomasz Maciej Nowak, 2017
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: vdr-satip 2.4.0\n"
|
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
|
||||||
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
|
||||||
"PO-Revision-Date: 2019-10-27 10:27+0200\n"
|
|
||||||
"Last-Translator: Tomasz Maciej Nowak <tomek_n@o2.pl>\n"
|
|
||||||
"Language-Team: Polish <vdr@linuxtv.org>\n"
|
|
||||||
"Language: pl_PL\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"X-Generator: Poedit 1.8.11\n"
|
|
||||||
|
|
||||||
msgid "PAT (0x00)"
|
|
||||||
msgstr "PAT (0x00)"
|
|
||||||
|
|
||||||
msgid "NIT (0x40)"
|
|
||||||
msgstr "NIT (0x40)"
|
|
||||||
|
|
||||||
msgid "SDT (0x42)"
|
|
||||||
msgstr "SDT (0x42)"
|
|
||||||
|
|
||||||
msgid "EIT (0x4E/0x4F/0x5X/0x6X)"
|
|
||||||
msgstr "EIT (0x4E/0x4F/0x5X/0x6X)"
|
|
||||||
|
|
||||||
msgid "TDT (0x70)"
|
|
||||||
msgstr "TDT (0x70)"
|
|
||||||
|
|
||||||
msgid "SAT>IP information not available!"
|
|
||||||
msgstr "Informacja o SAT>IP niedostępna!"
|
|
||||||
|
|
||||||
msgid "SAT>IP Devices"
|
|
||||||
msgstr "Urządzenia SAT>IP"
|
|
||||||
|
|
||||||
msgid "SAT>IP Server"
|
|
||||||
msgstr "Serwer SAT>IP"
|
|
||||||
|
|
||||||
msgid "Address"
|
|
||||||
msgstr "Adres"
|
|
||||||
|
|
||||||
msgid "Model"
|
|
||||||
msgstr "Model"
|
|
||||||
|
|
||||||
msgid "Description"
|
|
||||||
msgstr "Opis"
|
|
||||||
|
|
||||||
msgid "CI extension"
|
|
||||||
msgstr "Rozszerzenie CI"
|
|
||||||
|
|
||||||
msgid "Creation date"
|
|
||||||
msgstr "Data produkcji"
|
|
||||||
|
|
||||||
msgid "SAT>IP Device Status"
|
|
||||||
msgstr "Status urządzenia SAT>IP"
|
|
||||||
|
|
||||||
msgid "SAT>IP Information"
|
|
||||||
msgstr "SAT>IP - informacje"
|
|
||||||
|
|
||||||
msgid "General"
|
|
||||||
msgstr "Główne"
|
|
||||||
|
|
||||||
msgid "Pids"
|
|
||||||
msgstr "Pidy"
|
|
||||||
|
|
||||||
msgid "Filters"
|
|
||||||
msgstr "Filtry"
|
|
||||||
|
|
||||||
msgid "Bits/bytes"
|
|
||||||
msgstr "Bity/bajty"
|
|
||||||
|
|
||||||
msgid "off"
|
|
||||||
msgstr "wyłączone"
|
|
||||||
|
|
||||||
msgid "low"
|
|
||||||
msgstr "niski"
|
|
||||||
|
|
||||||
msgid "normal"
|
|
||||||
msgstr "normalny"
|
|
||||||
|
|
||||||
msgid "high"
|
|
||||||
msgstr "wysoki"
|
|
||||||
|
|
||||||
msgid "Unicast"
|
|
||||||
msgstr "Unicast"
|
|
||||||
|
|
||||||
msgid "Multicast"
|
|
||||||
msgstr "Multicast"
|
|
||||||
|
|
||||||
msgid "RTP-over-TCP"
|
|
||||||
msgstr "RTP-over-TCP"
|
|
||||||
|
|
||||||
msgid "Button$Devices"
|
|
||||||
msgstr "Urządzenia"
|
|
||||||
|
|
||||||
msgid "Operating mode"
|
|
||||||
msgstr "Tryb pracy"
|
|
||||||
|
|
||||||
msgid ""
|
|
||||||
"Define the used operating mode for all SAT>IP devices:\n"
|
|
||||||
"\n"
|
|
||||||
"off - devices are disabled\n"
|
|
||||||
"low - devices are working at the lowest priority\n"
|
|
||||||
"normal - devices are working within normal parameters\n"
|
|
||||||
"high - devices are working at the highest priority"
|
|
||||||
msgstr ""
|
|
||||||
"Określa tryb pracy wszystkich urządzeń SAT>IP:\n"
|
|
||||||
"\n"
|
|
||||||
"wyłączone - urządzenia są wyłączone\n"
|
|
||||||
"niski - urządzenia pracują z najniższym priorytetem\n"
|
|
||||||
"normalny - urządzenia pracują z normalnymi parametrami\n"
|
|
||||||
"wysoki - urządzenia pracują z najwyższym priorytetem"
|
|
||||||
|
|
||||||
msgid "Enable CI extension"
|
|
||||||
msgstr "Włącz rozszerzenie CI"
|
|
||||||
|
|
||||||
msgid ""
|
|
||||||
"Define whether a CI extension shall be used.\n"
|
|
||||||
"\n"
|
|
||||||
"This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)."
|
|
||||||
msgstr ""
|
|
||||||
"Określa czy korzystać z rozszerzenia CI.\n"
|
|
||||||
"\n"
|
|
||||||
"To ustawienie włącza obsługę dostępnego czytnika CI/CAM w niektórych urządzeniach SAT>IP (np. Digital Devices OctopusNet)."
|
|
||||||
|
|
||||||
msgid "CI/CAM"
|
|
||||||
msgstr "CI/CAM"
|
|
||||||
|
|
||||||
msgid ""
|
|
||||||
"Define a desired CAM type for the CI slot.\n"
|
|
||||||
"\n"
|
|
||||||
"The '---' option lets SAT>IP hardware do the auto-selection."
|
|
||||||
msgstr ""
|
|
||||||
"Określa typ modułu CAM w czytniku CI.\n"
|
|
||||||
"\n"
|
|
||||||
"Opcja '---' pozwala urządzeniu SAT>IP automatycznie wybrać typ."
|
|
||||||
|
|
||||||
msgid "Enable EPG scanning"
|
|
||||||
msgstr "Włącz skanowanie EPG"
|
|
||||||
|
|
||||||
msgid ""
|
|
||||||
"Define whether the EPG background scanning shall be used.\n"
|
|
||||||
"\n"
|
|
||||||
"This setting disables the automatic EIT scanning functionality for all SAT>IP devices."
|
|
||||||
msgstr ""
|
|
||||||
"Określa czy przeprowadzać skanowanie EPG w tle.\n"
|
|
||||||
"\n"
|
|
||||||
"To ustawienie wyłącza funkcję automatycznego skanowania EIT dla wszystkich urządzeń SAT>IP."
|
|
||||||
|
|
||||||
msgid "Disabled sources"
|
|
||||||
msgstr "Wyłączone źródła"
|
|
||||||
|
|
||||||
msgid "none"
|
|
||||||
msgstr "brak"
|
|
||||||
|
|
||||||
msgid ""
|
|
||||||
"Define number of sources to be disabled.\n"
|
|
||||||
"\n"
|
|
||||||
"SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here."
|
|
||||||
msgstr ""
|
|
||||||
"Określa liczbę wyłączonych źródeł.\n"
|
|
||||||
"\n"
|
|
||||||
"Serwery SAT>IP mogą nie mieć dostępu do niektórych pozycji satelitarnych, więc tutaj można je wyłączyć."
|
|
||||||
|
|
||||||
msgid "Define a source to be blacklisted."
|
|
||||||
msgstr "Określ źródła do wyłączenia."
|
|
||||||
|
|
||||||
msgid "Disabled filters"
|
|
||||||
msgstr "Wyłączone filtry"
|
|
||||||
|
|
||||||
msgid ""
|
|
||||||
"Define number of section filters to be disabled.\n"
|
|
||||||
"\n"
|
|
||||||
"Certain section filters might cause some unwanted behaviour to VDR such as time being falsely synchronized. By blacklisting the filters here, useful section data can be left intact for VDR to process."
|
|
||||||
msgstr ""
|
|
||||||
"Określa liczbę wyłączonych filtrów sekcji.\n"
|
|
||||||
"\n"
|
|
||||||
"Niektóre filtry sekcji mogą powodować niezamierzone efekty w VDR, takie jak zły czas synchronizacji. Poprzez wyłączenie niektórych filtrów, użyteczne dane sekcji będą dostępne do przetworzenia dla VDR."
|
|
||||||
|
|
||||||
msgid "Filter"
|
|
||||||
msgstr "Filtr"
|
|
||||||
|
|
||||||
msgid "Define an ill-behaving filter to be blacklisted."
|
|
||||||
msgstr "Określa filtry powodujące zakłócenia, które mają być wyłączone."
|
|
||||||
|
|
||||||
msgid "Transport mode"
|
|
||||||
msgstr "Tryb"
|
|
||||||
|
|
||||||
msgid ""
|
|
||||||
"Define which transport mode shall be used.\n"
|
|
||||||
"\n"
|
|
||||||
"Unicast, Multicast, RTP-over-TCP"
|
|
||||||
msgstr ""
|
|
||||||
"Określa tryb transmisji.\n"
|
|
||||||
"Unicast, Multicast, RTP-over-TCP."
|
|
||||||
|
|
||||||
msgid "Enable frontend reuse"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Define whether reusing a frontend for multiple channels in a transponder should be enabled."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Active SAT>IP servers:"
|
|
||||||
msgstr "Aktywne serwery SAT>IP:"
|
|
||||||
|
|
||||||
msgid "Help"
|
|
||||||
msgstr "Pomoc"
|
|
28
rtcp.c
28
rtcp.c
@ -34,7 +34,7 @@ int cSatipRtcp::GetFd(void)
|
|||||||
return Fd();
|
return Fd();
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipRtcp::GetApplicationOffset(unsigned char *bufferP, int *lengthP)
|
int cSatipRtcp::GetApplicationOffset(int *lengthP)
|
||||||
{
|
{
|
||||||
debug16("%s (%d) [device %d]", __PRETTY_FUNCTION__, lengthP ? *lengthP : -1, tunerM.GetId());
|
debug16("%s (%d) [device %d]", __PRETTY_FUNCTION__, lengthP ? *lengthP : -1, tunerM.GetId());
|
||||||
if (!lengthP)
|
if (!lengthP)
|
||||||
@ -43,29 +43,29 @@ int cSatipRtcp::GetApplicationOffset(unsigned char *bufferP, int *lengthP)
|
|||||||
int total = *lengthP;
|
int total = *lengthP;
|
||||||
while (total > 0) {
|
while (total > 0) {
|
||||||
// Version
|
// Version
|
||||||
unsigned int v = (bufferP[offset] >> 6) & 0x03;
|
unsigned int v = (bufferM[offset] >> 6) & 0x03;
|
||||||
// Padding
|
// Padding
|
||||||
//unsigned int p = (bufferP[offset] >> 5) & 0x01;
|
//unsigned int p = (bufferM[offset] >> 5) & 0x01;
|
||||||
// Subtype
|
// Subtype
|
||||||
//unsigned int st = bufferP[offset] & 0x1F;
|
//unsigned int st = bufferM[offset] & 0x1F;
|
||||||
// Payload type
|
// Payload type
|
||||||
unsigned int pt = bufferP[offset + 1] & 0xFF;
|
unsigned int pt = bufferM[offset + 1] & 0xFF;
|
||||||
// Length
|
// Length
|
||||||
unsigned int length = ((bufferP[offset + 2] & 0xFF) << 8) | (bufferP[offset + 3] & 0xFF);
|
unsigned int length = ((bufferM[offset + 2] & 0xFF) << 8) | (bufferM[offset + 3] & 0xFF);
|
||||||
// Convert it to bytes
|
// Convert it to bytes
|
||||||
length = (length + 1) * 4;
|
length = (length + 1) * 4;
|
||||||
// V=2, APP = 204
|
// V=2, APP = 204
|
||||||
if ((v == 2) && (pt == 204)) {
|
if ((v == 2) && (pt == 204)) {
|
||||||
// SSCR/CSCR
|
// SSCR/CSCR
|
||||||
//unsigned int ssrc = ((bufferP[offset + 4] & 0xFF) << 24) | ((bufferP[offset + 5] & 0xFF) << 16) |
|
//unsigned int ssrc = ((bufferM[offset + 4] & 0xFF) << 24) | ((bufferM[offset + 5] & 0xFF) << 16) |
|
||||||
// ((bufferP[offset + 6] & 0xFF) << 8) | (bufferP[offset + 7] & 0xFF);
|
// ((bufferM[offset + 6] & 0xFF) << 8) | (bufferM[offset + 7] & 0xFF);
|
||||||
// Name
|
// Name
|
||||||
if ((bufferP[offset + 8] == 'S') && (bufferP[offset + 9] == 'E') &&
|
if ((bufferM[offset + 8] == 'S') && (bufferM[offset + 9] == 'E') &&
|
||||||
(bufferP[offset + 10] == 'S') && (bufferP[offset + 11] == '1')) {
|
(bufferM[offset + 10] == 'S') && (bufferM[offset + 11] == '1')) {
|
||||||
// Identifier
|
// Identifier
|
||||||
//unsigned int id = ((bufferP[offset + 12] & 0xFF) << 8) | (bufferP[offset + 13] & 0xFF);
|
//unsigned int id = ((bufferM[offset + 12] & 0xFF) << 8) | (bufferM[offset + 13] & 0xFF);
|
||||||
// String length
|
// String length
|
||||||
int string_length = ((bufferP[offset + 14] & 0xFF) << 8) | (bufferP[offset + 15] & 0xFF);
|
int string_length = ((bufferM[offset + 14] & 0xFF) << 8) | (bufferM[offset + 15] & 0xFF);
|
||||||
if (string_length > 0) {
|
if (string_length > 0) {
|
||||||
*lengthP = string_length;
|
*lengthP = string_length;
|
||||||
return (offset + 16);
|
return (offset + 16);
|
||||||
@ -85,7 +85,7 @@ void cSatipRtcp::Process(void)
|
|||||||
if (bufferM) {
|
if (bufferM) {
|
||||||
int length;
|
int length;
|
||||||
while ((length = Read(bufferM, bufferLenM)) > 0) {
|
while ((length = Read(bufferM, bufferLenM)) > 0) {
|
||||||
int offset = GetApplicationOffset(bufferM, &length);
|
int offset = GetApplicationOffset(&length);
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
tunerM.ProcessApplicationData(bufferM + offset, length);
|
tunerM.ProcessApplicationData(bufferM + offset, length);
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ void cSatipRtcp::Process(unsigned char *dataP, int lengthP)
|
|||||||
{
|
{
|
||||||
debug16("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
debug16("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
||||||
if (dataP && lengthP > 0) {
|
if (dataP && lengthP > 0) {
|
||||||
int offset = GetApplicationOffset(dataP, &lengthP);
|
int offset = GetApplicationOffset(&lengthP);
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
tunerM.ProcessApplicationData(dataP + offset, lengthP);
|
tunerM.ProcessApplicationData(dataP + offset, lengthP);
|
||||||
}
|
}
|
||||||
|
2
rtcp.h
2
rtcp.h
@ -20,7 +20,7 @@ private:
|
|||||||
cSatipTunerIf &tunerM;
|
cSatipTunerIf &tunerM;
|
||||||
unsigned int bufferLenM;
|
unsigned int bufferLenM;
|
||||||
unsigned char *bufferM;
|
unsigned char *bufferM;
|
||||||
int GetApplicationOffset(unsigned char *bufferP, int *lengthP);
|
int GetApplicationOffset(int *lengthP);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit cSatipRtcp(cSatipTunerIf &tunerP);
|
explicit cSatipRtcp(cSatipTunerIf &tunerP);
|
||||||
|
7
rtp.c
7
rtp.c
@ -14,8 +14,7 @@
|
|||||||
#include "rtp.h"
|
#include "rtp.h"
|
||||||
|
|
||||||
cSatipRtp::cSatipRtp(cSatipTunerIf &tunerP)
|
cSatipRtp::cSatipRtp(cSatipTunerIf &tunerP)
|
||||||
: cSatipSocket(SatipConfig.GetRtpRcvBufSize()),
|
: tunerM(tunerP),
|
||||||
tunerM(tunerP),
|
|
||||||
bufferLenM(eRtpPacketReadCount * eMaxUdpPacketSizeB),
|
bufferLenM(eRtpPacketReadCount * eMaxUdpPacketSizeB),
|
||||||
bufferM(MALLOC(unsigned char, bufferLenM)),
|
bufferM(MALLOC(unsigned char, bufferLenM)),
|
||||||
lastErrorReportM(0),
|
lastErrorReportM(0),
|
||||||
@ -46,7 +45,7 @@ void cSatipRtp::Close(void)
|
|||||||
|
|
||||||
sequenceNumberM = -1;
|
sequenceNumberM = -1;
|
||||||
if (packetErrorsM) {
|
if (packetErrorsM) {
|
||||||
info("Detected %d RTP packet error%s [device %d]", packetErrorsM, packetErrorsM == 1 ? "": "s", tunerM.GetId());
|
info("Detected %d RTP packet errors [device %d]", packetErrorsM, tunerM.GetId());
|
||||||
packetErrorsM = 0;
|
packetErrorsM = 0;
|
||||||
lastErrorReportM = time(NULL);
|
lastErrorReportM = time(NULL);
|
||||||
}
|
}
|
||||||
@ -81,7 +80,7 @@ int cSatipRtp::GetHeaderLength(unsigned char *bufferP, unsigned int lengthP)
|
|||||||
else if ((sequenceNumberM >= 0) && (((sequenceNumberM + 1) % 0xFFFF) != seq)) {
|
else if ((sequenceNumberM >= 0) && (((sequenceNumberM + 1) % 0xFFFF) != seq)) {
|
||||||
packetErrorsM++;
|
packetErrorsM++;
|
||||||
if (time(NULL) - lastErrorReportM > eReportIntervalS) {
|
if (time(NULL) - lastErrorReportM > eReportIntervalS) {
|
||||||
info("Detected %d RTP packet error%s [device %d]", packetErrorsM, packetErrorsM == 1 ? "": "s", tunerM.GetId());
|
info("Detected %d RTP packet errors [device %d]", packetErrorsM, tunerM.GetId());
|
||||||
packetErrorsM = 0;
|
packetErrorsM = 0;
|
||||||
lastErrorReportM = time(NULL);
|
lastErrorReportM = time(NULL);
|
||||||
}
|
}
|
||||||
|
41
rtsp.c
41
rtsp.c
@ -164,6 +164,9 @@ void cSatipRtsp::Create(void)
|
|||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_TIMEOUT_MS, (long)eConnectTimeoutMs);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_TIMEOUT_MS, (long)eConnectTimeoutMs);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_CONNECTTIMEOUT_MS, (long)eConnectTimeoutMs);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_CONNECTTIMEOUT_MS, (long)eConnectTimeoutMs);
|
||||||
|
|
||||||
|
// Limit download speed (bytes/s)
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_MAX_RECV_SPEED_LARGE, eMaxDownloadSpeedMBits * 131072L);
|
||||||
|
|
||||||
// Set user-agent
|
// Set user-agent
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s (device %d)", PLUGIN_NAME_I18N, VERSION, tunerM.GetId()));
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s (device %d)", PLUGIN_NAME_I18N, VERSION, tunerM.GetId()));
|
||||||
}
|
}
|
||||||
@ -190,44 +193,6 @@ void cSatipRtsp::Reset(void)
|
|||||||
Create();
|
Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipRtsp::SetInterface(const char *bindAddrP)
|
|
||||||
{
|
|
||||||
debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, bindAddrP, tunerM.GetId());
|
|
||||||
bool result = true;
|
|
||||||
CURLcode res = CURLE_OK;
|
|
||||||
|
|
||||||
if (handleM && !isempty(bindAddrP)) {
|
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERFACE, *cString::sprintf("host!%s", bindAddrP));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERFACE, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cSatipRtsp::Receive(const char *uriP)
|
|
||||||
{
|
|
||||||
debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, uriP, tunerM.GetId());
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (handleM && !isempty(uriP) && modeM == cSatipConfig::eTransportModeRtpOverTcp) {
|
|
||||||
long rc = 0;
|
|
||||||
cTimeMs processing(0);
|
|
||||||
CURLcode res = CURLE_OK;
|
|
||||||
|
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_URL, uriP);
|
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP);
|
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS); // FIXME: this really should be CURL_RTSPREQ_RECEIVE, but getting timeout errors
|
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
|
||||||
|
|
||||||
result = ValidateLatestResponse(&rc);
|
|
||||||
debug5("%s (%s) Response %ld in %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, uriP, rc, processing.Elapsed(), tunerM.GetId());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cSatipRtsp::Options(const char *uriP)
|
bool cSatipRtsp::Options(const char *uriP)
|
||||||
{
|
{
|
||||||
debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, uriP, tunerM.GetId());
|
debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, uriP, tunerM.GetId());
|
||||||
|
3
rtsp.h
3
rtsp.h
@ -27,6 +27,7 @@ private:
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
eConnectTimeoutMs = 1500, // in milliseconds
|
eConnectTimeoutMs = 1500, // in milliseconds
|
||||||
|
eMaxDownloadSpeedMBits = 20, // in megabits per second
|
||||||
};
|
};
|
||||||
|
|
||||||
cSatipTunerIf &tunerM;
|
cSatipTunerIf &tunerM;
|
||||||
@ -58,8 +59,6 @@ public:
|
|||||||
cString GetActiveMode(void);
|
cString GetActiveMode(void);
|
||||||
cString RtspUnescapeString(const char *strP);
|
cString RtspUnescapeString(const char *strP);
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
bool SetInterface(const char *bindAddrP);
|
|
||||||
bool Receive(const char *uriP);
|
|
||||||
bool Options(const char *uriP);
|
bool Options(const char *uriP);
|
||||||
bool Setup(const char *uriP, int rtpPortP, int rtcpPortP, bool useTcpP);
|
bool Setup(const char *uriP, int rtpPortP, int rtcpPortP, bool useTcpP);
|
||||||
bool SetSession(const char *sessionP);
|
bool SetSession(const char *sessionP);
|
||||||
|
59
satip.c
59
satip.c
@ -5,7 +5,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <vdr/plugin.h>
|
#include <vdr/plugin.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@ -20,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 < 20400
|
#if defined(APIVERSNUM) && APIVERSNUM < 20200
|
||||||
#error "VDR-2.4.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[] = "2.4.1" GITVERSION;
|
const char VERSION[] = "2.2.4" 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 {
|
||||||
@ -85,37 +84,13 @@ const char *cPluginSatip::CommandLineHelp(void)
|
|||||||
// Return a string that describes all known command line options.
|
// Return a string that describes all known command line options.
|
||||||
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=[<srcaddress>@]<ipaddress>[:<port>]|<model>[:<filter>]|<description>[:<quirk>];...\n"
|
" -s <ipaddr>|<model>|<desc>, --server=<ipaddr1>|<model1>|<desc1>;<ipaddr2>:<port>|<model2>:<filter>|<desc2>:<quirk>\n"
|
||||||
" define hard-coded SAT>IP server(s)\n\n"
|
" define hard-coded SAT>IP server(s)\n"
|
||||||
" srcaddress (Optional) Source address can be used to define used\n"
|
|
||||||
" networking interface on a host, e.g. 127.0.0.1.\n"
|
|
||||||
" ipaddress IP address of SAT>IP server, e.g. 127.0.0.1.\n"
|
|
||||||
" port (Optional) IP port number of SAT>IP server, e.g 443.\n"
|
|
||||||
" model Model defines DVB modulation system (DVBS2,\n"
|
|
||||||
" DVBT2, DVBT, DVBC) and number of available\n"
|
|
||||||
" frontends separated by a hyphen, e.g. DVBT2-4.\n"
|
|
||||||
" filter (Optional) Filter can be used to limit satellite frontends\n"
|
|
||||||
" to certain satellite position, e.g. S19.2E.\n"
|
|
||||||
" description Friendly name of SAT>IP server. This is used\n"
|
|
||||||
" for autodetection of quirks.\n"
|
|
||||||
" quirk (Optional) Quirks are non-standard compliant features and\n"
|
|
||||||
" bug fixes of SAT>IP server defined by a\n"
|
|
||||||
" hexadecimal number. Multiple quirks can be\n"
|
|
||||||
" defined by combining values by addition:\n\n"
|
|
||||||
" 0x01: Fix session id bug\n"
|
|
||||||
" 0x02: Fix play parameter (addpids/delpids) bug\n"
|
|
||||||
" 0x04: Fix frontend locking bug\n"
|
|
||||||
" 0x08: Support for RTP over TCP\n"
|
|
||||||
" 0x10: Support the X_PMT protocol extension\n"
|
|
||||||
" 0x20: Support the CI TNR protocol extension\n"
|
|
||||||
" 0x40: Fix auto-detection of pilot tones bug\n"
|
|
||||||
" 0x80: Fix re-tuning bug by teardowning a session\n"
|
|
||||||
" -D, --detach set the detached mode on\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 autodetection of the server quirks\n"
|
" -n, --noquirks disable autodetection of the server quirks\n"
|
||||||
" -p, --portrange=<start>-<end> set a range of ports used for the RT[C]P server\n"
|
" -p, --portrange=<start>-<end> set a range of ports used for the RT[C]P server\n"
|
||||||
" a minimum of 2 ports per device is required.\n"
|
" a minimum of 2 ports per device is required.\n";
|
||||||
" -r, --rcvbuf override the size of the RTP receive buffer in bytes\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
||||||
@ -127,7 +102,6 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
|||||||
{ "trace", required_argument, NULL, 't' },
|
{ "trace", required_argument, NULL, 't' },
|
||||||
{ "server", required_argument, NULL, 's' },
|
{ "server", required_argument, NULL, 's' },
|
||||||
{ "portrange",required_argument, NULL, 'p' },
|
{ "portrange",required_argument, NULL, 'p' },
|
||||||
{ "rcvbuf", required_argument, NULL, 'r' },
|
|
||||||
{ "detach", no_argument, NULL, 'D' },
|
{ "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' },
|
||||||
@ -137,7 +111,7 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
|||||||
cString server;
|
cString server;
|
||||||
cString portrange;
|
cString portrange;
|
||||||
int c;
|
int c;
|
||||||
while ((c = getopt_long(argc, argv, "d:t:s:p:r:DSn", long_options, NULL)) != -1) {
|
while ((c = getopt_long(argc, argv, "d:t:s:p:DSn", long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'd':
|
case 'd':
|
||||||
deviceCountM = strtol(optarg, NULL, 0);
|
deviceCountM = strtol(optarg, NULL, 0);
|
||||||
@ -160,9 +134,6 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
|
|||||||
case 'p':
|
case 'p':
|
||||||
portrange = optarg;
|
portrange = optarg;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
|
||||||
SatipConfig.SetRtpRcvBufSize(strtol(optarg, NULL, 0));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -261,7 +232,7 @@ void cPluginSatip::ParseServer(const char *paramP)
|
|||||||
while (r) {
|
while (r) {
|
||||||
r = skipspace(r);
|
r = skipspace(r);
|
||||||
debug3("%s server[%d]=%s", __PRETTY_FUNCTION__, n, r);
|
debug3("%s server[%d]=%s", __PRETTY_FUNCTION__, n, r);
|
||||||
cString sourceAddr, serverAddr, serverModel, serverFilters, serverDescription;
|
cString serverAddr, serverModel, serverFilters, serverDescription;
|
||||||
int serverQuirk = cSatipServer::eSatipQuirkNone;
|
int serverQuirk = cSatipServer::eSatipQuirkNone;
|
||||||
int serverPort = SATIP_DEFAULT_RTSP_PORT;
|
int serverPort = SATIP_DEFAULT_RTSP_PORT;
|
||||||
int n2 = 0;
|
int n2 = 0;
|
||||||
@ -272,14 +243,8 @@ void cPluginSatip::ParseServer(const char *paramP)
|
|||||||
switch (n2++) {
|
switch (n2++) {
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
char *r3 = strchr(r2, '@');
|
|
||||||
if (r3) {
|
|
||||||
*r3 = 0;
|
|
||||||
sourceAddr = r2;
|
|
||||||
r2 = r3 + 1;
|
|
||||||
}
|
|
||||||
serverAddr = r2;
|
serverAddr = r2;
|
||||||
r3 = strchr(r2, ':');
|
char *r3 = strchr(r2, ':');
|
||||||
if (r3) {
|
if (r3) {
|
||||||
serverPort = strtol(r3 + 1, NULL, 0);
|
serverPort = strtol(r3 + 1, NULL, 0);
|
||||||
serverAddr = serverAddr.Truncate(r3 - r2);
|
serverAddr = serverAddr.Truncate(r3 - r2);
|
||||||
@ -312,10 +277,10 @@ void cPluginSatip::ParseServer(const char *paramP)
|
|||||||
r2 = strtok_r(NULL, "|", &s2);
|
r2 = strtok_r(NULL, "|", &s2);
|
||||||
}
|
}
|
||||||
if (*serverAddr && *serverModel && *serverDescription) {
|
if (*serverAddr && *serverModel && *serverDescription) {
|
||||||
debug1("%s srcaddr=%s ipaddr=%s port=%d model=%s (%s) desc=%s (%d)", __PRETTY_FUNCTION__, *sourceAddr, *serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk);
|
debug1("%s ipaddr=%s port=%d model=%s (%s) desc=%s (%d)", __PRETTY_FUNCTION__, *serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk);
|
||||||
if (!serversM)
|
if (!serversM)
|
||||||
serversM = new cSatipDiscoverServers();
|
serversM = new cSatipDiscoverServers();
|
||||||
serversM->Add(new cSatipDiscoverServer(*sourceAddr, *serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk));
|
serversM->Add(new cSatipDiscoverServer(*serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk));
|
||||||
}
|
}
|
||||||
++n;
|
++n;
|
||||||
r = strtok_r(NULL, ";", &s);
|
r = strtok_r(NULL, ";", &s);
|
||||||
@ -415,8 +380,6 @@ bool cPluginSatip::SetupParse(const char *nameP, const char *valueP)
|
|||||||
SatipConfig.SetOperatingMode(atoi(valueP));
|
SatipConfig.SetOperatingMode(atoi(valueP));
|
||||||
else if (!strcasecmp(nameP, "EnableCIExtension"))
|
else if (!strcasecmp(nameP, "EnableCIExtension"))
|
||||||
SatipConfig.SetCIExtension(atoi(valueP));
|
SatipConfig.SetCIExtension(atoi(valueP));
|
||||||
else if (!strcasecmp(nameP, "EnableFrontendReuse"))
|
|
||||||
SatipConfig.SetFrontendReuse(atoi(valueP));
|
|
||||||
else if (!strcasecmp(nameP, "CICAM")) {
|
else if (!strcasecmp(nameP, "CICAM")) {
|
||||||
int Cicams[MAX_CICAM_COUNT];
|
int Cicams[MAX_CICAM_COUNT];
|
||||||
for (unsigned int i = 0; i < ELEMENTS(Cicams); ++i)
|
for (unsigned int i = 0; i < ELEMENTS(Cicams); ++i)
|
||||||
|
173
sectionfilter.c
173
sectionfilter.c
@ -18,14 +18,35 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
|||||||
secLenM(0),
|
secLenM(0),
|
||||||
tsFeedpM(0),
|
tsFeedpM(0),
|
||||||
pidM(pidP),
|
pidM(pidP),
|
||||||
tidM(tidP),
|
|
||||||
maskM(maskP),
|
|
||||||
ringBufferM(new cRingBufferFrame(eDmxMaxSectionCount * eDmxMaxSectionSize)),
|
ringBufferM(new cRingBufferFrame(eDmxMaxSectionCount * eDmxMaxSectionSize)),
|
||||||
deviceIndexM(deviceIndexP)
|
deviceIndexM(deviceIndexP)
|
||||||
{
|
{
|
||||||
debug16("%s (%d, %d, %d, %d) [device %d]", __PRETTY_FUNCTION__, deviceIndexM, pidM, tidP, maskP, deviceIndexM);
|
debug16("%s (%d, %d, %d, %d) [device %d]", __PRETTY_FUNCTION__, deviceIndexM, pidM, tidP, maskP, deviceIndexM);
|
||||||
|
int i;
|
||||||
|
|
||||||
memset(secBufBaseM, 0, sizeof(secBufBaseM));
|
memset(secBufBaseM, 0, sizeof(secBufBaseM));
|
||||||
|
memset(filterValueM, 0, sizeof(filterValueM));
|
||||||
|
memset(filterMaskM, 0, sizeof(filterMaskM));
|
||||||
|
memset(filterModeM, 0, sizeof(filterModeM));
|
||||||
|
memset(maskAndModeM, 0, sizeof(maskAndModeM));
|
||||||
|
memset(maskAndNotModeM, 0, sizeof(maskAndNotModeM));
|
||||||
|
|
||||||
|
filterValueM[0] = tidP;
|
||||||
|
filterMaskM[0] = maskP;
|
||||||
|
|
||||||
|
// Invert the filter
|
||||||
|
for (i = 0; i < eDmxMaxFilterSize; ++i)
|
||||||
|
filterValueM[i] ^= 0xFF;
|
||||||
|
|
||||||
|
uint8_t doneq = 0;
|
||||||
|
for (i = 0; i < eDmxMaxFilterSize; ++i) {
|
||||||
|
uint8_t mode = filterModeM[i];
|
||||||
|
uint8_t mask = filterMaskM[i];
|
||||||
|
maskAndModeM[i] = (uint8_t)(mask & mode);
|
||||||
|
maskAndNotModeM[i] = (uint8_t)(mask & ~mode);
|
||||||
|
doneq |= maskAndNotModeM[i];
|
||||||
|
}
|
||||||
|
doneqM = doneq ? 1 : 0;
|
||||||
|
|
||||||
// Create sockets
|
// Create sockets
|
||||||
socketM[0] = socketM[1] = -1;
|
socketM[0] = socketM[1] = -1;
|
||||||
@ -68,13 +89,21 @@ void cSatipSectionFilter::New(void)
|
|||||||
int cSatipSectionFilter::Filter(void)
|
int cSatipSectionFilter::Filter(void)
|
||||||
{
|
{
|
||||||
if (secBufM) {
|
if (secBufM) {
|
||||||
if ((tidM & maskM) == (secBufM[0] & maskM)) {
|
int i;
|
||||||
if (ringBufferM && (secLenM > 0)) {
|
uint8_t neq = 0;
|
||||||
cFrame* section = new cFrame(secBufM, secLenM);
|
|
||||||
if (!ringBufferM->Put(section))
|
for (i = 0; i < eDmxMaxFilterSize; ++i) {
|
||||||
DELETE_POINTER(section);
|
uint8_t calcxor = (uint8_t)(filterValueM[i] ^ secBufM[i]);
|
||||||
}
|
if (maskAndModeM[i] & calcxor)
|
||||||
}
|
return 0;
|
||||||
|
neq |= (maskAndNotModeM[i] & calcxor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doneqM && !neq)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ringBufferM && (secLenM > 0))
|
||||||
|
ringBufferM->Put(new cFrame(secBufM, secLenM));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -97,7 +126,7 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
|
|||||||
if (tsFeedpM + lenP > eDmxMaxSectionFeedSize)
|
if (tsFeedpM + lenP > eDmxMaxSectionFeedSize)
|
||||||
lenP = (uint8_t)(eDmxMaxSectionFeedSize - tsFeedpM);
|
lenP = (uint8_t)(eDmxMaxSectionFeedSize - tsFeedpM);
|
||||||
|
|
||||||
if (lenP == 0)
|
if (lenP <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memcpy(secBufBaseM + tsFeedpM, bufP, lenP);
|
memcpy(secBufBaseM + tsFeedpM, bufP, lenP);
|
||||||
@ -112,7 +141,7 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
|
|||||||
|
|
||||||
for (n = 0; secBufpM + 2 < limit; ++n) {
|
for (n = 0; secBufpM + 2 < limit; ++n) {
|
||||||
uint16_t seclen = GetLength(secBufM);
|
uint16_t seclen = GetLength(secBufM);
|
||||||
if ((seclen > eDmxMaxSectionSize) || ((seclen + secBufpM) > limit))
|
if ((seclen <= 0) || (seclen > eDmxMaxSectionSize) || ((seclen + secBufpM) > limit))
|
||||||
return 0;
|
return 0;
|
||||||
secLenM = seclen;
|
secLenM = seclen;
|
||||||
if (pusiSeenM)
|
if (pusiSeenM)
|
||||||
@ -180,28 +209,27 @@ void cSatipSectionFilter::Process(const uint8_t* dataP)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipSectionFilter::Send(void)
|
bool cSatipSectionFilter::Send(void)
|
||||||
{
|
{
|
||||||
|
bool result = false;
|
||||||
cFrame *section = ringBufferM->Get();
|
cFrame *section = ringBufferM->Get();
|
||||||
if (section) {
|
if (section) {
|
||||||
uchar *data = section->Data();
|
uchar *data = section->Data();
|
||||||
int count = section->Count();
|
int count = section->Count();
|
||||||
if (data && (count > 0) && (socketM[1] >= 0) && (socketM[0] >= 0)) {
|
if (data && (count > 0) && (socketM[1] >= 0) && (socketM[0] >= 0)) {
|
||||||
if (send(socketM[1], data, count, MSG_EOR) > 0) {
|
ssize_t len = send(socketM[1], data, count, MSG_EOR);
|
||||||
|
ERROR_IF(len < 0 && errno != EAGAIN, "send()");
|
||||||
|
if (len > 0) {
|
||||||
|
ringBufferM->Drop(section);
|
||||||
|
result = !!ringBufferM->Available();
|
||||||
// Update statistics
|
// Update statistics
|
||||||
AddSectionStatistic(count, 1);
|
AddSectionStatistic(len, 1);
|
||||||
}
|
}
|
||||||
else if (errno != EAGAIN)
|
|
||||||
error("failed to send section data (%i bytes) [device=%d]", count, deviceIndexM);
|
|
||||||
}
|
}
|
||||||
ringBufferM->Drop(section);
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipSectionFilter::Available(void) const
|
|
||||||
{
|
|
||||||
return ringBufferM->Available();
|
|
||||||
}
|
|
||||||
|
|
||||||
cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP)
|
cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP)
|
||||||
: cThread(cString::sprintf("SATIP#%d section handler", deviceIndexP)),
|
: cThread(cString::sprintf("SATIP#%d section handler", deviceIndexP)),
|
||||||
@ -239,73 +267,54 @@ cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
|||||||
Delete(i);
|
Delete(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipSectionFilterHandler::SendAll(void)
|
|
||||||
{
|
|
||||||
cMutexLock MutexLock(&mutexM);
|
|
||||||
bool pendingData;
|
|
||||||
do {
|
|
||||||
pendingData = false;
|
|
||||||
|
|
||||||
// zero polling structures
|
|
||||||
memset(pollFdsM, 0, sizeof(pollFdsM));
|
|
||||||
|
|
||||||
// assemble all handlers to poll (use -1 to ignore handlers)
|
|
||||||
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
|
||||||
if (filtersM[i] && filtersM[i]->Available() != 0) {
|
|
||||||
pollFdsM[i].fd = filtersM[i]->GetFd();
|
|
||||||
pollFdsM[i].events = POLLOUT;
|
|
||||||
pendingData = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pollFdsM[i].fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// exit if there isn't any pending data or we time out
|
|
||||||
if (!pendingData || poll(pollFdsM, eMaxSecFilterCount, eSecFilterSendTimeoutMs) <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// send data (if available)
|
|
||||||
for (unsigned int i = 0; i < eMaxSecFilterCount && pendingData; ++i) {
|
|
||||||
if (pollFdsM[i].revents & POLLOUT)
|
|
||||||
filtersM[i]->Send();
|
|
||||||
}
|
|
||||||
} while (pendingData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cSatipSectionFilterHandler::Action(void)
|
void cSatipSectionFilterHandler::Action(void)
|
||||||
{
|
{
|
||||||
debug1("%s Entering [device %d]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug1("%s Entering [device %d]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
|
bool processed = false;
|
||||||
// Do the thread loop
|
// Do the thread loop
|
||||||
while (Running()) {
|
while (Running()) {
|
||||||
uchar *p = NULL;
|
|
||||||
int len = 0;
|
|
||||||
// Process all pending TS packets
|
|
||||||
while ((p = ringBufferM->Get(len)) != NULL) {
|
|
||||||
if (p && (len >= TS_SIZE)) {
|
|
||||||
if (*p != TS_SYNC_BYTE) {
|
|
||||||
for (int i = 1; i < len; ++i) {
|
|
||||||
if (p[i] == TS_SYNC_BYTE) {
|
|
||||||
len = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ringBufferM->Del(len);
|
|
||||||
debug1("%s Skipped %d bytes to sync on TS packet [device %d]", __PRETTY_FUNCTION__, len, deviceIndexM);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Process TS packet through all filters
|
|
||||||
mutexM.Lock();
|
|
||||||
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
|
||||||
if (filtersM[i])
|
|
||||||
filtersM[i]->Process(p);
|
|
||||||
}
|
|
||||||
mutexM.Unlock();
|
|
||||||
ringBufferM->Del(TS_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send demuxed section packets through all filters
|
// Send demuxed section packets through all filters
|
||||||
SendAll();
|
bool retry = false;
|
||||||
|
mutexM.Lock();
|
||||||
|
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
||||||
|
if (filtersM[i] && filtersM[i]->Send())
|
||||||
|
retry = true;
|
||||||
|
}
|
||||||
|
mutexM.Unlock();
|
||||||
|
if (retry)
|
||||||
|
continue;
|
||||||
|
// Read one TS packet
|
||||||
|
if (ringBufferM) {
|
||||||
|
int len = 0;
|
||||||
|
if (processed) {
|
||||||
|
ringBufferM->Del(TS_SIZE);
|
||||||
|
processed = false;
|
||||||
|
}
|
||||||
|
uchar *p = ringBufferM->Get(len);
|
||||||
|
if (p && (len >= TS_SIZE)) {
|
||||||
|
if (*p != TS_SYNC_BYTE) {
|
||||||
|
for (int i = 1; i < len; ++i) {
|
||||||
|
if (p[i] == TS_SYNC_BYTE) {
|
||||||
|
len = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ringBufferM->Del(len);
|
||||||
|
debug1("%s Skipped %d bytes to sync on TS packet [device %d]", __PRETTY_FUNCTION__, len, deviceIndexM);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Process TS packet through all filters
|
||||||
|
mutexM.Lock();
|
||||||
|
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
||||||
|
if (filtersM[i])
|
||||||
|
filtersM[i]->Process(p);
|
||||||
|
}
|
||||||
|
mutexM.Unlock();
|
||||||
|
processed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cCondWait::SleepMs(10); // to avoid busy loop and reduce cpu load
|
||||||
}
|
}
|
||||||
debug1("%s Exiting [device %d]", __PRETTY_FUNCTION__, deviceIndexM);
|
debug1("%s Exiting [device %d]", __PRETTY_FUNCTION__, deviceIndexM);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#ifndef __SATIP_SECTIONFILTER_H
|
#ifndef __SATIP_SECTIONFILTER_H
|
||||||
#define __SATIP_SECTIONFILTER_H
|
#define __SATIP_SECTIONFILTER_H
|
||||||
|
|
||||||
#include <poll.h>
|
|
||||||
#include <vdr/device.h>
|
#include <vdr/device.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@ -33,13 +32,18 @@ private:
|
|||||||
uint16_t secLenM;
|
uint16_t secLenM;
|
||||||
uint16_t tsFeedpM;
|
uint16_t tsFeedpM;
|
||||||
uint16_t pidM;
|
uint16_t pidM;
|
||||||
uint8_t tidM;
|
|
||||||
uint8_t maskM;
|
|
||||||
|
|
||||||
cRingBufferFrame *ringBufferM;
|
cRingBufferFrame *ringBufferM;
|
||||||
int deviceIndexM;
|
int deviceIndexM;
|
||||||
int socketM[2];
|
int socketM[2];
|
||||||
|
|
||||||
|
uint8_t filterValueM[eDmxMaxFilterSize];
|
||||||
|
uint8_t filterMaskM[eDmxMaxFilterSize];
|
||||||
|
uint8_t filterModeM[eDmxMaxFilterSize];
|
||||||
|
|
||||||
|
uint8_t maskAndModeM[eDmxMaxFilterSize];
|
||||||
|
uint8_t maskAndNotModeM[eDmxMaxFilterSize];
|
||||||
|
|
||||||
inline uint16_t GetLength(const uint8_t *dataP);
|
inline uint16_t GetLength(const uint8_t *dataP);
|
||||||
void New(void);
|
void New(void);
|
||||||
int Filter(void);
|
int Filter(void);
|
||||||
@ -51,27 +55,23 @@ public:
|
|||||||
cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_t tidP, uint8_t maskP);
|
cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_t tidP, uint8_t maskP);
|
||||||
virtual ~cSatipSectionFilter();
|
virtual ~cSatipSectionFilter();
|
||||||
void Process(const uint8_t* dataP);
|
void Process(const uint8_t* dataP);
|
||||||
void Send(void);
|
bool Send(void);
|
||||||
int GetFd(void) { return socketM[0]; }
|
int GetFd(void) { return socketM[0]; }
|
||||||
uint16_t GetPid(void) const { return pidM; }
|
uint16_t GetPid(void) const { return pidM; }
|
||||||
int Available(void) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class cSatipSectionFilterHandler : public cThread {
|
class cSatipSectionFilterHandler : public cThread {
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
eMaxSecFilterCount = 32,
|
eMaxSecFilterCount = 32
|
||||||
eSecFilterSendTimeoutMs = 10
|
|
||||||
};
|
};
|
||||||
cRingBufferLinear *ringBufferM;
|
cRingBufferLinear *ringBufferM;
|
||||||
cMutex mutexM;
|
cMutex mutexM;
|
||||||
int deviceIndexM;
|
int deviceIndexM;
|
||||||
cSatipSectionFilter *filtersM[eMaxSecFilterCount];
|
cSatipSectionFilter *filtersM[eMaxSecFilterCount];
|
||||||
struct pollfd pollFdsM[eMaxSecFilterCount];
|
|
||||||
|
|
||||||
bool Delete(unsigned int indexP);
|
bool Delete(unsigned int indexP);
|
||||||
bool IsBlackListed(u_short pidP, u_char tidP, u_char maskP) const;
|
bool IsBlackListed(u_short pidP, u_char tidP, u_char maskP) const;
|
||||||
void SendAll(void);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
|
114
server.c
114
server.c
@ -40,43 +40,29 @@ bool cSatipFrontends::Matches(int deviceIdP, int transponderP)
|
|||||||
bool cSatipFrontends::Assign(int deviceIdP, int transponderP)
|
bool cSatipFrontends::Assign(int deviceIdP, int transponderP)
|
||||||
{
|
{
|
||||||
cSatipFrontend *tmp = NULL;
|
cSatipFrontend *tmp = NULL;
|
||||||
// Prefer any used one
|
// Prefer any unused one
|
||||||
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||||
if (f->DeviceId() == deviceIdP) { // give deviceID priority, but take detached frontend if deviceID ist not yet attached
|
if (!f->Attached() || (f->DeviceId() == deviceIdP)) {
|
||||||
tmp = f;
|
tmp = f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!f->Attached()) {
|
|
||||||
tmp = f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
tmp->SetTransponder(transponderP);
|
tmp->SetTransponder(transponderP);
|
||||||
debug9("%s assigned TP %d to %s/#%d", __PRETTY_FUNCTION__, transponderP, *tmp->Description(), tmp->Index());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
error("no assignable frontend found [device %u]", deviceIdP);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipFrontends::Attach(int deviceIdP, int transponderP)
|
bool cSatipFrontends::Attach(int deviceIdP, int transponderP)
|
||||||
{
|
{
|
||||||
cSatipFrontend *tmp = NULL;
|
|
||||||
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||||
if (f->Transponder() == transponderP) {
|
if (f->Transponder() == transponderP) {
|
||||||
tmp = f;
|
f->Attach(deviceIdP);
|
||||||
if (f->DeviceId() == deviceIdP) {
|
debug9("%s (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
||||||
break;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp) {
|
|
||||||
tmp->Attach(deviceIdP);
|
|
||||||
debug9("%s attached deviceId %d (TP %d) to %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *tmp->Description(), tmp->Index());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
error("%s no Frontend found for attaching deviceID %d (TP %d)", __PRETTY_FUNCTION__, deviceIdP, transponderP);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +71,7 @@ bool cSatipFrontends::Detach(int deviceIdP, int transponderP)
|
|||||||
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||||
if (f->Transponder() == transponderP) {
|
if (f->Transponder() == transponderP) {
|
||||||
f->Detach(deviceIdP);
|
f->Detach(deviceIdP);
|
||||||
debug9("%s detached deviceID %d (TP %d) from %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
debug9("%s (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,9 +80,8 @@ bool cSatipFrontends::Detach(int deviceIdP, int transponderP)
|
|||||||
|
|
||||||
// --- cSatipServer -----------------------------------------------------------
|
// --- cSatipServer -----------------------------------------------------------
|
||||||
|
|
||||||
cSatipServer::cSatipServer(const char *srcAddressP, const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP)
|
cSatipServer::cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP)
|
||||||
: srcAddressM((srcAddressP && *srcAddressP) ? srcAddressP : ""),
|
: addressM((addressP && *addressP) ? addressP : "0.0.0.0"),
|
||||||
addressM((addressP && *addressP) ? addressP : "0.0.0.0"),
|
|
||||||
modelM((modelP && *modelP) ? modelP : "DVBS-1"),
|
modelM((modelP && *modelP) ? modelP : "DVBS-1"),
|
||||||
filtersM((filtersP && *filtersP) ? filtersP : ""),
|
filtersM((filtersP && *filtersP) ? filtersP : ""),
|
||||||
descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"),
|
descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"),
|
||||||
@ -131,50 +116,44 @@ cSatipServer::cSatipServer(const char *srcAddressP, const char *addressP, const
|
|||||||
// 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, "Multibox-") || // Inverto IDL-400s: Multibox-<MMAACC>:SAT>IP
|
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
||||||
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
|
||||||
)
|
)
|
||||||
quirkM |= eSatipQuirkSessionId;
|
quirkM |= eSatipQuirkSessionId;
|
||||||
// These devices contain support for RTP over TCP:
|
// These devices contain support for RTP over TCP:
|
||||||
if (strstr(*descriptionM, "minisatip") || // minisatip server
|
if (strstr(*descriptionM, "minisatip") || // minisatip server
|
||||||
strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server
|
strstr(*descriptionM, "DVBViewer") || // DVBViewer Media Server
|
||||||
|
strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400
|
||||||
|
strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1
|
||||||
|
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
||||||
)
|
)
|
||||||
quirkM |= eSatipQuirkRtpOverTcp;
|
quirkM |= eSatipQuirkRtpOverTcp;
|
||||||
// These devices contain a play (add/delpids) parameter bug:
|
// These devices contain a play (add/delpids) parameter bug:
|
||||||
if (strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C
|
if (strstr(*descriptionM, "fritzdvbc") // Fritz!WLAN Repeater DVB-C
|
||||||
strstr(*descriptionM, "fritzdvbc") // FRITZ!WLAN Repeater DVB-C (old firmware)
|
|
||||||
)
|
)
|
||||||
quirkM |= eSatipQuirkPlayPids;
|
quirkM |= eSatipQuirkPlayPids;
|
||||||
// These devices contain a frontend locking bug:
|
// These devices contain a frontend locking bug:
|
||||||
if (strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C
|
if (strstr(*descriptionM, "fritzdvbc") || // Fritz!WLAN Repeater DVB-C
|
||||||
strstr(*descriptionM, "fritzdvbc") || // FRITZ!WLAN Repeater DVB-C (old firmware)
|
strstr(*descriptionM, "Schwaiger Sat>IP Server") // Schwaiger MS41IP
|
||||||
strstr(*descriptionM, "Schwaiger Sat>IP Server") // Schwaiger MS41IP
|
|
||||||
)
|
)
|
||||||
quirkM |= eSatipQuirkForceLock;
|
quirkM |= eSatipQuirkForceLock;
|
||||||
// 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
|
||||||
strstr(*descriptionM, "minisatip") // minisatip server
|
strstr(*descriptionM, "minisatip") // minisatip server
|
||||||
)
|
)
|
||||||
quirkM |= eSatipQuirkCiXpmt;
|
quirkM |= eSatipQuirkCiXpmt;
|
||||||
// These devices support the TNR protocol extension:
|
// These devices support the TNR protocol extension
|
||||||
if (strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server
|
if (strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server
|
||||||
)
|
)
|
||||||
quirkM |= eSatipQuirkCiTnr;
|
quirkM |= eSatipQuirkCiTnr;
|
||||||
// These devices don't support auto-detection of pilot tones:
|
// These devices don't support auto-detection of pilot tones
|
||||||
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, "Multibox-") || // Inverto IDL-400s: Multibox-<MMAACC>:SAT>IP
|
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
||||||
strstr(*descriptionM, "Triax SatIP Converter") || // Triax TSS 400
|
// Kathrein ExIP 414/E
|
||||||
strstr(*descriptionM, "KATHREIN SatIP Server") // Kathrein ExIP 414/E
|
|
||||||
)
|
)
|
||||||
quirkM |= eSatipQuirkForcePilot;
|
quirkM |= eSatipQuirkForcePilot;
|
||||||
// These devices require TEARDOWN before new PLAY command:
|
|
||||||
if (strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C
|
|
||||||
strstr(*descriptionM, "fritzdvbc") // FRITZ!WLAN Repeater DVB-C (old firmware)
|
|
||||||
)
|
|
||||||
quirkM |= eSatipQuirkTearAndPlay;
|
|
||||||
}
|
}
|
||||||
if ((quirkM & eSatipQuirkMask) & eSatipQuirkSessionId)
|
if ((quirkM & eSatipQuirkMask) & eSatipQuirkSessionId)
|
||||||
quirksM = cString::sprintf("%s%sSessionId", *quirksM, isempty(*quirksM) ? "" : ",");
|
quirksM = cString::sprintf("%s%sSessionId", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
@ -227,11 +206,6 @@ cSatipServer::cSatipServer(const char *srcAddressP, const char *addressP, const
|
|||||||
for (int i = 1; i <= count; ++i)
|
for (int i = 1; i <= count; ++i)
|
||||||
frontendsM[eSatipFrontendDVBC2].Add(new cSatipFrontend(i, "DVB-C2"));
|
frontendsM[eSatipFrontendDVBC2].Add(new cSatipFrontend(i, "DVB-C2"));
|
||||||
}
|
}
|
||||||
else if (c = strstr(r, "ATSC-")) {
|
|
||||||
int count = atoi(c + 5);
|
|
||||||
for (int i = 1; i <= count; ++i)
|
|
||||||
frontendsM[eSatipFrontendATSC].Add(new cSatipFrontend(i, "ATSC"));
|
|
||||||
}
|
|
||||||
r = strtok_r(NULL, ",", &s);
|
r = strtok_r(NULL, ",", &s);
|
||||||
}
|
}
|
||||||
FREE_POINTER(p);
|
FREE_POINTER(p);
|
||||||
@ -284,8 +258,6 @@ bool cSatipServer::Assign(int deviceIdP, int sourceP, int systemP, int transpond
|
|||||||
else
|
else
|
||||||
result = frontendsM[eSatipFrontendDVBC].Assign(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Assign(deviceIdP, transponderP);
|
result = frontendsM[eSatipFrontendDVBC].Assign(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Assign(deviceIdP, transponderP);
|
||||||
}
|
}
|
||||||
else if (cSource::IsType(sourceP, 'A'))
|
|
||||||
result = frontendsM[eSatipFrontendATSC].Assign(deviceIdP, transponderP);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -299,8 +271,6 @@ bool cSatipServer::Matches(int sourceP)
|
|||||||
return GetModulesDVBT() || GetModulesDVBT2();
|
return GetModulesDVBT() || GetModulesDVBT2();
|
||||||
else if (cSource::IsType(sourceP, 'C'))
|
else if (cSource::IsType(sourceP, 'C'))
|
||||||
return GetModulesDVBC() || GetModulesDVBC2();
|
return GetModulesDVBC() || GetModulesDVBC2();
|
||||||
else if (cSource::IsType(sourceP, 'A'))
|
|
||||||
return GetModulesATSC();
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -323,8 +293,6 @@ bool cSatipServer::Matches(int deviceIdP, int sourceP, int systemP, int transpon
|
|||||||
else
|
else
|
||||||
result = frontendsM[eSatipFrontendDVBC].Matches(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Matches(deviceIdP, transponderP);
|
result = frontendsM[eSatipFrontendDVBC].Matches(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Matches(deviceIdP, transponderP);
|
||||||
}
|
}
|
||||||
else if (cSource::IsType(sourceP, 'A'))
|
|
||||||
result = frontendsM[eSatipFrontendATSC].Matches(deviceIdP, transponderP);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -370,11 +338,6 @@ int cSatipServer::GetModulesDVBC2(void)
|
|||||||
return frontendsM[eSatipFrontendDVBC2].Count();
|
return frontendsM[eSatipFrontendDVBC2].Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipServer::GetModulesATSC(void)
|
|
||||||
{
|
|
||||||
return frontendsM[eSatipFrontendATSC].Count();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cSatipServers ----------------------------------------------------------
|
// --- cSatipServers ----------------------------------------------------------
|
||||||
|
|
||||||
cSatipServer *cSatipServers::Find(cSatipServer *serverP)
|
cSatipServer *cSatipServers::Find(cSatipServer *serverP)
|
||||||
@ -483,18 +446,6 @@ void cSatipServers::Cleanup(uint64_t intervalMsP)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cString cSatipServers::GetSrcAddress(cSatipServer *serverP)
|
|
||||||
{
|
|
||||||
cString address = "";
|
|
||||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
|
||||||
if (s == serverP) {
|
|
||||||
address = s->SrcAddress();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
cString cSatipServers::GetAddress(cSatipServer *serverP)
|
cString cSatipServers::GetAddress(cSatipServer *serverP)
|
||||||
{
|
{
|
||||||
cString address = "";
|
cString address = "";
|
||||||
@ -535,10 +486,7 @@ cString cSatipServers::List(void)
|
|||||||
{
|
{
|
||||||
cString list = "";
|
cString list = "";
|
||||||
for (cSatipServer *s = First(); s; s = Next(s))
|
for (cSatipServer *s = First(); s; s = Next(s))
|
||||||
if (isempty(s->SrcAddress()))
|
list = cString::sprintf("%s%c %s|%s|%s\n", *list, s->IsActive() ? '+' : '-', s->Address(), s->Model(), s->Description());
|
||||||
list = cString::sprintf("%s%c %s|%s|%s\n", *list, s->IsActive() ? '+' : '-', s->Address(), s->Model(), s->Description());
|
|
||||||
else
|
|
||||||
list = cString::sprintf("%s%c %s@%s|%s|%s\n", *list, s->IsActive() ? '+' : '-', s->SrcAddress(), s->Address(), s->Model(), s->Description());
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,8 +504,6 @@ int cSatipServers::NumProvidedSystems(void)
|
|||||||
count += s->GetModulesDVBC() * 3;
|
count += s->GetModulesDVBC() * 3;
|
||||||
// DVB-C2: qam16, qam32, qam64, qam128, qam256
|
// DVB-C2: qam16, qam32, qam64, qam128, qam256
|
||||||
count += s->GetModulesDVBC2() * 5;
|
count += s->GetModulesDVBC2() * 5;
|
||||||
// ATSC: 8vbs, 16vbs, qam256
|
|
||||||
count += s->GetModulesATSC() * 3;
|
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
26
server.h
26
server.h
@ -52,13 +52,11 @@ private:
|
|||||||
eSatipFrontendDVBT2,
|
eSatipFrontendDVBT2,
|
||||||
eSatipFrontendDVBC,
|
eSatipFrontendDVBC,
|
||||||
eSatipFrontendDVBC2,
|
eSatipFrontendDVBC2,
|
||||||
eSatipFrontendATSC,
|
|
||||||
eSatipFrontendCount
|
eSatipFrontendCount
|
||||||
};
|
};
|
||||||
enum {
|
enum {
|
||||||
eSatipMaxSourceFilters = 16
|
eSatipMaxSourceFilters = 16
|
||||||
};
|
};
|
||||||
cString srcAddressM;
|
|
||||||
cString addressM;
|
cString addressM;
|
||||||
cString modelM;
|
cString modelM;
|
||||||
cString filtersM;
|
cString filtersM;
|
||||||
@ -76,18 +74,17 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum eSatipQuirk {
|
enum eSatipQuirk {
|
||||||
eSatipQuirkNone = 0x00,
|
eSatipQuirkNone = 0x00,
|
||||||
eSatipQuirkSessionId = 0x01,
|
eSatipQuirkSessionId = 0x01,
|
||||||
eSatipQuirkPlayPids = 0x02,
|
eSatipQuirkPlayPids = 0x02,
|
||||||
eSatipQuirkForceLock = 0x04,
|
eSatipQuirkForceLock = 0x04,
|
||||||
eSatipQuirkRtpOverTcp = 0x08,
|
eSatipQuirkRtpOverTcp = 0x08,
|
||||||
eSatipQuirkCiXpmt = 0x10,
|
eSatipQuirkCiXpmt = 0x10,
|
||||||
eSatipQuirkCiTnr = 0x20,
|
eSatipQuirkCiTnr = 0x20,
|
||||||
eSatipQuirkForcePilot = 0x40,
|
eSatipQuirkForcePilot = 0x40,
|
||||||
eSatipQuirkTearAndPlay = 0x80,
|
eSatipQuirkMask = 0xFF
|
||||||
eSatipQuirkMask = 0xFF
|
|
||||||
};
|
};
|
||||||
cSatipServer(const char *srcAddressP, const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP);
|
cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP);
|
||||||
virtual ~cSatipServer();
|
virtual ~cSatipServer();
|
||||||
virtual int Compare(const cListObject &listObjectP) const;
|
virtual int Compare(const cListObject &listObjectP) const;
|
||||||
bool Assign(int deviceIdP, int sourceP, int systemP, int transponderP);
|
bool Assign(int deviceIdP, int sourceP, int systemP, int transponderP);
|
||||||
@ -100,9 +97,7 @@ public:
|
|||||||
int GetModulesDVBT2(void);
|
int GetModulesDVBT2(void);
|
||||||
int GetModulesDVBC(void);
|
int GetModulesDVBC(void);
|
||||||
int GetModulesDVBC2(void);
|
int GetModulesDVBC2(void);
|
||||||
int GetModulesATSC(void);
|
|
||||||
void Activate(bool onOffP) { activeM = onOffP; }
|
void Activate(bool onOffP) { activeM = onOffP; }
|
||||||
const char *SrcAddress(void) { return *srcAddressM; }
|
|
||||||
const char *Address(void) { return *addressM; }
|
const char *Address(void) { return *addressM; }
|
||||||
const char *Model(void) { return *modelM; }
|
const char *Model(void) { return *modelM; }
|
||||||
const char *Filters(void) { return *filtersM; }
|
const char *Filters(void) { return *filtersM; }
|
||||||
@ -133,7 +128,6 @@ public:
|
|||||||
bool HasCI(cSatipServer *serverP);
|
bool HasCI(cSatipServer *serverP);
|
||||||
void Cleanup(uint64_t intervalMsP = 0);
|
void Cleanup(uint64_t intervalMsP = 0);
|
||||||
cString GetAddress(cSatipServer *serverP);
|
cString GetAddress(cSatipServer *serverP);
|
||||||
cString GetSrcAddress(cSatipServer *serverP);
|
|
||||||
cString GetString(cSatipServer *serverP);
|
cString GetString(cSatipServer *serverP);
|
||||||
int GetPort(cSatipServer *serverP);
|
int GetPort(cSatipServer *serverP);
|
||||||
cString List(void);
|
cString List(void);
|
||||||
|
13
setup.c
13
setup.c
@ -105,7 +105,7 @@ cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP)
|
|||||||
: cOsdMenu(tr("SAT>IP Server"), 20),
|
: cOsdMenu(tr("SAT>IP Server"), 20),
|
||||||
serverM(serverP),
|
serverM(serverP),
|
||||||
activeM(serverP && serverP->IsActive()),
|
activeM(serverP && serverP->IsActive()),
|
||||||
addressM(serverP ? (isempty(serverP->SrcAddress()) ? serverP->Address() : *cString::sprintf("%s@%s", serverP->SrcAddress(), 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->HasCI() ? trVDR("yes") : trVDR("no")),
|
ciExtensionM(serverP && serverP->HasCI() ? trVDR("yes") : trVDR("no")),
|
||||||
@ -167,7 +167,7 @@ cSatipServerItem::cSatipServerItem(cSatipServer *serverP)
|
|||||||
{
|
{
|
||||||
SetSelectable(true);
|
SetSelectable(true);
|
||||||
// Must begin with a '#' character!
|
// Must begin with a '#' character!
|
||||||
SetText(*cString::sprintf("%s %s (%s)\t%s", serverM->IsActive() ? "+" : "-", isempty(serverM->SrcAddress()) ? serverM->Address() : *cString::sprintf("%s@%s", serverM->SrcAddress(), serverM->Address()), serverM->Model(), serverM->Description()));
|
SetText(*cString::sprintf("%s %s (%s)\t%s", serverM->IsActive() ? "+" : "-", serverM->Address(), serverM->Model(), serverM->Description()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipServerItem::SetMenuItem(cSkinDisplayMenu *displayMenuP, int indexP, bool currentP, bool selectableP)
|
void cSatipServerItem::SetMenuItem(cSkinDisplayMenu *displayMenuP, int indexP, bool currentP, bool selectableP)
|
||||||
@ -347,7 +347,6 @@ cSatipPluginSetup::cSatipPluginSetup()
|
|||||||
operatingModeM(SatipConfig.GetOperatingMode()),
|
operatingModeM(SatipConfig.GetOperatingMode()),
|
||||||
transportModeM(SatipConfig.GetTransportMode()),
|
transportModeM(SatipConfig.GetTransportMode()),
|
||||||
ciExtensionM(SatipConfig.GetCIExtension()),
|
ciExtensionM(SatipConfig.GetCIExtension()),
|
||||||
frontendReuseM(SatipConfig.GetFrontendReuse()),
|
|
||||||
eitScanM(SatipConfig.GetEITScan()),
|
eitScanM(SatipConfig.GetEITScan()),
|
||||||
numDisabledSourcesM(SatipConfig.GetDisabledSourcesCount()),
|
numDisabledSourcesM(SatipConfig.GetDisabledSourcesCount()),
|
||||||
numDisabledFiltersM(SatipConfig.GetDisabledFiltersCount())
|
numDisabledFiltersM(SatipConfig.GetDisabledFiltersCount())
|
||||||
@ -419,10 +418,6 @@ void cSatipPluginSetup::Setup(void)
|
|||||||
}
|
}
|
||||||
Add(new cMenuEditStraItem(tr("Transport mode"), &transportModeM, ELEMENTS(transportModeTextsM), transportModeTextsM));
|
Add(new cMenuEditStraItem(tr("Transport mode"), &transportModeM, ELEMENTS(transportModeTextsM), transportModeTextsM));
|
||||||
helpM.Append(tr("Define which transport mode shall be used.\n\nUnicast, Multicast, RTP-over-TCP"));
|
helpM.Append(tr("Define which transport mode shall be used.\n\nUnicast, Multicast, RTP-over-TCP"));
|
||||||
|
|
||||||
Add(new cMenuEditBoolItem(tr("Enable frontend reuse"), &frontendReuseM));
|
|
||||||
helpM.Append(tr("Define whether reusing a frontend for multiple channels in a transponder should be enabled."));
|
|
||||||
|
|
||||||
Add(new cOsdItem(tr("Active SAT>IP servers:"), osUnknown, false));
|
Add(new cOsdItem(tr("Active SAT>IP servers:"), osUnknown, false));
|
||||||
helpM.Append("");
|
helpM.Append("");
|
||||||
|
|
||||||
@ -484,7 +479,6 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
|
|||||||
bool hadSubMenu = HasSubMenu();
|
bool hadSubMenu = HasSubMenu();
|
||||||
int oldOperatingMode = operatingModeM;
|
int oldOperatingMode = operatingModeM;
|
||||||
int oldCiExtension = ciExtensionM;
|
int oldCiExtension = ciExtensionM;
|
||||||
int oldFrontendReuse = frontendReuseM;
|
|
||||||
int oldNumDisabledSources = numDisabledSourcesM;
|
int oldNumDisabledSources = numDisabledSourcesM;
|
||||||
int oldNumDisabledFilters = numDisabledFiltersM;
|
int oldNumDisabledFilters = numDisabledFiltersM;
|
||||||
eOSState state = cMenuSetupPage::ProcessKey(keyP);
|
eOSState state = cMenuSetupPage::ProcessKey(keyP);
|
||||||
@ -510,7 +504,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) || ( oldFrontendReuse != frontendReuseM) || (detachedModeM != SatipConfig.GetDetachedMode()))) {
|
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))
|
||||||
@ -575,7 +569,6 @@ void cSatipPluginSetup::Store(void)
|
|||||||
SetupStore("OperatingMode", operatingModeM);
|
SetupStore("OperatingMode", operatingModeM);
|
||||||
SetupStore("TransportMode", transportModeM);
|
SetupStore("TransportMode", transportModeM);
|
||||||
SetupStore("EnableCIExtension", ciExtensionM);
|
SetupStore("EnableCIExtension", ciExtensionM);
|
||||||
SetupStore("EnableFrontendReuse", frontendReuseM);
|
|
||||||
SetupStore("EnableEITScan", eitScanM);
|
SetupStore("EnableEITScan", eitScanM);
|
||||||
StoreCicams("CICAM", cicamsM);
|
StoreCicams("CICAM", cicamsM);
|
||||||
StoreSources("DisabledSources", disabledSourcesM);
|
StoreSources("DisabledSources", disabledSourcesM);
|
||||||
|
1
setup.h
1
setup.h
@ -22,7 +22,6 @@ private:
|
|||||||
const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
|
const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
|
||||||
const char *transportModeTextsM[cSatipConfig::eTransportModeCount];
|
const char *transportModeTextsM[cSatipConfig::eTransportModeCount];
|
||||||
int ciExtensionM;
|
int ciExtensionM;
|
||||||
int frontendReuseM;
|
|
||||||
int cicamsM[MAX_CICAM_COUNT];
|
int cicamsM[MAX_CICAM_COUNT];
|
||||||
const char *cicamTextsM[CA_SYSTEMS_TABLE_SIZE];
|
const char *cicamTextsM[CA_SYSTEMS_TABLE_SIZE];
|
||||||
int eitScanM;
|
int eitScanM;
|
||||||
|
33
socket.c
33
socket.c
@ -19,35 +19,13 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
#if defined(__GLIBC__)
|
|
||||||
#if defined(__GLIBC_PREREQ)
|
|
||||||
#if !__GLIBC_PREREQ(2,12)
|
|
||||||
#define __SATIP_DISABLE_RECVMMSG__
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cSatipSocket::cSatipSocket()
|
cSatipSocket::cSatipSocket()
|
||||||
: socketPortM(0),
|
: socketPortM(0),
|
||||||
socketDescM(-1),
|
socketDescM(-1),
|
||||||
isMulticastM(false),
|
isMulticastM(false),
|
||||||
useSsmM(false),
|
useSsmM(false),
|
||||||
streamAddrM(htonl(INADDR_ANY)),
|
streamAddrM(htonl(INADDR_ANY)),
|
||||||
sourceAddrM(htonl(INADDR_ANY)),
|
sourceAddrM(htonl(INADDR_ANY))
|
||||||
rcvBufSizeM(0)
|
|
||||||
{
|
|
||||||
debug1("%s", __PRETTY_FUNCTION__);
|
|
||||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
|
||||||
}
|
|
||||||
|
|
||||||
cSatipSocket::cSatipSocket(size_t rcvBufSizeP)
|
|
||||||
: socketPortM(0),
|
|
||||||
socketDescM(-1),
|
|
||||||
isMulticastM(false),
|
|
||||||
useSsmM(false),
|
|
||||||
streamAddrM(htonl(INADDR_ANY)),
|
|
||||||
sourceAddrM(htonl(INADDR_ANY)),
|
|
||||||
rcvBufSizeM(rcvBufSizeP)
|
|
||||||
{
|
{
|
||||||
debug1("%s", __PRETTY_FUNCTION__);
|
debug1("%s", __PRETTY_FUNCTION__);
|
||||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||||
@ -92,11 +70,6 @@ bool cSatipSocket::Open(const int portP, const bool reuseP)
|
|||||||
ERROR_IF_FUNC(setsockopt(socketDescM, SOL_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0,
|
ERROR_IF_FUNC(setsockopt(socketDescM, SOL_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0,
|
||||||
"setsockopt(IP_PKTINFO)", Close(), return false);
|
"setsockopt(IP_PKTINFO)", Close(), return false);
|
||||||
#endif // __FreeBSD__
|
#endif // __FreeBSD__
|
||||||
// Tweak receive buffer size if requested
|
|
||||||
if (rcvBufSizeM > 0) {
|
|
||||||
ERROR_IF_FUNC(setsockopt(socketDescM, SOL_SOCKET, SO_RCVBUF, &rcvBufSizeM, sizeof(rcvBufSizeM)) < 0,
|
|
||||||
"setsockopt(SO_RCVBUF)", Close(), return false);
|
|
||||||
}
|
|
||||||
// Bind socket
|
// Bind socket
|
||||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||||
sockAddrM.sin_family = AF_INET;
|
sockAddrM.sin_family = AF_INET;
|
||||||
@ -128,7 +101,7 @@ bool cSatipSocket::OpenMulticast(const int portP, const char *streamAddrP, const
|
|||||||
|
|
||||||
void cSatipSocket::Close(void)
|
void cSatipSocket::Close(void)
|
||||||
{
|
{
|
||||||
debug1("%s socketPort=%d", __PRETTY_FUNCTION__, socketPortM);
|
debug1("%s sockerPort=%d", __PRETTY_FUNCTION__, socketPortM);
|
||||||
// Check if socket exists
|
// Check if socket exists
|
||||||
if (socketDescM >= 0) {
|
if (socketDescM >= 0) {
|
||||||
Leave();
|
Leave();
|
||||||
@ -316,7 +289,7 @@ int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRec
|
|||||||
error("%s Invalid parameter(s)", __PRETTY_FUNCTION__);
|
error("%s Invalid parameter(s)", __PRETTY_FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#ifndef __SATIP_DISABLE_RECVMMSG__
|
#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];
|
||||||
|
3
socket.h
3
socket.h
@ -19,15 +19,12 @@ private:
|
|||||||
bool useSsmM;
|
bool useSsmM;
|
||||||
in_addr_t streamAddrM;
|
in_addr_t streamAddrM;
|
||||||
in_addr_t sourceAddrM;
|
in_addr_t sourceAddrM;
|
||||||
size_t rcvBufSizeM;
|
|
||||||
|
|
||||||
bool CheckAddress(const char *addrP, in_addr_t *inAddrP);
|
bool CheckAddress(const char *addrP, in_addr_t *inAddrP);
|
||||||
bool Join(void);
|
bool Join(void);
|
||||||
bool Leave(void);
|
bool Leave(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cSatipSocket();
|
cSatipSocket();
|
||||||
explicit cSatipSocket(size_t rcvBufSizeP);
|
|
||||||
virtual ~cSatipSocket();
|
virtual ~cSatipSocket();
|
||||||
bool Open(const int portP = 0, const bool reuseP = false);
|
bool Open(const int portP = 0, const bool reuseP = false);
|
||||||
bool OpenMulticast(const int portP, const char *streamAddrP, const char *sourceAddrP);
|
bool OpenMulticast(const int portP, const char *streamAddrP, const char *sourceAddrP);
|
||||||
|
111
tuner.c
111
tuner.c
@ -25,8 +25,6 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
|||||||
rtcpM(*this),
|
rtcpM(*this),
|
||||||
streamAddrM(""),
|
streamAddrM(""),
|
||||||
streamParamM(""),
|
streamParamM(""),
|
||||||
lastAddrM(""),
|
|
||||||
lastParamM(""),
|
|
||||||
tnrParamM(""),
|
tnrParamM(""),
|
||||||
streamPortM(SATIP_DEFAULT_RTSP_PORT),
|
streamPortM(SATIP_DEFAULT_RTSP_PORT),
|
||||||
currentServerM(NULL, deviceP.GetId(), 0),
|
currentServerM(NULL, deviceP.GetId(), 0),
|
||||||
@ -36,14 +34,12 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
|||||||
keepAliveM(),
|
keepAliveM(),
|
||||||
statusUpdateM(),
|
statusUpdateM(),
|
||||||
pidUpdateCacheM(),
|
pidUpdateCacheM(),
|
||||||
setupTimeoutM(-1),
|
|
||||||
sessionM(""),
|
sessionM(""),
|
||||||
currentStateM(tsIdle),
|
currentStateM(tsIdle),
|
||||||
internalStateM(),
|
internalStateM(),
|
||||||
externalStateM(),
|
externalStateM(),
|
||||||
timeoutM(eMinKeepAliveIntervalMs - eKeepAlivePreBufferMs),
|
timeoutM(eMinKeepAliveIntervalMs),
|
||||||
hasLockM(false),
|
hasLockM(false),
|
||||||
signalStrengthDBmM(0.0),
|
|
||||||
signalStrengthM(-1),
|
signalStrengthM(-1),
|
||||||
signalQualityM(-1),
|
signalQualityM(-1),
|
||||||
frontendIdM(-1),
|
frontendIdM(-1),
|
||||||
@ -120,8 +116,6 @@ void cSatipTuner::Action(void)
|
|||||||
break;
|
break;
|
||||||
case tsSet:
|
case tsSet:
|
||||||
debug4("%s: tsSet [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug4("%s: tsSet [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkTearAndPlay))
|
|
||||||
Disconnect();
|
|
||||||
if (Connect()) {
|
if (Connect()) {
|
||||||
tuning.Set(eTuningTimeoutMs);
|
tuning.Set(eTuningTimeoutMs);
|
||||||
RequestState(tsTuned, smInternal);
|
RequestState(tsTuned, smInternal);
|
||||||
@ -132,7 +126,6 @@ void cSatipTuner::Action(void)
|
|||||||
break;
|
break;
|
||||||
case tsTuned:
|
case tsTuned:
|
||||||
debug4("%s: tsTuned [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug4("%s: tsTuned [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
deviceM->SetChannelTuned();
|
|
||||||
reConnectM.Set(eConnectTimeoutMs);
|
reConnectM.Set(eConnectTimeoutMs);
|
||||||
idleCheck.Set(eIdleCheckTimeoutMs);
|
idleCheck.Set(eIdleCheckTimeoutMs);
|
||||||
lastIdleStatus = false;
|
lastIdleStatus = false;
|
||||||
@ -141,7 +134,6 @@ void cSatipTuner::Action(void)
|
|||||||
// Quirk for devices without valid reception data
|
// Quirk for devices without valid reception data
|
||||||
if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkForceLock)) {
|
if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkForceLock)) {
|
||||||
hasLockM = true;
|
hasLockM = true;
|
||||||
signalStrengthDBmM = eDefaultSignalStrengthDBm;
|
|
||||||
signalStrengthM = eDefaultSignalStrength;
|
signalStrengthM = eDefaultSignalStrength;
|
||||||
signalQualityM = eDefaultSignalQuality;
|
signalQualityM = eDefaultSignalQuality;
|
||||||
}
|
}
|
||||||
@ -180,7 +172,6 @@ void cSatipTuner::Action(void)
|
|||||||
idleCheck.Set(eIdleCheckTimeoutMs);
|
idleCheck.Set(eIdleCheckTimeoutMs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Receive();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("Unknown tuner status %d [device %d]", currentStateM, deviceIdM);
|
error("Unknown tuner status %d [device %d]", currentStateM, deviceIdM);
|
||||||
@ -197,6 +188,8 @@ bool cSatipTuner::Open(void)
|
|||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
|
|
||||||
|
RequestState(tsSet, smExternal);
|
||||||
|
|
||||||
// return always true
|
// return always true
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -206,8 +199,7 @@ bool cSatipTuner::Close(void)
|
|||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
|
|
||||||
if (setupTimeoutM.TimedOut())
|
RequestState(tsRelease, smExternal);
|
||||||
RequestState(tsRelease, smExternal);
|
|
||||||
|
|
||||||
// return always true
|
// return always true
|
||||||
return true;
|
return true;
|
||||||
@ -223,34 +215,25 @@ bool cSatipTuner::Connect(void)
|
|||||||
tnrParamM = "";
|
tnrParamM = "";
|
||||||
// Just retune
|
// Just retune
|
||||||
if (streamIdM >= 0) {
|
if (streamIdM >= 0) {
|
||||||
if (!strcmp(*streamParamM, *lastParamM) && hasLockM) {
|
|
||||||
debug1("%s Identical parameters [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
|
||||||
//return true; // fall through because detection does not work reliably
|
|
||||||
}
|
|
||||||
cString uri = cString::sprintf("%sstream=%d?%s", *connectionUri, streamIdM, *streamParamM);
|
cString uri = cString::sprintf("%sstream=%d?%s", *connectionUri, streamIdM, *streamParamM);
|
||||||
debug1("%s Retuning [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug1("%s Retuning [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
if (rtspM.Play(*uri)) {
|
if (rtspM.Play(*uri)) {
|
||||||
keepAliveM.Set(timeoutM);
|
keepAliveM.Set(timeoutM);
|
||||||
lastParamM = streamParamM;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rtspM.SetInterface(nextServerM.IsValid() ? *nextServerM.GetSrcAddress() : NULL) && rtspM.Options(*connectionUri)) {
|
else if (rtspM.Options(*connectionUri)) {
|
||||||
cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM);
|
cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM);
|
||||||
bool useTcp = SatipConfig.IsTransportModeRtpOverTcp() && nextServerM.IsValid() && nextServerM.IsQuirk(cSatipServer::eSatipQuirkRtpOverTcp);
|
bool useTcp = SatipConfig.IsTransportModeRtpOverTcp() && nextServerM.IsValid() && nextServerM.IsQuirk(cSatipServer::eSatipQuirkRtpOverTcp);
|
||||||
// Flush any old content
|
// Flush any old content
|
||||||
//rtpM.Flush();
|
//rtpM.Flush();
|
||||||
//rtcpM.Flush();
|
//rtcpM.Flush();
|
||||||
if (useTcp)
|
|
||||||
debug1("%s Requesting TCP [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
|
||||||
if (rtspM.Setup(*uri, rtpM.Port(), rtcpM.Port(), useTcp)) {
|
if (rtspM.Setup(*uri, rtpM.Port(), rtcpM.Port(), useTcp)) {
|
||||||
lastParamM = streamParamM;
|
|
||||||
keepAliveM.Set(timeoutM);
|
keepAliveM.Set(timeoutM);
|
||||||
if (nextServerM.IsValid()) {
|
if (nextServerM.IsValid()) {
|
||||||
currentServerM = nextServerM;
|
currentServerM = nextServerM;
|
||||||
nextServerM.Reset();
|
nextServerM.Reset();
|
||||||
}
|
}
|
||||||
lastAddrM = connectionUri;
|
|
||||||
currentServerM.Attach();
|
currentServerM.Attach();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -268,8 +251,8 @@ bool cSatipTuner::Disconnect(void)
|
|||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
|
|
||||||
if (!isempty(*lastAddrM) && (streamIdM >= 0)) {
|
if (!isempty(*streamAddrM) && (streamIdM >= 0)) {
|
||||||
cString uri = cString::sprintf("%sstream=%d", *lastAddrM, streamIdM);
|
cString uri = cString::sprintf("%sstream=%d", *GetBaseUrl(*streamAddrM, streamPortM), streamIdM);
|
||||||
rtspM.Teardown(*uri);
|
rtspM.Teardown(*uri);
|
||||||
// some devices requires a teardown for TCP connection also
|
// some devices requires a teardown for TCP connection also
|
||||||
rtspM.Reset();
|
rtspM.Reset();
|
||||||
@ -278,14 +261,13 @@ bool cSatipTuner::Disconnect(void)
|
|||||||
|
|
||||||
// Reset signal parameters
|
// Reset signal parameters
|
||||||
hasLockM = false;
|
hasLockM = false;
|
||||||
signalStrengthDBmM = 0.0;
|
|
||||||
signalStrengthM = -1;
|
signalStrengthM = -1;
|
||||||
signalQualityM = -1;
|
signalQualityM = -1;
|
||||||
frontendIdM = -1;
|
frontendIdM = -1;
|
||||||
|
|
||||||
currentServerM.Detach();
|
currentServerM.Detach();
|
||||||
statusUpdateM.Set(0);
|
statusUpdateM.Set(0);
|
||||||
timeoutM = eMinKeepAliveIntervalMs - eKeepAlivePreBufferMs;
|
timeoutM = eMinKeepAliveIntervalMs;
|
||||||
pmtPidM = -1;
|
pmtPidM = -1;
|
||||||
addPidsM.Clear();
|
addPidsM.Clear();
|
||||||
delPidsM.Clear();
|
delPidsM.Clear();
|
||||||
@ -348,9 +330,8 @@ void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP)
|
|||||||
// No signal corresponds to 0
|
// No signal corresponds to 0
|
||||||
c = strstr(c, ",");
|
c = strstr(c, ",");
|
||||||
value = min(atoi(++c), 255);
|
value = min(atoi(++c), 255);
|
||||||
signalStrengthDBmM = (value >= 0) ? 40.0 * (value - 32) / 192.0 - 65.0 : 0.0;
|
|
||||||
// Scale value to 0-100
|
// Scale value to 0-100
|
||||||
signalStrengthM = (value >= 0) ? value * 100 / 255 : -1;
|
signalStrengthM = (value >= 0) ? (value * 100 / 255) : -1;
|
||||||
|
|
||||||
// lock:
|
// lock:
|
||||||
// lock Set to one of the following values:
|
// lock Set to one of the following values:
|
||||||
@ -394,7 +375,6 @@ void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
|
|||||||
if (nextServerM.IsQuirk(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;
|
||||||
timeoutM -= eKeepAlivePreBufferMs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipTuner::SetupTransport(int rtpPortP, int rtcpPortP, const char *streamAddrP, const char *sourceAddrP)
|
void cSatipTuner::SetupTransport(int rtpPortP, int rtcpPortP, const char *streamAddrP, const char *sourceAddrP)
|
||||||
@ -405,8 +385,8 @@ void cSatipTuner::SetupTransport(int rtpPortP, int rtcpPortP, const char *stream
|
|||||||
// Adapt RTP to any transport media change
|
// Adapt RTP to any transport media change
|
||||||
if (multicast != rtpM.IsMulticast() || rtpPortP != rtpM.Port()) {
|
if (multicast != rtpM.IsMulticast() || rtpPortP != rtpM.Port()) {
|
||||||
cSatipPoller::GetInstance()->Unregister(rtpM);
|
cSatipPoller::GetInstance()->Unregister(rtpM);
|
||||||
|
rtpM.Close();
|
||||||
if (rtpPortP >= 0) {
|
if (rtpPortP >= 0) {
|
||||||
rtpM.Close();
|
|
||||||
if (multicast)
|
if (multicast)
|
||||||
rtpM.OpenMulticast(rtpPortP, streamAddrP, sourceAddrP);
|
rtpM.OpenMulticast(rtpPortP, streamAddrP, sourceAddrP);
|
||||||
else
|
else
|
||||||
@ -417,12 +397,12 @@ void cSatipTuner::SetupTransport(int rtpPortP, int rtcpPortP, const char *stream
|
|||||||
// Adapt RTCP to any transport media change
|
// Adapt RTCP to any transport media change
|
||||||
if (multicast != rtcpM.IsMulticast() || rtcpPortP != rtcpM.Port()) {
|
if (multicast != rtcpM.IsMulticast() || rtcpPortP != rtcpM.Port()) {
|
||||||
cSatipPoller::GetInstance()->Unregister(rtcpM);
|
cSatipPoller::GetInstance()->Unregister(rtcpM);
|
||||||
|
rtcpM.Close();
|
||||||
if (rtcpPortP >= 0) {
|
if (rtcpPortP >= 0) {
|
||||||
rtcpM.Close();
|
|
||||||
if (multicast)
|
if (multicast)
|
||||||
rtcpM.OpenMulticast(rtcpPortP, streamAddrP, sourceAddrP);
|
rtcpM.OpenMulticast(rtpPortP, streamAddrP, sourceAddrP);
|
||||||
else
|
else
|
||||||
rtcpM.Open(rtcpPortP);
|
rtcpM.Open(rtpPortP);
|
||||||
cSatipPoller::GetInstance()->Register(rtcpM);
|
cSatipPoller::GetInstance()->Register(rtcpM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -459,13 +439,7 @@ bool cSatipTuner::SetSource(cSatipServer *serverP, const int transponderP, const
|
|||||||
if (nextServerM.IsQuirk(cSatipServer::eSatipQuirkForcePilot) && strstr(parameterP, "msys=dvbs2") && !strstr(parameterP, "plts="))
|
if (nextServerM.IsQuirk(cSatipServer::eSatipQuirkForcePilot) && strstr(parameterP, "msys=dvbs2") && !strstr(parameterP, "plts="))
|
||||||
streamParamM = rtspM.RtspUnescapeString(*cString::sprintf("%s&plts=on", parameterP));
|
streamParamM = rtspM.RtspUnescapeString(*cString::sprintf("%s&plts=on", parameterP));
|
||||||
// Reconnect
|
// Reconnect
|
||||||
if (!isempty(*lastAddrM)) {
|
|
||||||
cString connectionUri = GetBaseUrl(*streamAddrM, streamPortM);
|
|
||||||
if (strcmp(*connectionUri, *lastAddrM))
|
|
||||||
RequestState(tsRelease, smInternal);
|
|
||||||
}
|
|
||||||
RequestState(tsSet, smExternal);
|
RequestState(tsSet, smExternal);
|
||||||
setupTimeoutM.Set(eSetupTimeoutMs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -505,24 +479,17 @@ bool cSatipTuner::UpdatePids(bool forceP)
|
|||||||
cString uri = cString::sprintf("%sstream=%d", *GetBaseUrl(*streamAddrM, streamPortM), streamIdM);
|
cString uri = cString::sprintf("%sstream=%d", *GetBaseUrl(*streamAddrM, streamPortM), streamIdM);
|
||||||
bool useci = (SatipConfig.GetCIExtension() && currentServerM.HasCI());
|
bool useci = (SatipConfig.GetCIExtension() && currentServerM.HasCI());
|
||||||
bool usedummy = currentServerM.IsQuirk(cSatipServer::eSatipQuirkPlayPids);
|
bool usedummy = currentServerM.IsQuirk(cSatipServer::eSatipQuirkPlayPids);
|
||||||
bool paramadded = false;
|
|
||||||
if (forceP || usedummy) {
|
if (forceP || usedummy) {
|
||||||
if (pidsM.Size()) {
|
if (pidsM.Size())
|
||||||
uri = cString::sprintf("%s%spids=%s", *uri, paramadded ? "&" : "?", *pidsM.ListPids());
|
uri = cString::sprintf("%s?pids=%s", *uri, *pidsM.ListPids());
|
||||||
if (usedummy && (pidsM.Size() == 1) && (pidsM[0] < 0x20))
|
if (usedummy && (pidsM.Size() == 1) && (pidsM[0] < 0x20))
|
||||||
uri = cString::sprintf("%s,%d", *uri, eDummyPid);
|
uri = cString::sprintf("%s,%d", *uri, eDummyPid);
|
||||||
paramadded = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (addPidsM.Size()) {
|
if (addPidsM.Size())
|
||||||
uri = cString::sprintf("%s%saddpids=%s", *uri, paramadded ? "&" : "?", *addPidsM.ListPids());
|
uri = cString::sprintf("%s?addpids=%s", *uri, *addPidsM.ListPids());
|
||||||
paramadded = true;
|
if (delPidsM.Size())
|
||||||
}
|
uri = cString::sprintf("%s%sdelpids=%s", *uri, addPidsM.Size() ? "&" : "?", *delPidsM.ListPids());
|
||||||
if (delPidsM.Size()) {
|
|
||||||
uri = cString::sprintf("%s%sdelpids=%s", *uri, paramadded ? "&" : "?", *delPidsM.ListPids());
|
|
||||||
paramadded = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (useci) {
|
if (useci) {
|
||||||
if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkCiXpmt)) {
|
if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkCiXpmt)) {
|
||||||
@ -535,10 +502,9 @@ bool cSatipTuner::UpdatePids(bool forceP)
|
|||||||
int pid = deviceM->GetPmtPid();
|
int pid = deviceM->GetPmtPid();
|
||||||
if ((pid > 0) && (pid != pmtPidM)) {
|
if ((pid > 0) && (pid != pmtPidM)) {
|
||||||
int slot = deviceM->GetCISlot();
|
int slot = deviceM->GetCISlot();
|
||||||
uri = cString::sprintf("%s%sx_pmt=%d", *uri, paramadded ? "&" : "?", pid);
|
uri = cString::sprintf("%s&x_pmt=%d", *uri, pid);
|
||||||
if (slot > 0)
|
if (slot > 0)
|
||||||
uri = cString::sprintf("%s&x_ci=%d", *uri, slot);
|
uri = cString::sprintf("%s&x_ci=%d", *uri, slot);
|
||||||
paramadded = true;
|
|
||||||
}
|
}
|
||||||
pmtPidM = pid;
|
pmtPidM = pid;
|
||||||
}
|
}
|
||||||
@ -546,18 +512,14 @@ bool cSatipTuner::UpdatePids(bool forceP)
|
|||||||
// CI extension parameters:
|
// CI extension parameters:
|
||||||
// - tnr : specifies a channel config entry
|
// - tnr : specifies a channel config entry
|
||||||
cString param = deviceM->GetTnrParameterString();
|
cString param = deviceM->GetTnrParameterString();
|
||||||
if (!isempty(*param) && strcmp(*tnrParamM, *param) != 0) {
|
if (!isempty(*param) && strcmp(*tnrParamM, *param) != 0)
|
||||||
uri = cString::sprintf("%s%stnr=%s", *uri, paramadded ? "&" : "?", *param);
|
uri = cString::sprintf("%s&tnr=%s", *uri, *param);
|
||||||
paramadded = true;
|
|
||||||
}
|
|
||||||
tnrParamM = param;
|
tnrParamM = param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (paramadded) {
|
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
|
||||||
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
|
if (!rtspM.Play(*uri))
|
||||||
if (!rtspM.Play(*uri))
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
addPidsM.Clear();
|
addPidsM.Clear();
|
||||||
delPidsM.Clear();
|
delPidsM.Clear();
|
||||||
}
|
}
|
||||||
@ -565,19 +527,6 @@ bool cSatipTuner::UpdatePids(bool forceP)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipTuner::Receive(void)
|
|
||||||
{
|
|
||||||
debug16("%s tunerState=%s [device %d]", __PRETTY_FUNCTION__, TunerStateString(currentStateM), deviceIdM);
|
|
||||||
cMutexLock MutexLock(&mutexM);
|
|
||||||
if (!isempty(*streamAddrM)) {
|
|
||||||
cString uri = GetBaseUrl(*streamAddrM, streamPortM);
|
|
||||||
if (!rtspM.Receive(*uri))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cSatipTuner::KeepAlive(bool forceP)
|
bool cSatipTuner::KeepAlive(bool forceP)
|
||||||
{
|
{
|
||||||
debug16("%s (%d) tunerState=%s [device %d]", __PRETTY_FUNCTION__, forceP, TunerStateString(currentStateM), deviceIdM);
|
debug16("%s (%d) tunerState=%s [device %d]", __PRETTY_FUNCTION__, forceP, TunerStateString(currentStateM), deviceIdM);
|
||||||
@ -718,12 +667,6 @@ int cSatipTuner::SignalStrength(void)
|
|||||||
return signalStrengthM;
|
return signalStrengthM;
|
||||||
}
|
}
|
||||||
|
|
||||||
double cSatipTuner::SignalStrengthDBm(void)
|
|
||||||
{
|
|
||||||
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
|
||||||
return signalStrengthDBmM;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cSatipTuner::SignalQuality(void)
|
int cSatipTuner::SignalQuality(void)
|
||||||
{
|
{
|
||||||
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
|
30
tuner.h
30
tuner.h
@ -69,7 +69,6 @@ public:
|
|||||||
void Set(cSatipServer *serverP, const int transponderP) { serverM = serverP; transponderM = transponderP; }
|
void Set(cSatipServer *serverP, const int transponderP) { serverM = serverP; transponderM = transponderP; }
|
||||||
void Reset(void) { serverM = NULL; transponderM = 0; }
|
void Reset(void) { serverM = NULL; transponderM = 0; }
|
||||||
cString GetAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerAddress(serverM) : ""; }
|
cString GetAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerAddress(serverM) : ""; }
|
||||||
cString GetSrcAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetSourceAddress(serverM) : ""; }
|
|
||||||
int GetPort(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerPort(serverM) : SATIP_DEFAULT_RTSP_PORT; }
|
int GetPort(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerPort(serverM) : SATIP_DEFAULT_RTSP_PORT; }
|
||||||
cString GetInfo(void) { return cString::sprintf("server=%s deviceid=%d transponder=%d", serverM ? "assigned" : "null", deviceIdM, transponderM); }
|
cString GetInfo(void) { return cString::sprintf("server=%s deviceid=%d transponder=%d", serverM ? "assigned" : "null", deviceIdM, transponderM); }
|
||||||
};
|
};
|
||||||
@ -78,19 +77,16 @@ class cSatipTuner : public cThread, public cSatipTunerStatistics, public cSatipT
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
eDummyPid = 100,
|
eDummyPid = 100,
|
||||||
eDefaultSignalStrengthDBm = -25,
|
eDefaultSignalStrength = 15,
|
||||||
eDefaultSignalStrength = 224,
|
eDefaultSignalQuality = 224,
|
||||||
eDefaultSignalQuality = 15,
|
eSleepTimeoutMs = 250, // in milliseconds
|
||||||
eSleepTimeoutMs = 250, // in milliseconds
|
eStatusUpdateTimeoutMs = 1000, // in milliseconds
|
||||||
eStatusUpdateTimeoutMs = 1000, // in milliseconds
|
ePidUpdateIntervalMs = 250, // in milliseconds
|
||||||
ePidUpdateIntervalMs = 250, // in milliseconds
|
eConnectTimeoutMs = 5000, // in milliseconds
|
||||||
eConnectTimeoutMs = 5000, // in milliseconds
|
eIdleCheckTimeoutMs = 15000, // in milliseconds
|
||||||
eIdleCheckTimeoutMs = 15000, // in milliseconds
|
eTuningTimeoutMs = 20000, // in milliseconds
|
||||||
eTuningTimeoutMs = 20000, // in milliseconds
|
eMinKeepAliveIntervalMs = 30000 // in milliseconds
|
||||||
eMinKeepAliveIntervalMs = 30000, // in milliseconds
|
|
||||||
eKeepAlivePreBufferMs = 2000, // in milliseconds
|
|
||||||
eSetupTimeoutMs = 2000 // in milliseconds
|
|
||||||
};
|
};
|
||||||
enum eTunerState { tsIdle, tsRelease, tsSet, tsTuned, tsLocked };
|
enum eTunerState { tsIdle, tsRelease, tsSet, tsTuned, tsLocked };
|
||||||
enum eStateMode { smInternal, smExternal };
|
enum eStateMode { smInternal, smExternal };
|
||||||
@ -103,8 +99,6 @@ private:
|
|||||||
cSatipRtcp rtcpM;
|
cSatipRtcp rtcpM;
|
||||||
cString streamAddrM;
|
cString streamAddrM;
|
||||||
cString streamParamM;
|
cString streamParamM;
|
||||||
cString lastAddrM;
|
|
||||||
cString lastParamM;
|
|
||||||
cString tnrParamM;
|
cString tnrParamM;
|
||||||
int streamPortM;
|
int streamPortM;
|
||||||
cSatipTunerServer currentServerM;
|
cSatipTunerServer currentServerM;
|
||||||
@ -114,14 +108,12 @@ private:
|
|||||||
cTimeMs keepAliveM;
|
cTimeMs keepAliveM;
|
||||||
cTimeMs statusUpdateM;
|
cTimeMs statusUpdateM;
|
||||||
cTimeMs pidUpdateCacheM;
|
cTimeMs pidUpdateCacheM;
|
||||||
cTimeMs setupTimeoutM;
|
|
||||||
cString sessionM;
|
cString sessionM;
|
||||||
eTunerState currentStateM;
|
eTunerState currentStateM;
|
||||||
cVector<eTunerState> internalStateM;
|
cVector<eTunerState> internalStateM;
|
||||||
cVector<eTunerState> externalStateM;
|
cVector<eTunerState> externalStateM;
|
||||||
int timeoutM;
|
int timeoutM;
|
||||||
bool hasLockM;
|
bool hasLockM;
|
||||||
double signalStrengthDBmM;
|
|
||||||
int signalStrengthM;
|
int signalStrengthM;
|
||||||
int signalQualityM;
|
int signalQualityM;
|
||||||
int frontendIdM;
|
int frontendIdM;
|
||||||
@ -133,7 +125,6 @@ private:
|
|||||||
|
|
||||||
bool Connect(void);
|
bool Connect(void);
|
||||||
bool Disconnect(void);
|
bool Disconnect(void);
|
||||||
bool Receive(void);
|
|
||||||
bool KeepAlive(bool forceP = false);
|
bool KeepAlive(bool forceP = false);
|
||||||
bool ReadReceptionStatus(bool forceP = false);
|
bool ReadReceptionStatus(bool forceP = false);
|
||||||
bool UpdatePids(bool forceP = false);
|
bool UpdatePids(bool forceP = false);
|
||||||
@ -157,7 +148,6 @@ public:
|
|||||||
bool Close(void);
|
bool Close(void);
|
||||||
int FrontendId(void);
|
int FrontendId(void);
|
||||||
int SignalStrength(void);
|
int SignalStrength(void);
|
||||||
double SignalStrengthDBm(void);
|
|
||||||
int SignalQuality(void);
|
int SignalQuality(void);
|
||||||
bool HasLock(void);
|
bool HasLock(void);
|
||||||
cString GetSignalStatus(void);
|
cString GetSignalStatus(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user