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 | |
---|---|---|---|
|
02a842f95a | ||
|
a76ff4c25a | ||
|
64554ad0cc | ||
|
0a216f1cf9 | ||
|
02296fa8d7 | ||
|
417d4ed8fc | ||
|
1ad0a81d16 | ||
|
27122747a7 | ||
|
ba0b04ba12 | ||
|
55362a2db6 | ||
|
0115ba1725 | ||
|
43b60b1566 | ||
|
df81905821 | ||
|
cc19cff5e9 | ||
|
63d3c4370b | ||
|
a7625c028c | ||
|
17c36fa9d2 | ||
|
826dea4ba8 | ||
|
a3fa5865f3 | ||
|
19e3057f34 | ||
|
b697e435d4 | ||
|
66d7aae89d | ||
|
a4051bf88c | ||
|
98ecd22a27 | ||
|
8130a4b4e5 | ||
|
5254bb7ca2 | ||
|
6c74c10cbb | ||
|
6e6cd42c84 | ||
|
299296bbb1 |
34
HISTORY
34
HISTORY
@ -193,3 +193,37 @@ VDR Plugin 'satip' Revision History
|
|||||||
- Added support for FRITZ!Box 6490 Cable (Thanks to 9000h).
|
- Added support for FRITZ!Box 6490 Cable (Thanks to 9000h).
|
||||||
- Updated FRITZ!WLAN Repeater DVB-C detection for the latest firmware (Thanks to 9000h).
|
- Updated FRITZ!WLAN Repeater DVB-C detection for the latest firmware (Thanks to 9000h).
|
||||||
- Added GCC7 compatibility (Thanks to Sascha Kuehndel).
|
- 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.
|
||||||
|
127
README
127
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: http://www.saunalahti.fi/~rahrenbe/vdr/satip/
|
Project's homepage: https://github.com/rofafor/vdr-plugin-satip
|
||||||
|
|
||||||
Latest version available at: http://www.saunalahti.fi/~rahrenbe/vdr/satip/
|
Latest version available at: https://github.com/rofafor/vdr-plugin-satip/releases
|
||||||
|
|
||||||
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,12 +47,38 @@ 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. The parameter string is a semicolon
|
via UPnP somehow can't be used. Multiple service entries can be given
|
||||||
separated list of "<ipaddress>|<model>|<description>" entries. The model
|
separated by a semicolon:
|
||||||
consists of a DVB system (DVBS2,DVBT2,DVBT,DVBC) and number of available
|
|
||||||
frontends separated by a hyphen:
|
[<srcaddress>@]<ipaddress>[:<port>]|<model>[:<filter>]|<description>[:<quirk>];...
|
||||||
|
|
||||||
|
- 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 [<srcaddress>@]<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'
|
||||||
@ -86,46 +112,50 @@ 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.
|
||||||
- [Red:Scan] Forces network scanning of SAT>IP hardware.
|
- Enable frontend reuse = yes Certain devices might have artifacts if
|
||||||
- [Yellow:Devices] Opens SAT>IP device status menu.
|
multiple channels are assigned to the same
|
||||||
- [Blue:Info] Opens SAT>IP information/statistics menu.
|
frontend. If you want to avoid such a
|
||||||
- [Ok] Opens information menu of selected SAT>IP
|
frontend assignment, set this option to "no".
|
||||||
device.
|
- [Red:Scan] Forces network scanning of SAT>IP hardware.
|
||||||
|
- [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:
|
||||||
|
|
||||||
@ -159,6 +189,9 @@ 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
|
- If you are experiencing glitches in the video stream, one possible
|
||||||
reason can be buffer overflows in RTP receive sockets. You can verify
|
reason can be buffer overflows in RTP receive sockets. You can verify
|
||||||
this by checking "receive buffer errors" counter by running "netstat -s"
|
this by checking "receive buffer errors" counter by running "netstat -s"
|
||||||
|
1
config.c
1
config.c
@ -15,6 +15,7 @@ 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),
|
||||||
|
3
config.h
3
config.h
@ -17,6 +17,7 @@ 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;
|
||||||
@ -74,6 +75,7 @@ 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; }
|
||||||
@ -95,6 +97,7 @@ public:
|
|||||||
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; }
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
""" Simple tool to detect SAT>IP devices as JSON.
|
""" Simple tool to detect SAT>IP devices as JSON.
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
@ -8,21 +7,26 @@ import sys
|
|||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
SSDP_BIND = '0.0.0.0'
|
SSDP_BIND = "0.0.0.0"
|
||||||
SSDP_ADDR = '239.255.255.250'
|
SSDP_ADDR = "239.255.255.250"
|
||||||
SSDP_PORT = 1900
|
SSDP_PORT = 1900
|
||||||
SSDP_MX = 1
|
SSDP_MX = 1
|
||||||
SSDP_ST = 'urn:ses-com:device:SatIPServer:1'
|
SSDP_ST = "urn:ses-com:device:SatIPServer:1"
|
||||||
SSDP_REQUEST = 'M-SEARCH * HTTP/1.1\r\n' + \
|
SSDP_REQUEST = "\r\n".join(
|
||||||
'HOST: %s:%d\r\n' % (SSDP_ADDR, SSDP_PORT) + \
|
[
|
||||||
'MAN: "ssdp:discover"\r\n' + \
|
"M-SEARCH * HTTP/1.1",
|
||||||
'MX: %d\r\n' % (SSDP_MX, ) + \
|
f"HOST: {SSDP_ADDR}:{SSDP_PORT}",
|
||||||
'ST: %s\r\n' % (SSDP_ST, ) + \
|
'MAN: "ssdp:discover"',
|
||||||
'\r\n'
|
f"MX: {SSDP_MX}",
|
||||||
|
f"ST: {SSDP_ST}",
|
||||||
|
"USER-AGENT: vdr-detectsatip",
|
||||||
|
"\r\n",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def parse_satip_xml(data):
|
def parse_satip_xml(data):
|
||||||
""" Parse SAT>IP XML data.
|
"""Parse SAT>IP XML data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data (str): XML input data..
|
data (str): XML input data..
|
||||||
@ -30,12 +34,15 @@ def parse_satip_xml(data):
|
|||||||
Returns:
|
Returns:
|
||||||
dict: Parsed SAT>IP device name and frontend information.
|
dict: Parsed SAT>IP device name and frontend information.
|
||||||
"""
|
"""
|
||||||
result = {'name': '', 'frontends': {}}
|
result = {"name": "", "frontends": {}}
|
||||||
if data:
|
if data:
|
||||||
root = ET.fromstring(data)
|
root = ET.fromstring(data)
|
||||||
name = root.find('.//*/{urn:schemas-upnp-org:device-1-0}friendlyName')
|
name = root.find(".//*/{urn:schemas-upnp-org:device-1-0}friendlyName")
|
||||||
result['name'] = name.text
|
result["name"] = name.text
|
||||||
satipcap = root.find('.//*/{urn:ses-com:satip}X_SATIPCAP')
|
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 = {}
|
caps = {}
|
||||||
for system in satipcap.text.split(","):
|
for system in satipcap.text.split(","):
|
||||||
cap = system.split("-")
|
cap = system.split("-")
|
||||||
@ -44,12 +51,12 @@ def parse_satip_xml(data):
|
|||||||
if cap[0] in caps:
|
if cap[0] in caps:
|
||||||
count = count + caps[cap[0]]
|
count = count + caps[cap[0]]
|
||||||
caps[cap[0]] = count
|
caps[cap[0]] = count
|
||||||
result['frontends'] = caps
|
result["frontends"] = caps
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def detect_satip_devices():
|
def detect_satip_devices():
|
||||||
""" Detect available SAT>IP devices by sending a broadcast message.
|
"""Detect available SAT>IP devices by sending a broadcast message.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: Found SAT>IP devices.
|
list: Found SAT>IP devices.
|
||||||
@ -66,14 +73,14 @@ def detect_satip_devices():
|
|||||||
pass
|
pass
|
||||||
sock.settimeout(1)
|
sock.settimeout(1)
|
||||||
sock.bind((SSDP_BIND, SSDP_PORT))
|
sock.bind((SSDP_BIND, SSDP_PORT))
|
||||||
sock.sendto(SSDP_REQUEST, (SSDP_ADDR, SSDP_PORT))
|
sock.sendto(SSDP_REQUEST.encode("utf-8"), (SSDP_ADDR, SSDP_PORT))
|
||||||
try:
|
try:
|
||||||
while 1:
|
while 1:
|
||||||
data = sock.recv(1024)
|
data = sock.recv(1024).decode("utf-8")
|
||||||
if data:
|
if data:
|
||||||
for row in data.split('\r\n'):
|
for row in data.split("\r\n"):
|
||||||
if 'LOCATION:' in row:
|
if "LOCATION:" in row:
|
||||||
url = row.replace('LOCATION:', '').strip()
|
url = row.replace("LOCATION:", "").strip()
|
||||||
if url in urls:
|
if url in urls:
|
||||||
continue
|
continue
|
||||||
urls.append(url)
|
urls.append(url)
|
||||||
@ -87,5 +94,5 @@ def detect_satip_devices():
|
|||||||
return devices
|
return devices
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
json.dump(detect_satip_devices(), fp=sys.stdout, sort_keys=True, indent=2)
|
json.dump(detect_satip_devices(), fp=sys.stdout, sort_keys=True, indent=2)
|
||||||
|
18
device.c
18
device.c
@ -295,10 +295,10 @@ bool cSatipDevice::ProvidesChannel(const cChannel *channelP, int priorityP, bool
|
|||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = true;
|
result = !!SatipConfig.GetFrontendReuse();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
needsDetachReceivers = Receiving();
|
needsDetachReceivers = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,7 +309,11 @@ 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
|
||||||
@ -390,7 +394,7 @@ void cSatipDevice::SetChannelTuned(void)
|
|||||||
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) {
|
if (pTunerM && handleP && handleP->pid >= 0 && handleP->pid <= 8191) {
|
||||||
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))
|
||||||
@ -444,6 +448,14 @@ 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 (startswith(r, "LOCATION:")) {
|
if (strcasestr(r, "LOCATION:") == r) {
|
||||||
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 (startswith(r, "ST:")) {
|
else if (strcasestr(r, "ST:") == r) {
|
||||||
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;
|
||||||
|
62
param.c
62
param.c
@ -59,6 +59,10 @@ 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" },
|
||||||
@ -85,6 +89,11 @@ 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" },
|
||||||
@ -165,33 +174,36 @@ 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)
|
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;
|
return &buffer[1];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
14
po/ca_ES.po
14
po/ca_ES.po
@ -1,14 +1,14 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2017 Rolf Ahrenberg
|
# Copyright (C) 2007-2019 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-2017
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 2.3.1\n"
|
"Project-Id-Version: vdr-satip 2.4.0\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2017-08-15 08:15+0300\n"
|
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
||||||
"PO-Revision-Date: 2017-08-15 08:15+0300\n"
|
"PO-Revision-Date: 2019-10-27 10:27+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"
|
||||||
@ -196,6 +196,12 @@ 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:"
|
||||||
|
|
||||||
|
22
po/de_DE.po
22
po/de_DE.po
@ -1,14 +1,14 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2017 Rolf Ahrenberg
|
# Copyright (C) 2007-2019 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-2017
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 2.3.1\n"
|
"Project-Id-Version: vdr-satip 2.4.0\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2017-08-15 08:15+0300\n"
|
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
||||||
"PO-Revision-Date: 2017-08-15 08:15+0300\n"
|
"PO-Revision-Date: 2019-10-27 10:27+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äte Status"
|
msgstr "SAT>IP Gerätestatus"
|
||||||
|
|
||||||
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 abgeschaltet\n"
|
"aus - Geräte sind deaktiviert\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öchste Priorität"
|
"hoch - Geräte arbeiten mit höchster 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."
|
"Diese Einstellung schaltet die automatische EIT Aktualisierung für alle SAT>IP Geräte aus."
|
||||||
|
|
||||||
msgid "Disabled sources"
|
msgid "Disabled sources"
|
||||||
msgstr "Deaktivierte Quellen"
|
msgstr "Deaktivierte Quellen"
|
||||||
@ -199,6 +199,12 @@ 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:"
|
||||||
|
|
||||||
|
14
po/es_ES.po
14
po/es_ES.po
@ -1,14 +1,14 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2017 Rolf Ahrenberg
|
# Copyright (C) 2007-2019 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-2017
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 2.3.1\n"
|
"Project-Id-Version: vdr-satip 2.4.0\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2017-08-15 08:15+0300\n"
|
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
||||||
"PO-Revision-Date: 2017-08-15 08:15+0300\n"
|
"PO-Revision-Date: 2019-10-27 10:27+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"
|
||||||
@ -196,6 +196,12 @@ 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-2017 Rolf Ahrenberg
|
# Copyright (C) 2007-2019 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-2017
|
# Rolf Ahrenberg, 2015-2019
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 2.3.1\n"
|
"Project-Id-Version: vdr-satip 2.4.0\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2017-08-15 08:15+0300\n"
|
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
||||||
"PO-Revision-Date: 2017-08-15 08:15+0300\n"
|
"PO-Revision-Date: 2019-10-27 10:27+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,6 +198,12 @@ 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:"
|
||||||
|
|
||||||
|
14
po/pl_PL.po
14
po/pl_PL.po
@ -1,14 +1,14 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2017 Rolf Ahrenberg
|
# Copyright (C) 2007-2019 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the vdr-satip package.
|
# This file is distributed under the same license as the vdr-satip package.
|
||||||
# Tomasz Maciej Nowak, 2017
|
# Tomasz Maciej Nowak, 2017
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 2.3.1\n"
|
"Project-Id-Version: vdr-satip 2.4.0\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2017-08-15 08:15+0300\n"
|
"POT-Creation-Date: 2019-10-27 19:12+0200\n"
|
||||||
"PO-Revision-Date: 2017-08-15 08:15+0300\n"
|
"PO-Revision-Date: 2019-10-27 10:27+0200\n"
|
||||||
"Last-Translator: Tomasz Maciej Nowak <tomek_n@o2.pl>\n"
|
"Last-Translator: Tomasz Maciej Nowak <tomek_n@o2.pl>\n"
|
||||||
"Language-Team: Polish <vdr@linuxtv.org>\n"
|
"Language-Team: Polish <vdr@linuxtv.org>\n"
|
||||||
"Language: pl_PL\n"
|
"Language: pl_PL\n"
|
||||||
@ -199,6 +199,12 @@ msgstr ""
|
|||||||
"Określa tryb transmisji.\n"
|
"Określa tryb transmisji.\n"
|
||||||
"Unicast, Multicast, RTP-over-TCP."
|
"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:"
|
msgid "Active SAT>IP servers:"
|
||||||
msgstr "Aktywne serwery SAT>IP:"
|
msgstr "Aktywne serwery SAT>IP:"
|
||||||
|
|
||||||
|
28
rtcp.c
28
rtcp.c
@ -34,7 +34,7 @@ int cSatipRtcp::GetFd(void)
|
|||||||
return Fd();
|
return Fd();
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipRtcp::GetApplicationOffset(int *lengthP)
|
int cSatipRtcp::GetApplicationOffset(unsigned char *bufferP, 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(int *lengthP)
|
|||||||
int total = *lengthP;
|
int total = *lengthP;
|
||||||
while (total > 0) {
|
while (total > 0) {
|
||||||
// Version
|
// Version
|
||||||
unsigned int v = (bufferM[offset] >> 6) & 0x03;
|
unsigned int v = (bufferP[offset] >> 6) & 0x03;
|
||||||
// Padding
|
// Padding
|
||||||
//unsigned int p = (bufferM[offset] >> 5) & 0x01;
|
//unsigned int p = (bufferP[offset] >> 5) & 0x01;
|
||||||
// Subtype
|
// Subtype
|
||||||
//unsigned int st = bufferM[offset] & 0x1F;
|
//unsigned int st = bufferP[offset] & 0x1F;
|
||||||
// Payload type
|
// Payload type
|
||||||
unsigned int pt = bufferM[offset + 1] & 0xFF;
|
unsigned int pt = bufferP[offset + 1] & 0xFF;
|
||||||
// Length
|
// Length
|
||||||
unsigned int length = ((bufferM[offset + 2] & 0xFF) << 8) | (bufferM[offset + 3] & 0xFF);
|
unsigned int length = ((bufferP[offset + 2] & 0xFF) << 8) | (bufferP[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 = ((bufferM[offset + 4] & 0xFF) << 24) | ((bufferM[offset + 5] & 0xFF) << 16) |
|
//unsigned int ssrc = ((bufferP[offset + 4] & 0xFF) << 24) | ((bufferP[offset + 5] & 0xFF) << 16) |
|
||||||
// ((bufferM[offset + 6] & 0xFF) << 8) | (bufferM[offset + 7] & 0xFF);
|
// ((bufferP[offset + 6] & 0xFF) << 8) | (bufferP[offset + 7] & 0xFF);
|
||||||
// Name
|
// Name
|
||||||
if ((bufferM[offset + 8] == 'S') && (bufferM[offset + 9] == 'E') &&
|
if ((bufferP[offset + 8] == 'S') && (bufferP[offset + 9] == 'E') &&
|
||||||
(bufferM[offset + 10] == 'S') && (bufferM[offset + 11] == '1')) {
|
(bufferP[offset + 10] == 'S') && (bufferP[offset + 11] == '1')) {
|
||||||
// Identifier
|
// Identifier
|
||||||
//unsigned int id = ((bufferM[offset + 12] & 0xFF) << 8) | (bufferM[offset + 13] & 0xFF);
|
//unsigned int id = ((bufferP[offset + 12] & 0xFF) << 8) | (bufferP[offset + 13] & 0xFF);
|
||||||
// String length
|
// String length
|
||||||
int string_length = ((bufferM[offset + 14] & 0xFF) << 8) | (bufferM[offset + 15] & 0xFF);
|
int string_length = ((bufferP[offset + 14] & 0xFF) << 8) | (bufferP[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(&length);
|
int offset = GetApplicationOffset(bufferM, &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(&lengthP);
|
int offset = GetApplicationOffset(dataP, &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(int *lengthP);
|
int GetApplicationOffset(unsigned char *bufferP, int *lengthP);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit cSatipRtcp(cSatipTunerIf &tunerP);
|
explicit cSatipRtcp(cSatipTunerIf &tunerP);
|
||||||
|
22
rtsp.c
22
rtsp.c
@ -206,6 +206,28 @@ bool cSatipRtsp::SetInterface(const char *bindAddrP)
|
|||||||
return result;
|
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());
|
||||||
|
1
rtsp.h
1
rtsp.h
@ -59,6 +59,7 @@ public:
|
|||||||
cString RtspUnescapeString(const char *strP);
|
cString RtspUnescapeString(const char *strP);
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
bool SetInterface(const char *bindAddrP);
|
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);
|
||||||
|
35
satip.c
35
satip.c
@ -20,15 +20,15 @@
|
|||||||
#warning "CURL version >= 7.36.0 is recommended"
|
#warning "CURL version >= 7.36.0 is recommended"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(APIVERSNUM) && APIVERSNUM < 20307
|
#if defined(APIVERSNUM) && APIVERSNUM < 20400
|
||||||
#error "VDR-2.3.7 API version or greater is required!"
|
#error "VDR-2.4.0 API version or greater is required!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GITVERSION
|
#ifndef GITVERSION
|
||||||
#define GITVERSION ""
|
#define GITVERSION ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char VERSION[] = "2.3.1" GITVERSION;
|
const char VERSION[] = "2.4.1" 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,8 +85,31 @@ 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=<ipaddr1>|<model1>|<desc1>;<ipaddr2>:<port>|<model2>:<filter>|<desc2>:<quirk>\n"
|
" -s <ipaddr>|<model>|<desc>, --server=[<srcaddress>@]<ipaddress>[:<port>]|<model>[:<filter>]|<description>[:<quirk>];...\n"
|
||||||
" define hard-coded SAT>IP server(s)\n"
|
" define hard-coded SAT>IP server(s)\n\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"
|
||||||
@ -392,6 +415,8 @@ 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)
|
||||||
|
@ -18,35 +18,14 @@ 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;
|
||||||
@ -89,23 +68,12 @@ void cSatipSectionFilter::New(void)
|
|||||||
int cSatipSectionFilter::Filter(void)
|
int cSatipSectionFilter::Filter(void)
|
||||||
{
|
{
|
||||||
if (secBufM) {
|
if (secBufM) {
|
||||||
int i;
|
if ((tidM & maskM) == (secBufM[0] & maskM)) {
|
||||||
uint8_t neq = 0;
|
if (ringBufferM && (secLenM > 0)) {
|
||||||
|
cFrame* section = new cFrame(secBufM, secLenM);
|
||||||
for (i = 0; i < eDmxMaxFilterSize; ++i) {
|
if (!ringBufferM->Put(section))
|
||||||
uint8_t calcxor = (uint8_t)(filterValueM[i] ^ secBufM[i]);
|
DELETE_POINTER(section);
|
||||||
if (maskAndModeM[i] & calcxor)
|
}
|
||||||
return 0;
|
|
||||||
neq |= (maskAndNotModeM[i] & calcxor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doneqM && !neq)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (ringBufferM && (secLenM > 0)) {
|
|
||||||
cFrame* section = new cFrame(secBufM, secLenM);
|
|
||||||
if (!ringBufferM->Put(section))
|
|
||||||
DELETE_POINTER(section);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -33,18 +33,13 @@ 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);
|
||||||
|
63
server.c
63
server.c
@ -40,29 +40,43 @@ 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 unused one
|
// Prefer any used one
|
||||||
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
for (cSatipFrontend *f = First(); f; f = Next(f)) {
|
||||||
if (!f->Attached() || (f->DeviceId() == deviceIdP)) {
|
if (f->DeviceId() == deviceIdP) { // give deviceID priority, but take detached frontend if deviceID ist not yet attached
|
||||||
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) {
|
||||||
f->Attach(deviceIdP);
|
tmp = f;
|
||||||
debug9("%s (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
if (f->DeviceId() == deviceIdP) {
|
||||||
return true;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +85,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 (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
debug9("%s detached deviceID %d (TP %d) from %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,6 +133,7 @@ cSatipServer::cSatipServer(const char *srcAddressP, const char *addressP, const
|
|||||||
// 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;
|
||||||
@ -128,34 +143,38 @@ cSatipServer::cSatipServer(const char *srcAddressP, const char *addressP, const
|
|||||||
)
|
)
|
||||||
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!Box 6490 Cable") || // FRITZ!Box 6490 Cable
|
if (strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C
|
||||||
strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C
|
|
||||||
strstr(*descriptionM, "fritzdvbc") // FRITZ!WLAN Repeater DVB-C (old firmware)
|
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!Box 6490 Cable") || // FRITZ!Box 6490 Cable
|
if (strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C
|
||||||
strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C
|
|
||||||
strstr(*descriptionM, "fritzdvbc") || // FRITZ!WLAN Repeater DVB-C (old firmware)
|
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
|
||||||
strstr(*descriptionM, "KATHREIN SatIP Server") // 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) ? "" : ",");
|
||||||
@ -208,6 +227,11 @@ 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);
|
||||||
@ -260,6 +284,8 @@ 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;
|
||||||
}
|
}
|
||||||
@ -273,6 +299,8 @@ 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;
|
||||||
}
|
}
|
||||||
@ -295,6 +323,8 @@ 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;
|
||||||
}
|
}
|
||||||
@ -340,6 +370,11 @@ 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)
|
||||||
@ -521,6 +556,8 @@ 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;
|
||||||
}
|
}
|
||||||
|
21
server.h
21
server.h
@ -52,6 +52,7 @@ private:
|
|||||||
eSatipFrontendDVBT2,
|
eSatipFrontendDVBT2,
|
||||||
eSatipFrontendDVBC,
|
eSatipFrontendDVBC,
|
||||||
eSatipFrontendDVBC2,
|
eSatipFrontendDVBC2,
|
||||||
|
eSatipFrontendATSC,
|
||||||
eSatipFrontendCount
|
eSatipFrontendCount
|
||||||
};
|
};
|
||||||
enum {
|
enum {
|
||||||
@ -75,15 +76,16 @@ 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,
|
||||||
eSatipQuirkMask = 0xFF
|
eSatipQuirkTearAndPlay = 0x80,
|
||||||
|
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 *srcAddressP, const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP);
|
||||||
virtual ~cSatipServer();
|
virtual ~cSatipServer();
|
||||||
@ -98,6 +100,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 *SrcAddress(void) { return *srcAddressM; }
|
||||||
const char *Address(void) { return *addressM; }
|
const char *Address(void) { return *addressM; }
|
||||||
|
9
setup.c
9
setup.c
@ -347,6 +347,7 @@ 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())
|
||||||
@ -418,6 +419,10 @@ 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("");
|
||||||
|
|
||||||
@ -479,6 +484,7 @@ 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);
|
||||||
@ -504,7 +510,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) || (detachedModeM != SatipConfig.GetDetachedMode()))) {
|
if ((keyP != kNone) && ((numDisabledSourcesM != oldNumDisabledSources) || (numDisabledFiltersM != oldNumDisabledFilters) || (operatingModeM != oldOperatingMode) || (ciExtensionM != oldCiExtension) || ( oldFrontendReuse != frontendReuseM) || (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))
|
||||||
@ -569,6 +575,7 @@ 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,6 +22,7 @@ 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;
|
||||||
|
86
tuner.c
86
tuner.c
@ -25,6 +25,8 @@ 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),
|
||||||
@ -34,11 +36,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),
|
timeoutM(eMinKeepAliveIntervalMs - eKeepAlivePreBufferMs),
|
||||||
hasLockM(false),
|
hasLockM(false),
|
||||||
signalStrengthDBmM(0.0),
|
signalStrengthDBmM(0.0),
|
||||||
signalStrengthM(-1),
|
signalStrengthM(-1),
|
||||||
@ -117,6 +120,8 @@ 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);
|
||||||
@ -175,6 +180,7 @@ 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);
|
||||||
@ -191,8 +197,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -202,7 +206,8 @@ bool cSatipTuner::Close(void)
|
|||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
|
|
||||||
RequestState(tsRelease, smExternal);
|
if (setupTimeoutM.TimedOut())
|
||||||
|
RequestState(tsRelease, smExternal);
|
||||||
|
|
||||||
// return always true
|
// return always true
|
||||||
return true;
|
return true;
|
||||||
@ -218,10 +223,15 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,11 +244,13 @@ bool cSatipTuner::Connect(void)
|
|||||||
if (useTcp)
|
if (useTcp)
|
||||||
debug1("%s Requesting TCP [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
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;
|
||||||
}
|
}
|
||||||
@ -256,8 +268,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(*streamAddrM) && (streamIdM >= 0)) {
|
if (!isempty(*lastAddrM) && (streamIdM >= 0)) {
|
||||||
cString uri = cString::sprintf("%sstream=%d", *GetBaseUrl(*streamAddrM, streamPortM), streamIdM);
|
cString uri = cString::sprintf("%sstream=%d", *lastAddrM, 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();
|
||||||
@ -273,7 +285,7 @@ bool cSatipTuner::Disconnect(void)
|
|||||||
|
|
||||||
currentServerM.Detach();
|
currentServerM.Detach();
|
||||||
statusUpdateM.Set(0);
|
statusUpdateM.Set(0);
|
||||||
timeoutM = eMinKeepAliveIntervalMs;
|
timeoutM = eMinKeepAliveIntervalMs - eKeepAlivePreBufferMs;
|
||||||
pmtPidM = -1;
|
pmtPidM = -1;
|
||||||
addPidsM.Clear();
|
addPidsM.Clear();
|
||||||
delPidsM.Clear();
|
delPidsM.Clear();
|
||||||
@ -382,6 +394,7 @@ 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)
|
||||||
@ -446,7 +459,13 @@ 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 {
|
||||||
@ -486,17 +505,24 @@ 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?pids=%s", *uri, *pidsM.ListPids());
|
uri = cString::sprintf("%s%spids=%s", *uri, paramadded ? "&" : "?", *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?addpids=%s", *uri, *addPidsM.ListPids());
|
uri = cString::sprintf("%s%saddpids=%s", *uri, paramadded ? "&" : "?", *addPidsM.ListPids());
|
||||||
if (delPidsM.Size())
|
paramadded = true;
|
||||||
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)) {
|
||||||
@ -509,9 +535,10 @@ 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&x_pmt=%d", *uri, pid);
|
uri = cString::sprintf("%s%sx_pmt=%d", *uri, paramadded ? "&" : "?", 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;
|
||||||
}
|
}
|
||||||
@ -519,14 +546,18 @@ 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&tnr=%s", *uri, *param);
|
uri = cString::sprintf("%s%stnr=%s", *uri, paramadded ? "&" : "?", *param);
|
||||||
|
paramadded = true;
|
||||||
|
}
|
||||||
tnrParamM = param;
|
tnrParamM = param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
|
if (paramadded) {
|
||||||
if (!rtspM.Play(*uri))
|
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
|
||||||
return false;
|
if (!rtspM.Play(*uri))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
addPidsM.Clear();
|
addPidsM.Clear();
|
||||||
delPidsM.Clear();
|
delPidsM.Clear();
|
||||||
}
|
}
|
||||||
@ -534,6 +565,19 @@ 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);
|
||||||
|
8
tuner.h
8
tuner.h
@ -88,7 +88,9 @@ private:
|
|||||||
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 };
|
||||||
@ -101,6 +103,8 @@ 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;
|
||||||
@ -110,6 +114,7 @@ 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;
|
||||||
@ -128,6 +133,7 @@ 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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user