mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 11:37:42 +00:00
Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
fb40846171 | ||
|
b19be5b5c5 | ||
|
1a304e9dc2 | ||
|
5ff54d27a3 | ||
|
276370afbb | ||
|
f2081c4f00 | ||
|
388543a58d | ||
|
f46d07a95f | ||
|
43cc15357e | ||
|
5b1af5ba29 | ||
|
80fc28d8cf | ||
|
5e8b7b7c5e | ||
|
88b2ad9244 | ||
|
7b58d9f28f | ||
|
f493df0e3d | ||
|
9a6ae40954 | ||
|
b5ec84fd91 | ||
|
e7a74f3ad4 | ||
|
40d280af10 | ||
|
9f2d99435d | ||
|
06dd2f7261 | ||
|
dfbb3515ef | ||
|
497b1893db | ||
|
8c05ce31f9 |
40
HISTORY
40
HISTORY
@@ -6,3 +6,43 @@ VDR Plugin 'satip' Revision History
|
||||
|
||||
- Initial revision.
|
||||
- Added German translation (Thanks to Frank Neumann).
|
||||
|
||||
2014-03-15: Version 0.1.0
|
||||
|
||||
- Switched to the standard S/T/C source identifiers.
|
||||
- Added a new operation mode setup parameter.
|
||||
- Added new SVDRP commands.
|
||||
|
||||
2014-03-16: Version 0.1.1
|
||||
|
||||
- Changed code to utilize a proper XML library.
|
||||
- Refactored the session code.
|
||||
- Fixed EIT scan functionality.
|
||||
- Updated for vdr-2.1.6.
|
||||
|
||||
2014-03-28: Version 0.2.0
|
||||
|
||||
- Added support for cDevice::Ready().
|
||||
- Fixed pid leaking while disabling section filters.
|
||||
- Fixed keepalive heartbeat.
|
||||
|
||||
2014-04-01: Version 0.2.1
|
||||
|
||||
- Changed implementation to report about RTP packet
|
||||
errors on 5 minutes interval only.
|
||||
- Added a check to write new sections only if there
|
||||
is no data in the read socket.
|
||||
- Fixed keepalive heartbeat again.
|
||||
|
||||
2014-04-05: Version 0.2.2
|
||||
|
||||
- Fixed the default keepalive interval.
|
||||
- Refactored the section filtering.
|
||||
- Added Catalan translation (Thanks to Gabriel Bonich).
|
||||
|
||||
2014-04-12: Version 0.2.3
|
||||
|
||||
- Added Spanish translation (Thanks to Gabriel Bonich).
|
||||
- Fixed parameters of the OPTIONS command.
|
||||
- Added a device identication into the user agent string.
|
||||
- Removed unnecessary PLAY commands and header callbacks.
|
||||
|
15
Makefile
15
Makefile
@@ -6,6 +6,10 @@
|
||||
|
||||
#SATIP_DEBUG = 1
|
||||
|
||||
# Use TinyXML instead of PugiXML
|
||||
|
||||
#SATIP_USE_TINYXML = 1
|
||||
|
||||
# Strip debug symbols? Set eg. to /bin/true if not
|
||||
|
||||
STRIP = strip
|
||||
@@ -64,6 +68,13 @@ INCLUDES +=
|
||||
|
||||
DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
|
||||
|
||||
ifdef SATIP_USE_TINYXML
|
||||
DEFINES += -DUSE_TINYXML
|
||||
LIBS += -ltinyxml
|
||||
else
|
||||
LIBS += -lpugixml
|
||||
endif
|
||||
|
||||
ifdef SATIP_DEBUG
|
||||
DEFINES += -DDEBUG
|
||||
endif
|
||||
@@ -77,8 +88,8 @@ all-redirect: all
|
||||
|
||||
### The object files (add further files here):
|
||||
|
||||
OBJS = $(PLUGIN).o common.o config.o device.o discover.o \
|
||||
sectionfilter.o setup.o socket.o source.o statistics.o tuner.o
|
||||
OBJS = $(PLUGIN).o common.o config.o device.o discover.o param.o \
|
||||
sectionfilter.o server.o setup.o socket.o statistics.o tuner.o
|
||||
|
||||
### The main target:
|
||||
|
||||
|
151
README
151
README
@@ -14,10 +14,16 @@ See the file COPYING for more information.
|
||||
|
||||
Requirements:
|
||||
|
||||
- Libcurl - the multiprotocol file transfer library with RTSP support
|
||||
- Libcurl >= 7.36.0 - the multiprotocol file transfer library with RTSP support
|
||||
http://curl.haxx.se/libcurl/
|
||||
|
||||
- VDR-2.1.4+ for scrambled channels
|
||||
- PugiXML - Light-weight, simple and fast XML parser for C++
|
||||
http://pugixml.org/
|
||||
or
|
||||
TinyXML - a simple, small, C++ XML parser
|
||||
http://www.grinninglizard.com/tinyxml/
|
||||
|
||||
- VDR >= 2.1.4 for scrambled channels
|
||||
|
||||
Description:
|
||||
|
||||
@@ -32,9 +38,37 @@ Installation:
|
||||
tar -xzf /put/your/path/here/vdr-satip-X.Y.Z.tgz
|
||||
make -C satip-X.Y.Z install
|
||||
|
||||
Configuration:
|
||||
|
||||
The plugin accepts a "--devices" (-d) command-line parameter defaulting
|
||||
to one. This parameter defines how many simultaneous transponders can
|
||||
be received, if there are available SAT>IP tuners.
|
||||
|
||||
SAT>IP satellite positions (aka. signal sources) shall be defined via
|
||||
sources.conf. If the source description begins with a number, it's used
|
||||
as SAT>IP signal source selection parameter. Otherwise, the default
|
||||
parameter is one:
|
||||
|
||||
S19.2E Astra 1KR/1L/1M/2C
|
||||
=> Signal source = 1
|
||||
|
||||
S19.2E 2
|
||||
=> Signal source = 2
|
||||
|
||||
S19.2E 3 Astra 1KR/1L/1M/2C
|
||||
=> Signal source = 3
|
||||
|
||||
Setup menu:
|
||||
|
||||
- Enable EPG scanning = yes 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
|
||||
normal option to "off". Otherwise, if you want
|
||||
high to keep SAT>IP at a low priority when
|
||||
selecting available devices, set this
|
||||
option to "low". Similarly, the "high"
|
||||
value prefers the SAT>IP over the local
|
||||
DVB cards when selecting available devices.
|
||||
- Enable EPG scanning = yes If you want exclude all SAT>IP devices
|
||||
from VDR's EIT background scanning, set
|
||||
this option to "no".
|
||||
- Disabled filters = none Certain section filters might cause some
|
||||
@@ -46,6 +80,7 @@ Setup menu:
|
||||
"Disable filter" options which allow you
|
||||
to disable the individual section filters.
|
||||
Valid range: "none" = 0 ... 7
|
||||
- [Red:Scan] Forces network scanning of SAT>IP hardware.
|
||||
- [Blue:Info] Opens SAT>IP information/statistics menu.
|
||||
- [Ok] Opens information menu of selected SAT>IP
|
||||
device.
|
||||
@@ -57,118 +92,22 @@ Information menu:
|
||||
- [Yellow:Filters] Opens the section filter statistics page.
|
||||
- [Blue:Bits/bytes] Toggles between bits and bytes mode.
|
||||
|
||||
SAT>IP device menu:
|
||||
|
||||
- [Red:Scan] Starts the channel scanning sometime in
|
||||
the future.
|
||||
|
||||
Configuration:
|
||||
|
||||
- Parameters
|
||||
|
||||
Various parameters, depending on whether this is a DVB-S, DVB-S2, DVB-T,
|
||||
or DVB-T2 channel. Each parameter consist of a key character, followed by
|
||||
an integer number that represents the actual setting of that parameter.
|
||||
The valid key characters, their meaning, and allowed values are:
|
||||
|
||||
B Bandwidth (1712, 5, 6, 7, 8, 10)
|
||||
C Code rate high priority (12, 23, 34, 35, 45, 56, 67, 78, 89, 910)
|
||||
G Guard interval (4, 8, 16, 32, 128, 19128, 19256)
|
||||
H Horizontal polarization
|
||||
L Left circular polarization
|
||||
M Modulation (2, 5, 16, 64, 256)
|
||||
N pilot toNes (0, 1)
|
||||
O rollOff (20, 25, 35)
|
||||
P stream id (0-255)
|
||||
Q t2 system id (0-65535)
|
||||
R Right circular polarization
|
||||
S delivery System (0, 1)
|
||||
T Transmission mode (1, 2, 4, 8, 16, 32)
|
||||
V Vertical polarization
|
||||
X siso/miso mode (0, 1)
|
||||
Z signal source position (1-255)
|
||||
|
||||
Bandwidth: The bandwidth of the channel in MHz (1712 in kHz)
|
||||
(DVB-T/DVB-T2)
|
||||
|
||||
Code rate high priority: Forward Error Correction (FEC) of the high
|
||||
priority stream (DVB-T/DVB-T2) or the the inner FEC scheme (DVB-S/DVB-S2)
|
||||
12 = 1/2, 23 = 2/3, 34 = 3/4, 35 = 3/5, 45 = 4/5, 56 = 5/6,
|
||||
67 = 6/7, 78 = 7/8, 89 = 8/9, 910 = 9/10
|
||||
(DVB-T/DVB-T2/DVB-S/DVB-S2)
|
||||
|
||||
Guard interval: The guard interval value
|
||||
4 = 1/4, 8 = 1/8, 16 = 1/16, 32 = 1/32, 128 = 1/128,
|
||||
19128 = 19/128, 19256 = 19/256
|
||||
(DVB-T/DVB-T2)
|
||||
|
||||
Modulation: Specifies the modulation/constellation of the channel
|
||||
2 = QPSK (DVB-S, DVB-S2, DVB-T, DVB-T2)
|
||||
5 = 8PSK (DVB-S, DVB-S2)
|
||||
16 = QAM16 (DVB-T, DVB-T2)
|
||||
64 = QAM64 (DVB-T, DVB-T2)
|
||||
256 = QAM256 (DVB-T2)
|
||||
|
||||
Pilot tones: Specifies pilot tones usage
|
||||
0 = off, 1 = on
|
||||
(DVB-S2)
|
||||
|
||||
Rolloff: The Nyquist filter rolloff factor
|
||||
35 = 0.35, 25 = 0.25, 20 = 0.20
|
||||
(DVB-S/DVB-S2)
|
||||
|
||||
Stream id: Physical Layer Pipe (PLP) id (0-255) for DVB-T2 multiplex
|
||||
(DVB-T2)
|
||||
|
||||
T2 system id: Unique identifier (0-65535) of the T2 system
|
||||
(DVB-T2)
|
||||
|
||||
Transmission mode: Number of DVB-T OFDM carriers
|
||||
32 = 32k, 16 = 16k, 8 = 8k, 4 = 4k, 2 = 2k, 1 = 1k
|
||||
(DVB-T/DVB-T2)
|
||||
|
||||
Delivery System: The delivery system
|
||||
0 = "first generation" (DVB-S/DVB-T)
|
||||
1 = "second generation" (DVB-S2/DVB-T2)
|
||||
|
||||
Polarization: Satellite antenna polarization
|
||||
H = horizontal, V = vertical
|
||||
R = circular right, L = circular left
|
||||
(DVB-S/DVB-S2)
|
||||
|
||||
Signal source: Specifies the signal source (satellite) position
|
||||
(DVB-S/DVB-S2)
|
||||
|
||||
SISO/MISO: Specifies the Single-Input/Multiple-Input Single-Output mode
|
||||
0 = SISO, 1 = MISO
|
||||
(DVB-T2)
|
||||
|
||||
- Source
|
||||
|
||||
There are two separate signal sources for SAT>IP channels:
|
||||
Z = SAT>IP Satellite (DVB-S/DVB-S2)
|
||||
Y = SAT>IP Terrestrial (DVB-T/DVB-T2)
|
||||
|
||||
- Examples
|
||||
|
||||
MTV3;DVB-T:658000000:B8C23D23G8M64S0T8Y0:T:0:305=2:561=fin@4,562=dut@4:5010;1073=fin,1074=dut:0:49:8438:8193:0
|
||||
=>
|
||||
MTV3;SAT>IP:658000000:B8C23G8M64S0T8:Y:0:305=2:561=fin@4,562=dut@4:5010;1073=fin,1074=dut:0:49:8438:8193:0
|
||||
|
||||
Das Erste HD;DVB-S2:11494:HC23M5O35S1:S19.2E:22000:5101=27:5102=deu@3,5103=mis@3;5106=deu@106:5104;5105=deu:0:10301:1:1019:0
|
||||
=>
|
||||
Das Erste HD;SAT>IP:11494:HC23M5O35S1:Z:22000:5101=27:5102=deu@3,5103=mis@3;5106=deu@106:5104;5105=deu:0:10301:1:1019:0
|
||||
|
||||
Notes:
|
||||
|
||||
- The stream id "-1" states about unsuccessful tuning. This might be a
|
||||
result of invalid channel parameters or lack of free SAT>IP tuners.
|
||||
|
||||
- SAT>IP specification 1.2 doesn't support DVB-C/DVB-C2 receivers yet.
|
||||
- SAT>IP specification 1.2 doesn't support DVB-C/DVB-C2 receivers yet,
|
||||
but DVB-C (KABEL>IP) is supported for Digital Devices Octopus Net
|
||||
devices.
|
||||
|
||||
- If the plugin doesn't detect your SAT>IP network device, make sure
|
||||
your setup doesn't have firewalled the UDP port 1900.
|
||||
|
||||
- Stream decryption requires a separate CAM plugin that works without
|
||||
direct access to any DVB card devices. The integrated CAM slot in
|
||||
Octopus Net devices isn't supported.
|
||||
|
||||
Acknowledgements:
|
||||
|
||||
- Big thanks to Digital Devices GmbH for providing the Octopus Net
|
||||
|
14
common.c
14
common.c
@@ -70,12 +70,10 @@ cString ChangeCase(const cString &strP, bool upperP)
|
||||
|
||||
const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE] =
|
||||
{
|
||||
/* description tag pid tid mask */
|
||||
{trNOOP("PAT (0x00)"), "PAT", 0x00, 0x00, 0xFF},
|
||||
{trNOOP("NIT (0x40)"), "NIT", 0x10, 0x40, 0xFF},
|
||||
{trNOOP("SDT (0x42)"), "SDT", 0x11, 0x42, 0xFF},
|
||||
{trNOOP("EIT (0x4E/0x4F)"), "EIT", 0x12, 0x4E, 0xFE},
|
||||
{trNOOP("EIT (0x5X)"), "EIT", 0x12, 0x50, 0xF0},
|
||||
{trNOOP("EIT (0x6X)"), "EIT", 0x12, 0x60, 0xF0},
|
||||
{trNOOP("TDT (0x70)"), "TDT", 0x14, 0x70, 0xFF},
|
||||
/* description tag pid tid mask */
|
||||
{trNOOP("PAT (0x00)"), "PAT", 0x00, 0x00, 0xFF},
|
||||
{trNOOP("NIT (0x40)"), "NIT", 0x10, 0x40, 0xFF},
|
||||
{trNOOP("SDT (0x42)"), "SDT", 0x11, 0x42, 0xFF},
|
||||
{trNOOP("EIT (0x4E/0x4F/0x5X/0x6X)"), "EIT", 0x12, 0x40, 0xC0},
|
||||
{trNOOP("TDT (0x70)"), "TDT", 0x14, 0x70, 0xFF},
|
||||
};
|
||||
|
11
common.h
11
common.h
@@ -36,7 +36,7 @@
|
||||
#define SATIP_STATS_ACTIVE_PIDS_COUNT 10
|
||||
#define SATIP_STATS_ACTIVE_FILTERS_COUNT 10
|
||||
|
||||
#define SECTION_FILTER_TABLE_SIZE 7
|
||||
#define SECTION_FILTER_TABLE_SIZE 5
|
||||
|
||||
#define SATIP_CURL_EASY_GETINFO(X, Y, Z) \
|
||||
if ((res = curl_easy_getinfo((X), (Y), (Z))) != CURLE_OK) { \
|
||||
@@ -78,6 +78,15 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FREE_POINTER(ptr) \
|
||||
do { \
|
||||
if (ptr) { \
|
||||
typeof(*ptr) *tmp = ptr; \
|
||||
ptr = NULL; \
|
||||
free(tmp); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
uint16_t ts_pid(const uint8_t *bufP);
|
||||
|
3
config.c
3
config.c
@@ -11,7 +11,8 @@
|
||||
cSatipConfig SatipConfig;
|
||||
|
||||
cSatipConfig::cSatipConfig(void)
|
||||
: eitScanM(1),
|
||||
: operatingModeM(eOperatingModeLow),
|
||||
eitScanM(1),
|
||||
useBytesM(1)
|
||||
{
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(disabledFiltersM); ++i)
|
||||
|
15
config.h
15
config.h
@@ -14,19 +14,34 @@
|
||||
class cSatipConfig
|
||||
{
|
||||
private:
|
||||
unsigned int operatingModeM;
|
||||
unsigned int eitScanM;
|
||||
unsigned int useBytesM;
|
||||
int disabledFiltersM[SECTION_FILTER_TABLE_SIZE];
|
||||
char configDirectoryM[PATH_MAX];
|
||||
|
||||
public:
|
||||
enum {
|
||||
eOperatingModeOff = 0,
|
||||
eOperatingModeLow,
|
||||
eOperatingModeNormal,
|
||||
eOperatingModeHigh,
|
||||
eOperatingModeCount
|
||||
};
|
||||
cSatipConfig();
|
||||
unsigned int GetOperatingMode(void) const { return operatingModeM; }
|
||||
bool IsOperatingModeOff(void) const { return (operatingModeM == eOperatingModeOff); }
|
||||
bool IsOperatingModeLow(void) const { return (operatingModeM == eOperatingModeLow); }
|
||||
bool IsOperatingModeNormal(void) const { return (operatingModeM == eOperatingModeNormal); }
|
||||
bool IsOperatingModeHigh(void) const { return (operatingModeM == eOperatingModeHigh); }
|
||||
void ToggleOperatingMode(void) { operatingModeM = (operatingModeM + 1) % eOperatingModeCount; }
|
||||
unsigned int GetEITScan(void) const { return eitScanM; }
|
||||
unsigned int GetUseBytes(void) const { return useBytesM; }
|
||||
const char *GetConfigDirectory(void) const { return configDirectoryM; }
|
||||
unsigned int GetDisabledFiltersCount(void) const;
|
||||
int GetDisabledFilters(unsigned int indexP) const;
|
||||
|
||||
void SetOperatingMode(unsigned int operatingModeP) { operatingModeM = operatingModeP; }
|
||||
void SetEITScan(unsigned int onOffP) { eitScanM = onOffP; }
|
||||
void SetUseBytes(unsigned int onOffP) { useBytesM = onOffP; }
|
||||
void SetConfigDirectory(const char *directoryP);
|
||||
|
90
device.c
90
device.c
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "discover.h"
|
||||
#include "source.h"
|
||||
#include "param.h"
|
||||
#include "device.h"
|
||||
|
||||
#define SATIP_MAX_DEVICES MAXDEVICES
|
||||
@@ -19,7 +19,9 @@ cSatipDevice::cSatipDevice(unsigned int indexP)
|
||||
isPacketDeliveredM(false),
|
||||
isOpenDvrM(false),
|
||||
deviceNameM(*cString::sprintf("%s %d", *DeviceType(), deviceIndexM)),
|
||||
channelM()
|
||||
channelM(),
|
||||
createdM(0),
|
||||
mutexM()
|
||||
{
|
||||
unsigned int bufsize = (unsigned int)SATIP_BUFFER_SIZE;
|
||||
bufsize -= (bufsize % TS_SIZE);
|
||||
@@ -49,8 +51,6 @@ cSatipDevice::~cSatipDevice()
|
||||
bool cSatipDevice::Initialize(unsigned int deviceCountP)
|
||||
{
|
||||
debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceCountP);
|
||||
new cSatipSourceParam('Y', "DVB-T (SAT>IP)");
|
||||
new cSatipSourceParam('Z', "DVB-S (SAT>IP)");
|
||||
if (deviceCountP > SATIP_MAX_DEVICES)
|
||||
deviceCountP = SATIP_MAX_DEVICES;
|
||||
for (unsigned int i = 0; i < deviceCountP; ++i)
|
||||
@@ -146,6 +146,12 @@ cString cSatipDevice::GetInformation(unsigned int pageP)
|
||||
return s;
|
||||
}
|
||||
|
||||
bool cSatipDevice::Ready(void)
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
return ((cSatipDiscover::GetInstance()->GetServerCount() > 0) || (createdM.Elapsed() > eReadyTimeoutMs));
|
||||
}
|
||||
|
||||
cString cSatipDevice::DeviceType(void) const
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
@@ -158,6 +164,12 @@ cString cSatipDevice::DeviceName(void) const
|
||||
return deviceNameM;
|
||||
}
|
||||
|
||||
bool cSatipDevice::AvoidRecording(void) const
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
return SatipConfig.IsOperatingModeLow();
|
||||
}
|
||||
|
||||
int cSatipDevice::SignalStrength(void) const
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
@@ -172,13 +184,8 @@ int cSatipDevice::SignalQuality(void) const
|
||||
|
||||
bool cSatipDevice::ProvidesSource(int sourceP) const
|
||||
{
|
||||
debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
int model = 0;
|
||||
if (cSource::IsType(sourceP, 'Z'))
|
||||
model |= cSatipServer::eSatipModelTypeDVBS2;
|
||||
if (cSource::IsType(sourceP, 'Y'))
|
||||
model |= cSatipServer::eSatipModelTypeDVBT2 | cSatipServer::eSatipModelTypeDVBT;
|
||||
return !!cSatipDiscover::GetInstance()->GetServer(model);
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
return (!SatipConfig.IsOperatingModeOff() && !!cSatipDiscover::GetInstance()->GetServer(sourceP));
|
||||
}
|
||||
|
||||
bool cSatipDevice::ProvidesTransponder(const cChannel *channelP) const
|
||||
@@ -225,12 +232,23 @@ bool cSatipDevice::ProvidesChannel(const cChannel *channelP, int priorityP, bool
|
||||
|
||||
bool cSatipDevice::ProvidesEIT(void) const
|
||||
{
|
||||
return (SatipConfig.GetEITScan() && pTunerM && pTunerM->IsTuned());
|
||||
return (SatipConfig.GetEITScan());
|
||||
}
|
||||
|
||||
int cSatipDevice::NumProvidedSystems(void) const
|
||||
{
|
||||
return cSatipDiscover::GetInstance()->NumProvidedSystems();
|
||||
int count = cSatipDiscover::GetInstance()->NumProvidedSystems();
|
||||
// Tweak the count according to operation mode
|
||||
if (SatipConfig.IsOperatingModeLow())
|
||||
count = 15;
|
||||
else if (SatipConfig.IsOperatingModeHigh())
|
||||
count = 1;
|
||||
// Clamp the count between 1 and 15
|
||||
if (count > 15)
|
||||
count = 15;
|
||||
else if (count < 1)
|
||||
count = 1;
|
||||
return count;
|
||||
}
|
||||
|
||||
const cChannel *cSatipDevice::GetCurrentlyTunedTransponder(void) const
|
||||
@@ -255,33 +273,20 @@ bool cSatipDevice::MaySwitchTransponder(const cChannel *channelP) const
|
||||
bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
|
||||
{
|
||||
if (channelP) {
|
||||
cSatipTransponderParameters stp(channelP->Parameters());
|
||||
cString params = stp.UrlParameters(cSource::ToChar(channelP->Source()));
|
||||
cString address;
|
||||
int mode = 0;
|
||||
if (cSource::IsType(channelP->Source(), 'Z'))
|
||||
mode |= cSatipServer::eSatipModelTypeDVBS2;
|
||||
if (cSource::IsType(channelP->Source(), 'Y'))
|
||||
mode |= stp.System() ? cSatipServer::eSatipModelTypeDVBT2 : cSatipServer::eSatipModelTypeDVBT;
|
||||
cSatipServer *server = cSatipDiscover::GetInstance()->GetServer(mode);
|
||||
if (!server) {
|
||||
debug("cSatipDevice::%s(%u): no suitable server found", __FUNCTION__, deviceIndexM);
|
||||
return false;
|
||||
}
|
||||
address = server->Address();
|
||||
float freq = channelP->Frequency();
|
||||
cDvbTransponderParameters dtp(channelP->Parameters());
|
||||
cString params = GetTransponderUrlParameters(channelP);
|
||||
if (isempty(params)) {
|
||||
error("Unrecognized SAT>IP channel parameters: %s", channelP->Parameters());
|
||||
return false;
|
||||
}
|
||||
// Scale down frequencies to MHz
|
||||
while (freq > 20000L)
|
||||
freq /= 1000L;
|
||||
params = cString::sprintf("freq=%s%s", *dtoa(freq, "%.3f"), *params);
|
||||
if (cSource::IsType(channelP->Source(), 'Z'))
|
||||
params = cString::sprintf("%s&sr=%d", *params, channelP->Srate());
|
||||
if (pTunerM && pTunerM->SetSource(*address, *params, deviceIndexM)) {
|
||||
deviceNameM = cString::sprintf("%s %d %s:%s:%s", *DeviceType(), deviceIndexM, server->Address(), server->Model(), server->Description());
|
||||
cString address;
|
||||
cSatipServer *server = cSatipDiscover::GetInstance()->GetServer(channelP->Source(), dtp.System());
|
||||
if (!server) {
|
||||
debug("cSatipDevice::%s(%u): no suitable server found", __FUNCTION__, deviceIndexM);
|
||||
return false;
|
||||
}
|
||||
if (pTunerM && pTunerM->SetSource(server, *params, deviceIndexM)) {
|
||||
deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server));
|
||||
channelM = *channelP;
|
||||
return true;
|
||||
}
|
||||
@@ -303,11 +308,12 @@ bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP)
|
||||
|
||||
int cSatipDevice::OpenFilter(u_short pidP, u_char tidP, u_char maskP)
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u): pid=%d tid=%d mask=%d", __FUNCTION__, deviceIndexM, pidP, tidP, maskP);
|
||||
//debug("cSatipDevice::%s(%u): pid=%d tid=%d mask=%d", __FUNCTION__, deviceIndexM, pidP, tidP, maskP);
|
||||
if (pSectionFilterHandlerM) {
|
||||
if (pTunerM)
|
||||
int handle = pSectionFilterHandlerM->Open(pidP, tidP, maskP);
|
||||
if (pTunerM && (handle >= 0))
|
||||
pTunerM->SetPid(pidP, ptOther, true);
|
||||
return pSectionFilterHandlerM->Open(pidP, tidP, maskP);
|
||||
return handle;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -375,6 +381,12 @@ unsigned int cSatipDevice::CheckData(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cSatipDevice::GetId(void)
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
return deviceIndexM;
|
||||
}
|
||||
|
||||
uchar *cSatipDevice::GetData(int *availableP)
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
|
7
device.h
7
device.h
@@ -26,6 +26,9 @@ public:
|
||||
|
||||
// private parts
|
||||
private:
|
||||
enum {
|
||||
eReadyTimeoutMs = 2000 // in milliseconds
|
||||
};
|
||||
unsigned int deviceIndexM;
|
||||
bool isPacketDeliveredM;
|
||||
bool isOpenDvrM;
|
||||
@@ -34,6 +37,7 @@ private:
|
||||
cRingBufferLinear *tsBufferM;
|
||||
cSatipTuner *pTunerM;
|
||||
cSatipSectionFilterHandler *pSectionFilterHandlerM;
|
||||
cTimeMs createdM;
|
||||
cMutex mutexM;
|
||||
|
||||
// constructor & destructor
|
||||
@@ -54,8 +58,10 @@ private:
|
||||
|
||||
// for channel info
|
||||
public:
|
||||
virtual bool Ready(void);
|
||||
virtual cString DeviceType(void) const;
|
||||
virtual cString DeviceName(void) const;
|
||||
virtual bool AvoidRecording(void) const;
|
||||
virtual int SignalStrength(void) const;
|
||||
virtual int SignalQuality(void) const;
|
||||
|
||||
@@ -101,6 +107,7 @@ public:
|
||||
public:
|
||||
virtual void WriteData(u_char *bufferP, int lengthP);
|
||||
virtual unsigned int CheckData(void);
|
||||
virtual int GetId(void);
|
||||
};
|
||||
|
||||
#endif // __SATIP_DEVICE_H
|
||||
|
@@ -14,6 +14,7 @@ public:
|
||||
virtual ~cSatipDeviceIf() {}
|
||||
virtual void WriteData(u_char *bufferP, int lengthP) = 0;
|
||||
virtual unsigned int CheckData(void) = 0;
|
||||
virtual int GetId(void) = 0;
|
||||
|
||||
private:
|
||||
cSatipDeviceIf(const cSatipDeviceIf&);
|
||||
|
144
discover.c
144
discover.c
@@ -6,7 +6,11 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_TINYXML
|
||||
#include <tinyxml.h>
|
||||
#else
|
||||
#include <pugixml.hpp>
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "socket.h"
|
||||
@@ -31,36 +35,52 @@ cSatipDiscover *cSatipDiscover::GetInstance(void)
|
||||
bool cSatipDiscover::Initialize(void)
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
if (instanceS)
|
||||
instanceS->Activate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void cSatipDiscover::Destroy(void)
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
DELETE_POINTER(instanceS);
|
||||
if (instanceS)
|
||||
instanceS->Deactivate();
|
||||
}
|
||||
|
||||
size_t cSatipDiscover::WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP)
|
||||
size_t cSatipDiscover::WriteCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP)
|
||||
{
|
||||
cSatipDiscover *obj = reinterpret_cast<cSatipDiscover *>(dataP);
|
||||
size_t len = sizeP * nmembP;
|
||||
//debug("cSatipDiscover::%s(%zu)", __FUNCTION__, len);
|
||||
|
||||
char *s, *p = (char *)ptrP;
|
||||
char *r = strtok_r(p, "\r\n", &s);
|
||||
char *desc = NULL, *model = NULL, *addr = NULL;
|
||||
while (r) {
|
||||
//debug("cSatipDiscover::%s(%zu): %s", __FUNCTION__, len, r);
|
||||
// <friendlyName>OctopusNet</friendlyName>
|
||||
if (startswith(r, "<friendlyName"))
|
||||
desc = StripTags(r);
|
||||
// <satip:X_SATIPCAP xmlns:satip="urn:ses-com:satip">DVBT-2</satip:X_SATIPCAP>
|
||||
if (startswith(r, "<satip:X_SATIPCAP"))
|
||||
model = StripTags(r);
|
||||
r = strtok_r(NULL, "\r\n", &s);
|
||||
}
|
||||
if (obj) {
|
||||
CURLcode res = CURLE_OK;
|
||||
const char *desc = NULL, *model = NULL, *addr = NULL;
|
||||
#ifdef USE_TINYXML
|
||||
TiXmlDocument doc;
|
||||
char *xml = MALLOC(char, len + 1);
|
||||
memcpy(xml, ptrP, len);
|
||||
*(xml + len + 1) = 0;
|
||||
doc.Parse((const char *)xml);
|
||||
TiXmlHandle docHandle(&doc);
|
||||
TiXmlElement *descElement = docHandle.FirstChild("root").FirstChild("device").FirstChild("friendlyName").ToElement();
|
||||
if (descElement)
|
||||
desc = descElement->GetText() ? descElement->GetText() : "MyBrokenHardware";
|
||||
TiXmlElement *modelElement = docHandle.FirstChild("root").FirstChild("device").FirstChild("satip:X_SATIPCAP").ToElement();
|
||||
if (modelElement)
|
||||
model = modelElement->GetText() ? modelElement->GetText() : "DVBS2-1";
|
||||
#else
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_buffer(ptrP, len);
|
||||
if (result) {
|
||||
pugi::xml_node descNode = doc.first_element_by_path("root/device/friendlyName");
|
||||
if (descNode)
|
||||
desc = descNode.text().as_string("MyBrokenHardware");
|
||||
pugi::xml_node modelNode = doc.first_element_by_path("root/device/satip:X_SATIPCAP");
|
||||
if (modelNode)
|
||||
model = modelNode.text().as_string("DVBS2-1");
|
||||
}
|
||||
#endif
|
||||
SATIP_CURL_EASY_GETINFO(obj->handleM, CURLINFO_PRIMARY_IP, &addr);
|
||||
obj->AddServer(addr, desc, model);
|
||||
}
|
||||
@@ -85,10 +105,8 @@ cSatipDiscover::cSatipDiscover()
|
||||
cSatipDiscover::~cSatipDiscover()
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
Deactivate();
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
sleepM.Signal();
|
||||
if (Running())
|
||||
Cancel(3);
|
||||
// Free allocated memory
|
||||
DELETENULL(socketM);
|
||||
DELETENULL(serversM);
|
||||
@@ -97,6 +115,21 @@ cSatipDiscover::~cSatipDiscover()
|
||||
handleM = NULL;
|
||||
}
|
||||
|
||||
void cSatipDiscover::Activate(void)
|
||||
{
|
||||
// Start the thread
|
||||
Start();
|
||||
}
|
||||
|
||||
void cSatipDiscover::Deactivate(void)
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
sleepM.Signal();
|
||||
if (Running())
|
||||
Cancel(3);
|
||||
}
|
||||
|
||||
void cSatipDiscover::Action(void)
|
||||
{
|
||||
debug("cSatipDiscover::%s(): entering", __FUNCTION__);
|
||||
@@ -117,12 +150,8 @@ void cSatipDiscover::Janitor(void)
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) {
|
||||
if (srv->LastSeen() > eProbeIntervalMs * 2) {
|
||||
info("Removing device %s (%s %s)", srv->Description(), srv->Address(), srv->Model());
|
||||
serversM->Del(srv);
|
||||
}
|
||||
}
|
||||
if (serversM)
|
||||
serversM->Cleanup(eProbeIntervalMs * 2);
|
||||
}
|
||||
|
||||
void cSatipDiscover::Probe(void)
|
||||
@@ -213,15 +242,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *descP, const char
|
||||
if (serversM) {
|
||||
cSatipServer *tmp = new cSatipServer(addrP, descP, modelP);
|
||||
// Validate against existing servers
|
||||
bool found = false;
|
||||
for (cSatipServer *s = serversM->First(); s; s = serversM->Next(s)) {
|
||||
if (s->Compare(*tmp) == 0) {
|
||||
found = true;
|
||||
s->Update();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (!serversM->Update(tmp)) {
|
||||
info("Adding device %s (%s %s)", tmp->Description(), tmp->Address(), tmp->Model());
|
||||
serversM->Add(tmp);
|
||||
}
|
||||
@@ -230,26 +251,25 @@ void cSatipDiscover::AddServer(const char *addrP, const char *descP, const char
|
||||
}
|
||||
}
|
||||
|
||||
bool cSatipDiscover::IsValidServer(cSatipServer *serverP)
|
||||
int cSatipDiscover::GetServerCount(void)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d)", __FUNCTION__);
|
||||
//debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) {
|
||||
if (srv == serverP)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return serversM ? serversM->Count() : -1;
|
||||
}
|
||||
|
||||
cSatipServer *cSatipDiscover::GetServer(int modelP)
|
||||
cSatipServer *cSatipDiscover::GetServer(int sourceP, int systemP)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
|
||||
//debug("cSatipDiscover::%s(%d, %d)", __FUNCTION__, sourceP, systemP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) {
|
||||
if (srv->Match(modelP))
|
||||
return srv;
|
||||
}
|
||||
return NULL;
|
||||
return serversM ? serversM->Find(sourceP, systemP) : NULL;
|
||||
}
|
||||
|
||||
cSatipServer *cSatipDiscover::GetServer(cSatipServer *serverP)
|
||||
{
|
||||
//debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
return serversM ? serversM->Find(serverP) : NULL;
|
||||
}
|
||||
|
||||
cSatipServers *cSatipDiscover::GetServers(void)
|
||||
@@ -259,25 +279,31 @@ cSatipServers *cSatipDiscover::GetServers(void)
|
||||
return serversM;
|
||||
}
|
||||
|
||||
cString cSatipDiscover::GetServerString(cSatipServer *serverP)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
return serversM ? serversM->GetString(serverP) : "";
|
||||
}
|
||||
|
||||
cString cSatipDiscover::GetServerList(void)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
cString list = "";
|
||||
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv))
|
||||
list = cString::sprintf("%s%s:%s:%s\n", *list, srv->Address(), srv->Model(), srv->Description());
|
||||
return list;
|
||||
return serversM ? serversM->List() : "";
|
||||
}
|
||||
|
||||
void cSatipDiscover::UseServer(cSatipServer *serverP, bool onOffP)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
if (serversM)
|
||||
serversM->Use(serverP, onOffP);
|
||||
}
|
||||
|
||||
int cSatipDiscover::NumProvidedSystems(void)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d)", __FUNCTION__, modelP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
int count = 0;
|
||||
for (cSatipServer *srv = serversM->First(); srv; srv = serversM->Next(srv)) {
|
||||
count += srv->Satellite();
|
||||
count += srv->Terrestrial();
|
||||
count += srv->Terrestrial2();
|
||||
}
|
||||
return count;
|
||||
return serversM ? serversM->NumProvidedSystems() : 0;
|
||||
}
|
||||
|
80
discover.h
80
discover.h
@@ -9,79 +9,13 @@
|
||||
#define __SATIP_DISCOVER_H
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
#include <vdr/thread.h>
|
||||
#include <vdr/tools.h>
|
||||
|
||||
#include "server.h"
|
||||
#include "socket.h"
|
||||
|
||||
class cSatipServer : public cListObject {
|
||||
private:
|
||||
enum eSatipServer {
|
||||
eSatipServerDVBS2 = 0,
|
||||
eSatipServerDVBT,
|
||||
eSatipServerDVBT2,
|
||||
eSatipServerCount
|
||||
};
|
||||
cString addressM;
|
||||
cString descriptionM;
|
||||
cString modelM;
|
||||
int modelCountM[eSatipServerCount];
|
||||
int modelTypeM;
|
||||
cTimeMs lastSeenM;
|
||||
|
||||
public:
|
||||
enum eSatipModelType {
|
||||
eSatipModelTypeDVBS2 = 0x01,
|
||||
eSatipModelTypeDVBT = 0x02,
|
||||
eSatipModelTypeDVBT2 = 0x04,
|
||||
eSatipModelTypeMask = 0x0F
|
||||
};
|
||||
cSatipServer(const char *addressP, const char *descriptionP, const char *modelP) : addressM(addressP), descriptionM(descriptionP), modelM(modelP), modelTypeM(eSatipModelTypeMask), lastSeenM(0)
|
||||
{
|
||||
memset(modelCountM, 0, sizeof(modelCountM));
|
||||
if (isempty(*modelM))
|
||||
modelM = "DVBS-1,DVBT2-1";
|
||||
char *s, *p = strdup(*modelM);
|
||||
char *r = strtok_r(p, ",", &s);
|
||||
while (r) {
|
||||
if (strstr(r, "DVBS2")) {
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBS2;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipServerDVBS2] = atoi(++c);
|
||||
}
|
||||
if (strstr(r, "DVBT2")) {
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBT | cSatipServer::eSatipModelTypeDVBT2;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipServerDVBT2] = atoi(++c);
|
||||
}
|
||||
if (strstr(r, "DVBT")) {
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBT;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipServerDVBT] = atoi(++c);
|
||||
}
|
||||
r = strtok_r(NULL, ",", &s);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
virtual int Compare(const cListObject &listObjectP) const { const cSatipServer *s = (const cSatipServer *)&listObjectP; return strcasecmp(*addressM, *s->addressM); }
|
||||
const char *Description() { return *descriptionM; }
|
||||
const char *Address() { return *addressM; }
|
||||
const char *Model(void) { return modelM; }
|
||||
int ModelType(void) { return modelTypeM; }
|
||||
bool Match(int modelP) { return ((modelP & eSatipModelTypeMask) & modelTypeM); }
|
||||
int Satellite() { return (modelTypeM & eSatipModelTypeDVBS2) ? modelCountM[eSatipServerDVBS2] : 0; }
|
||||
int Terrestrial() { return (modelTypeM & eSatipModelTypeDVBT) ? modelCountM[eSatipServerDVBT] : 0; }
|
||||
int Terrestrial2() { return (modelTypeM & eSatipModelTypeDVBT2) ? modelCountM[eSatipServerDVBT2] : 0; }
|
||||
int LastSeen(void) { return lastSeenM.Elapsed(); }
|
||||
void Update(void) { lastSeenM.Set(); }
|
||||
};
|
||||
|
||||
class cSatipServers : public cList<cSatipServer> {
|
||||
};
|
||||
|
||||
|
||||
class cSatipDiscover : public cThread {
|
||||
private:
|
||||
enum {
|
||||
@@ -94,13 +28,15 @@ private:
|
||||
static cSatipDiscover *instanceS;
|
||||
static const char *bcastAddressS;
|
||||
static const char *bcastMessageS;
|
||||
static size_t WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
||||
static size_t WriteCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
||||
cMutex mutexM;
|
||||
CURL *handleM;
|
||||
cSatipSocket *socketM;
|
||||
cCondWait sleepM;
|
||||
cTimeMs probeIntervalM;
|
||||
cSatipServers *serversM;
|
||||
void Activate(void);
|
||||
void Deactivate(void);
|
||||
void Janitor(void);
|
||||
void Probe(void);
|
||||
void Read(void);
|
||||
@@ -119,9 +55,13 @@ public:
|
||||
static bool Initialize(void);
|
||||
static void Destroy(void);
|
||||
virtual ~cSatipDiscover();
|
||||
bool IsValidServer(cSatipServer *serverP);
|
||||
cSatipServer *GetServer(int modelP);
|
||||
void TriggerScan(void) { probeIntervalM.Set(0); }
|
||||
int GetServerCount(void);
|
||||
cSatipServer *GetServer(int sourceP, int systemP = -1);
|
||||
cSatipServer *GetServer(cSatipServer *serverP);
|
||||
cSatipServers *GetServers(void);
|
||||
cString GetServerString(cSatipServer *serverP);
|
||||
void UseServer(cSatipServer *serverP, bool onOffP);
|
||||
cString GetServerList(void);
|
||||
int NumProvidedSystems(void);
|
||||
};
|
||||
|
183
param.c
Normal file
183
param.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* param.c: SAT>IP plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <vdr/dvbdevice.h>
|
||||
#include "common.h"
|
||||
#include "param.h"
|
||||
|
||||
// --- cSatipParameterMaps ----------------------------------------------------
|
||||
|
||||
struct tSatipParameterMap {
|
||||
int driverValue;
|
||||
const char *satipString;
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipBandwidthValues[] = {
|
||||
{ 5000000, "&bw=5" },
|
||||
{ 6000000, "&bw=6" },
|
||||
{ 7000000, "&bw=7" },
|
||||
{ 8000000, "&bw=8" },
|
||||
{ 10000000, "&bw=10" },
|
||||
{ 1712000, "&bw=1.712" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipPilotValues[] = {
|
||||
{ PILOT_OFF, "&plts=off" },
|
||||
{ PILOT_ON, "&plts=on" },
|
||||
{ PILOT_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSisoMisoValues[] = {
|
||||
{ 0, "&sm=0" },
|
||||
{ 1, "&sm=1" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipCodeRateValues[] = {
|
||||
{ FEC_NONE, "" },
|
||||
{ FEC_1_2, "&fec=12" },
|
||||
{ FEC_2_3, "&fec=23" },
|
||||
{ FEC_3_4, "&fec=34" },
|
||||
{ FEC_3_5, "&fec=35" },
|
||||
{ FEC_4_5, "&fec=45" },
|
||||
{ FEC_5_6, "&fec=56" },
|
||||
{ FEC_6_7, "&fec=67" },
|
||||
{ FEC_7_8, "&fec=78" },
|
||||
{ FEC_8_9, "&fec=89" },
|
||||
{ FEC_9_10, "&fec=910" },
|
||||
{ FEC_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipModulationValues[] = {
|
||||
{ QPSK, "&mtype=qpsk" },
|
||||
{ PSK_8, "&mtype=8psk" },
|
||||
{ QAM_16, "&mtype=16qam" },
|
||||
{ QAM_64, "&mtype=64qam" },
|
||||
{ QAM_128, "&mtype=128qam" },
|
||||
{ QAM_256, "&mtype=256qam" },
|
||||
{ QAM_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSystemValuesSat[] = {
|
||||
{ 0, "&msys=dvbs" },
|
||||
{ 1, "&msys=dvbs2" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSystemValuesTerrestrial[] = {
|
||||
{ 0, "&msys=dvbt" },
|
||||
{ 1, "&msys=dvbt2" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSystemValuesCable[] = {
|
||||
{ 0, "&msys=dvbc" },
|
||||
{ 1, "&msys=dvbc2" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipTransmissionValues[] = {
|
||||
{ TRANSMISSION_MODE_1K, "&tmode=1k" },
|
||||
{ TRANSMISSION_MODE_2K, "&tmode=2k" },
|
||||
{ TRANSMISSION_MODE_4K, "&tmode=4k" },
|
||||
{ TRANSMISSION_MODE_8K, "&tmode=8k" },
|
||||
{ TRANSMISSION_MODE_16K, "&tmode=16k" },
|
||||
{ TRANSMISSION_MODE_32K, "&tmode=32k" },
|
||||
{ TRANSMISSION_MODE_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipGuardValues[] = {
|
||||
{ GUARD_INTERVAL_1_4, "&gi=14" },
|
||||
{ GUARD_INTERVAL_1_8, "&gi=18" },
|
||||
{ GUARD_INTERVAL_1_16, "&gi=116" },
|
||||
{ GUARD_INTERVAL_1_32, "&gi=132" },
|
||||
{ GUARD_INTERVAL_1_128, "&gi=1128" },
|
||||
{ GUARD_INTERVAL_19_128, "&gi=19128" },
|
||||
{ GUARD_INTERVAL_19_256, "&gi=19256" },
|
||||
{ GUARD_INTERVAL_AUTO, "" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipRollOffValues[] = {
|
||||
{ ROLLOFF_AUTO, "" },
|
||||
{ ROLLOFF_20, "&ro=0.20" },
|
||||
{ ROLLOFF_25, "&ro=0.25" },
|
||||
{ ROLLOFF_35, "&ro=0.35" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static int SatipUserIndex(int valueP, const tSatipParameterMap *mapP)
|
||||
{
|
||||
const tSatipParameterMap *map = mapP;
|
||||
while (map && map->driverValue != -1) {
|
||||
if (map->driverValue == valueP)
|
||||
return map - mapP;
|
||||
map++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int PrintUrlString(char *bufP, int lenP, int valueP, const tSatipParameterMap *mapP)
|
||||
{
|
||||
int n = SatipUserIndex(valueP, mapP);
|
||||
return ((n >= 0) && (lenP > 0)) ? snprintf(bufP, lenP, "%s", mapP[n].satipString) : 0;
|
||||
}
|
||||
|
||||
cString GetTransponderUrlParameters(const cChannel *channelP)
|
||||
{
|
||||
if (channelP) {
|
||||
char buffer[255];
|
||||
cDvbTransponderParameters dtp(channelP->Parameters());
|
||||
#if defined(APIVERSNUM) && APIVERSNUM < 20106
|
||||
int Pilot = PILOT_AUTO;
|
||||
int T2SystemId = 0;
|
||||
int SisoMiso = 0;
|
||||
#else
|
||||
int Pilot = dtp.Pilot();
|
||||
int T2SystemId = dtp.T2SystemId();
|
||||
int SisoMiso = dtp.SisoMiso();
|
||||
#endif
|
||||
float freq = channelP->Frequency();
|
||||
char type = cSource::ToChar(channelP->Source());
|
||||
cSource *source = Sources.Get(channelP->Source());
|
||||
int src = (strchr("S", type) && source) ? atoi(source->Description()) : 1;
|
||||
char *q = buffer;
|
||||
*q = 0;
|
||||
// Scale down frequencies to MHz
|
||||
while (freq > 20000L)
|
||||
freq /= 1000L;
|
||||
#define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*')))
|
||||
#define STBUFLEFT (sizeof(buffer) - (q - buffer))
|
||||
q += snprintf(q, STBUFLEFT, "freq=%s", *dtoa(freq, "%lg"));
|
||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&src=%d", ((src > 0) && (src <= 255)) ? src : 1);
|
||||
ST("CS *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&pol=%c", tolower(dtp.Polarization()));
|
||||
ST("C T2") q += snprintf(q, STBUFLEFT, "&plp=%d", dtp.StreamId());
|
||||
ST(" T2") q += snprintf(q, STBUFLEFT, "&t2id=%d", T2SystemId);
|
||||
ST(" T2") q += PrintUrlString(q, STBUFLEFT, SisoMiso, SatipSisoMisoValues);
|
||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Bandwidth(), SatipBandwidthValues);
|
||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Guard(), SatipGuardValues);
|
||||
ST("CST*") q += PrintUrlString(q, STBUFLEFT, dtp.CoderateH(), SatipCodeRateValues);
|
||||
ST(" S 2") q += PrintUrlString(q, STBUFLEFT, Pilot, SatipPilotValues);
|
||||
ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
||||
ST("C T*") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(), SatipModulationValues);
|
||||
ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.RollOff(), SatipRollOffValues);
|
||||
ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesSat);
|
||||
ST("C *") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesCable);
|
||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.System(), SatipSystemValuesTerrestrial);
|
||||
ST(" T*") q += PrintUrlString(q, STBUFLEFT, dtp.Transmission(), SatipTransmissionValues);
|
||||
#undef ST
|
||||
return buffer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
15
param.h
Normal file
15
param.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* param.h: SAT>IP plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SATIP_PARAM_H
|
||||
#define __SATIP_PARAM_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
cString GetTransponderUrlParameters(const cChannel *channelP);
|
||||
|
||||
#endif // __SATIP_PARAM_H
|
137
po/ca_ES.po
Normal file
137
po/ca_ES.po
Normal file
@@ -0,0 +1,137 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||
# This file is distributed under the same license as the satip package.
|
||||
# Gabriel Bonich, 2014
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 0.2.3\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2014-04-12 04:12+0200\n"
|
||||
"PO-Revision-Date: 2014-04-12 04:12+0200\n"
|
||||
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
||||
"Language-Team: Catalan <vdr@linuxtv.org>\n"
|
||||
"Language: ca\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\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 Devices"
|
||||
msgstr "SAT>IP Dispositius"
|
||||
|
||||
msgid "SAT>IP Device"
|
||||
msgstr "SAT>IP Dispositiu"
|
||||
|
||||
msgid "Address"
|
||||
msgstr "Adressa"
|
||||
|
||||
msgid "Model"
|
||||
msgstr "Model"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descripció"
|
||||
|
||||
msgid "Creation date"
|
||||
msgstr "Creació de data"
|
||||
|
||||
msgid "SAT>IP Information"
|
||||
msgstr "SAT>IP Informació"
|
||||
|
||||
msgid "General"
|
||||
msgstr "General"
|
||||
|
||||
msgid "Pids"
|
||||
msgstr "Pids"
|
||||
|
||||
msgid "Filters"
|
||||
msgstr "Filtres"
|
||||
|
||||
msgid "Bits/bytes"
|
||||
msgstr "Bits/Bytes"
|
||||
|
||||
msgid "SAT>IP information not available!"
|
||||
msgstr "SAT>IP Informació no disponible!"
|
||||
|
||||
msgid "off"
|
||||
msgstr "Apagat"
|
||||
|
||||
msgid "low"
|
||||
msgstr "Baix"
|
||||
|
||||
msgid "normal"
|
||||
msgstr "Normal"
|
||||
|
||||
msgid "high"
|
||||
msgstr "Alt"
|
||||
|
||||
msgid "Operating mode"
|
||||
msgstr "Mode de operació"
|
||||
|
||||
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 ""
|
||||
"Defineig la manera de operar els Disposituis SAT>IP:\n"
|
||||
"\n"
|
||||
"Apagat - Dispositius desactivats\n"
|
||||
"Baix - Dispositius treballan a baixa prioritat\n"
|
||||
"Normal - Dispositius treballan en parametres normals\n"
|
||||
"Alta - Dispositius treballan a prioritat Alta"
|
||||
|
||||
msgid "Enable EPG scanning"
|
||||
msgstr "Activa Escanneig 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 ""
|
||||
"Definir si s'utilitzarà l'anàlisi en segon pla del EPG.\n"
|
||||
"\n"
|
||||
"Aquesta configuració desactiva la funcionalitat d'escaneig EIT automàtica per a tots els dispositius SAT>IP."
|
||||
|
||||
msgid "Disabled filters"
|
||||
msgstr "Desactiva filtres"
|
||||
|
||||
msgid "none"
|
||||
msgstr "no"
|
||||
|
||||
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 black-listing the filters here useful section data can be left intact for VDR to process."
|
||||
msgstr ""
|
||||
"Defineix el numero de filtres de secció que seran deshabilitats.\n"
|
||||
"\n"
|
||||
"Alguns filtres de secció podrien provocar un comportament no desitjat a VDR, com sincronitzar malament l'hora. Posant aquests filtres a la llista negra, aqui, la secció de dades útil pot ser deixada intacta pel seu procès en el VDR."
|
||||
|
||||
msgid "Filter"
|
||||
msgstr "Filtra"
|
||||
|
||||
msgid "Define an ill-behaving filter to be blacklisted."
|
||||
msgstr "Definir un filtre mal comportar a la llista negra."
|
||||
|
||||
msgid "Active SAT>IP devices:"
|
||||
msgstr "Dispositius SAT>IP actius:"
|
||||
|
||||
msgid "Help"
|
||||
msgstr "Ajuda"
|
100
po/de_DE.po
100
po/de_DE.po
@@ -1,14 +1,14 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg & Antti Seppala
|
||||
# This file is distributed under the same license as the iptv package.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||
# This file is distributed under the same license as the satip package.
|
||||
# Frank Neumann, 2014
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 0.0.1\n"
|
||||
"Project-Id-Version: vdr-satip 0.2.3\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2014-03-08 03:08+0200\n"
|
||||
"PO-Revision-Date: 2014-03-08 03:08+0200\n"
|
||||
"POT-Creation-Date: 2014-04-12 04:12+0200\n"
|
||||
"PO-Revision-Date: 2014-04-12 04:12+0200\n"
|
||||
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
|
||||
"Language-Team: German <vdr@linuxtv.org>\n"
|
||||
"Language: de\n"
|
||||
@@ -25,14 +25,8 @@ msgstr "NIT (0x40)"
|
||||
msgid "SDT (0x42)"
|
||||
msgstr "SDT (0x42)"
|
||||
|
||||
msgid "EIT (0x4E/0x4F)"
|
||||
msgstr "EIT (0x4E/0x4F)"
|
||||
|
||||
msgid "EIT (0x5X)"
|
||||
msgstr "EIT (0x5X)"
|
||||
|
||||
msgid "EIT (0x6X)"
|
||||
msgstr "EIT (0x6X)"
|
||||
msgid "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
msgstr "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
|
||||
msgid "TDT (0x70)"
|
||||
msgstr "TDT (0x70)"
|
||||
@@ -43,8 +37,17 @@ msgstr "SAT>IP Geräte"
|
||||
msgid "SAT>IP Device"
|
||||
msgstr "SAT>IP Gerät"
|
||||
|
||||
msgid "Button$Scan"
|
||||
msgstr "Starte Kanalsuche"
|
||||
msgid "Address"
|
||||
msgstr "Adresse"
|
||||
|
||||
msgid "Model"
|
||||
msgstr "Modell"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
msgid "Creation date"
|
||||
msgstr "Zeitpunkt der Erstellung"
|
||||
|
||||
msgid "SAT>IP Information"
|
||||
msgstr "SAT>IP Informationen"
|
||||
@@ -64,6 +67,36 @@ msgstr "Bits/Bytes"
|
||||
msgid "SAT>IP information not available!"
|
||||
msgstr "Keine SAT>IP Informationen verfügbar!"
|
||||
|
||||
msgid "off"
|
||||
msgstr "aus"
|
||||
|
||||
msgid "low"
|
||||
msgstr "niedrig"
|
||||
|
||||
msgid "normal"
|
||||
msgstr "normal"
|
||||
|
||||
msgid "high"
|
||||
msgstr "hoch"
|
||||
|
||||
msgid "Operating mode"
|
||||
msgstr "Betriebsmodus"
|
||||
|
||||
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 ""
|
||||
"Bestimme den Betriebsmodus für alle SAT>IP Geräte:\n"
|
||||
"\n"
|
||||
"aus - Geräte sind abgeschaltet\n"
|
||||
"niedrig - Geräte arbeiten mit geringster Priorität\n"
|
||||
"normal - Geräte arbeiten innerhalb der gewöhnlichen Parameter\n"
|
||||
"hoch - Geräte arbeiten mit höchste Priorität"
|
||||
|
||||
msgid "Enable EPG scanning"
|
||||
msgstr "Aktiviere EPG Aktualisierung"
|
||||
|
||||
@@ -76,7 +109,6 @@ msgstr ""
|
||||
"\n"
|
||||
"Diese Einstellung schaltet die automatische EIT Aktualisierung für alle SAT>IP Geräte."
|
||||
|
||||
|
||||
msgid "Disabled filters"
|
||||
msgstr "Deaktivierte Filter"
|
||||
|
||||
@@ -103,39 +135,3 @@ msgstr "Aktive SAT>IP Geräte:"
|
||||
|
||||
msgid "Help"
|
||||
msgstr "Hilfe"
|
||||
|
||||
msgid "off"
|
||||
msgstr "aus"
|
||||
|
||||
msgid "on"
|
||||
msgstr "ein"
|
||||
|
||||
msgid "auto"
|
||||
msgstr "auto"
|
||||
|
||||
msgid "SISO"
|
||||
msgstr "SISO"
|
||||
|
||||
msgid "MISO"
|
||||
msgstr "MISO"
|
||||
|
||||
msgid "Nid"
|
||||
msgstr "Nid"
|
||||
|
||||
msgid "Tid"
|
||||
msgstr "Tid"
|
||||
|
||||
msgid "Rid"
|
||||
msgstr "Rid"
|
||||
|
||||
msgid "SignalSource"
|
||||
msgstr "Signalquelle"
|
||||
|
||||
msgid "PilotTones"
|
||||
msgstr "Pilottöne"
|
||||
|
||||
msgid "T2SystemId"
|
||||
msgstr "T2-Systemkennung"
|
||||
|
||||
msgid "SISO/MISO"
|
||||
msgstr "SISO/MISO"
|
||||
|
137
po/es_ES.po
Normal file
137
po/es_ES.po
Normal file
@@ -0,0 +1,137 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||
# This file is distributed under the same license as the satip package.
|
||||
# Gabriel Bonich, 2014
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 0.2.3\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2014-04-12 04:12+0200\n"
|
||||
"PO-Revision-Date: 2014-04-12 04:12+0200\n"
|
||||
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
||||
"Language-Team: Spanish <vdr@linuxtv.org>\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\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 Devices"
|
||||
msgstr "SAT>IP Dispositivos"
|
||||
|
||||
msgid "SAT>IP Device"
|
||||
msgstr "SAT>IP Dispositivo"
|
||||
|
||||
msgid "Address"
|
||||
msgstr "Dirección"
|
||||
|
||||
msgid "Model"
|
||||
msgstr "Modelo"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
msgid "Creation date"
|
||||
msgstr "Fecha creación"
|
||||
|
||||
msgid "SAT>IP Information"
|
||||
msgstr "SAT>IP Información"
|
||||
|
||||
msgid "General"
|
||||
msgstr "General"
|
||||
|
||||
msgid "Pids"
|
||||
msgstr "Pids"
|
||||
|
||||
msgid "Filters"
|
||||
msgstr "Filtros"
|
||||
|
||||
msgid "Bits/bytes"
|
||||
msgstr "Bits/Bytes"
|
||||
|
||||
msgid "SAT>IP information not available!"
|
||||
msgstr "SAT>IP Información no disponible!"
|
||||
|
||||
msgid "off"
|
||||
msgstr "Apagado"
|
||||
|
||||
msgid "low"
|
||||
msgstr "Bajo"
|
||||
|
||||
msgid "normal"
|
||||
msgstr "Normal"
|
||||
|
||||
msgid "high"
|
||||
msgstr "Alto"
|
||||
|
||||
msgid "Operating mode"
|
||||
msgstr "Modo de operación"
|
||||
|
||||
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 ""
|
||||
"Define la manera que trabajan los Dispositivos SAT>IP:\n"
|
||||
"\n"
|
||||
"Apagat - Dispositivos desactivados\n"
|
||||
"Baix - Dispositivos trabajando con prioridad Baja\n"
|
||||
"Normal - Dispositivos trabajando con prioridad Normal\n"
|
||||
"Alta - Dispositivos trabajando con prioridad Alta"
|
||||
|
||||
msgid "Enable EPG scanning"
|
||||
msgstr "Activa Escaneo 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 ""
|
||||
"Definir si se utilitzará el analisí en segundo plano del EPG.\n"
|
||||
"\n"
|
||||
"Esta configuración desactiva la funcionalidad del escaneo EIT automática para todos los Dispositivos SAT>IP."
|
||||
|
||||
msgid "Disabled filters"
|
||||
msgstr "Desactiva filtros"
|
||||
|
||||
msgid "none"
|
||||
msgstr "no"
|
||||
|
||||
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 black-listing the filters here useful section data can be left intact for VDR to process."
|
||||
msgstr ""
|
||||
"Define el numero de filtros de sección que seran deshabilitados.\n"
|
||||
"\n"
|
||||
"Algunos filtros de sección podrian causar un comportamiento no deseado a VDR, como sincronizar mal la hora. Poniendo estos filtros en la lista negra, aqui, la sección de datos útiles se puede dejar intacta para su proceso con el VDR."
|
||||
|
||||
msgid "Filter"
|
||||
msgstr "Filtra"
|
||||
|
||||
msgid "Define an ill-behaving filter to be blacklisted."
|
||||
msgstr "Define un filtro para poner en la lista negra."
|
||||
|
||||
msgid "Active SAT>IP devices:"
|
||||
msgstr "Dispositivos SAT>IP activos:"
|
||||
|
||||
msgid "Help"
|
||||
msgstr "Ayuda"
|
98
po/fi_FI.po
98
po/fi_FI.po
@@ -1,14 +1,14 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg & Antti Seppala
|
||||
# This file is distributed under the same license as the iptv package.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||
# This file is distributed under the same license as the satip package.
|
||||
# Rolf Ahrenberg, 2014
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 0.0.1\n"
|
||||
"Project-Id-Version: vdr-satip 0.2.3\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2014-03-08 03:08+0200\n"
|
||||
"PO-Revision-Date: 2014-03-08 03:08+0200\n"
|
||||
"POT-Creation-Date: 2014-04-12 04:12+0200\n"
|
||||
"PO-Revision-Date: 2014-04-12 04:12+0200\n"
|
||||
"Last-Translator: Rolf Ahrenberg\n"
|
||||
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
||||
"Language: fi\n"
|
||||
@@ -25,14 +25,8 @@ msgstr "NIT (0x40)"
|
||||
msgid "SDT (0x42)"
|
||||
msgstr "SDT (0x42)"
|
||||
|
||||
msgid "EIT (0x4E/0x4F)"
|
||||
msgstr "EIT (0x4E/0x4F)"
|
||||
|
||||
msgid "EIT (0x5X)"
|
||||
msgstr "EIT (0x5X)"
|
||||
|
||||
msgid "EIT (0x6X)"
|
||||
msgstr "EIT (0x6X)"
|
||||
msgid "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
msgstr "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
|
||||
msgid "TDT (0x70)"
|
||||
msgstr "TDT (0x70)"
|
||||
@@ -43,8 +37,17 @@ msgstr "SAT>IP-laitteet"
|
||||
msgid "SAT>IP Device"
|
||||
msgstr "SAT>IP-laite"
|
||||
|
||||
msgid "Button$Scan"
|
||||
msgstr "Kanavahaku"
|
||||
msgid "Address"
|
||||
msgstr "Osoite"
|
||||
|
||||
msgid "Model"
|
||||
msgstr "Malli"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Kuvaus"
|
||||
|
||||
msgid "Creation date"
|
||||
msgstr "Luontiajankohta"
|
||||
|
||||
msgid "SAT>IP Information"
|
||||
msgstr "SAT>IP-tiedot"
|
||||
@@ -64,6 +67,35 @@ msgstr "Bitit/tavut"
|
||||
msgid "SAT>IP information not available!"
|
||||
msgstr "SAT>IP-tietoja ei saatavilla!"
|
||||
|
||||
msgid "off"
|
||||
msgstr "ei käytössä"
|
||||
|
||||
msgid "low"
|
||||
msgstr "matala"
|
||||
|
||||
msgid "normal"
|
||||
msgstr "normaali"
|
||||
|
||||
msgid "high"
|
||||
msgstr "korkea"
|
||||
|
||||
msgid "Operating mode"
|
||||
msgstr "Laitteiden toimintatapa"
|
||||
|
||||
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 ""
|
||||
"Määrittele toimintamoodi SAT>IP-laitteille:\n"
|
||||
"ei käytössä - laitteet ovat pois käytöstä\n"
|
||||
"matala - laitteet toimivat matalalla prioriteetilla\n"
|
||||
"normaali - laitteet toimivat normaalilla prioriteetilla\n"
|
||||
"korkea - laitteet toimivat korkealla prioriteetilla"
|
||||
|
||||
msgid "Enable EPG scanning"
|
||||
msgstr "Käytä ohjelmaoppaan taustapäivitystä"
|
||||
|
||||
@@ -102,39 +134,3 @@ msgstr "Aktiiviset SAT>IP-laitteet:"
|
||||
|
||||
msgid "Help"
|
||||
msgstr "Opaste"
|
||||
|
||||
msgid "off"
|
||||
msgstr "pois"
|
||||
|
||||
msgid "on"
|
||||
msgstr "päällä"
|
||||
|
||||
msgid "auto"
|
||||
msgstr "auto"
|
||||
|
||||
msgid "SISO"
|
||||
msgstr "SISO"
|
||||
|
||||
msgid "MISO"
|
||||
msgstr "MISO"
|
||||
|
||||
msgid "Nid"
|
||||
msgstr "Verkko-ID"
|
||||
|
||||
msgid "Tid"
|
||||
msgstr "Lähete-ID"
|
||||
|
||||
msgid "Rid"
|
||||
msgstr "Radio-ID"
|
||||
|
||||
msgid "SignalSource"
|
||||
msgstr "Signaalin lähde"
|
||||
|
||||
msgid "PilotTones"
|
||||
msgstr "Pilottiäänet"
|
||||
|
||||
msgid "T2SystemId"
|
||||
msgstr "T2-järjestelmä"
|
||||
|
||||
msgid "SISO/MISO"
|
||||
msgstr "SISO/MISO"
|
||||
|
34
satip.c
34
satip.c
@@ -13,6 +13,10 @@
|
||||
#include "discover.h"
|
||||
#include "setup.h"
|
||||
|
||||
#if defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM < 0x072400
|
||||
#warning "CURL version >= 0.7.36 is recommended"
|
||||
#endif
|
||||
|
||||
#if defined(APIVERSNUM) && APIVERSNUM < 20000
|
||||
#error "VDR-2.0.0 API version or greater is required!"
|
||||
#endif
|
||||
@@ -21,7 +25,7 @@
|
||||
#define GITVERSION ""
|
||||
#endif
|
||||
|
||||
const char VERSION[] = "0.0.1" GITVERSION;
|
||||
const char VERSION[] = "0.2.3" GITVERSION;
|
||||
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
||||
|
||||
class cPluginSatip : public cPlugin {
|
||||
@@ -194,7 +198,9 @@ bool cPluginSatip::SetupParse(const char *nameP, const char *valueP)
|
||||
{
|
||||
debug("cPluginSatip::%s()", __FUNCTION__);
|
||||
// Parse your own setup parameters and store their values.
|
||||
if (!strcasecmp(nameP, "EnableEITScan"))
|
||||
if (!strcasecmp(nameP, "OperatingMode"))
|
||||
SatipConfig.SetOperatingMode(atoi(valueP));
|
||||
else if (!strcasecmp(nameP, "EnableEITScan"))
|
||||
SatipConfig.SetEITScan(atoi(valueP));
|
||||
else if (!strcasecmp(nameP, "DisabledFilters")) {
|
||||
int DisabledFilters[SECTION_FILTER_TABLE_SIZE];
|
||||
@@ -229,6 +235,8 @@ const char **cPluginSatip::SVDRPHelpPages(void)
|
||||
" Lists active SAT>IP servers.\n",
|
||||
"CONT\n"
|
||||
" Shows SAT>IP device count.\n",
|
||||
"OPER\n"
|
||||
" Toggles operating mode of SAT>IP devices.\n",
|
||||
NULL
|
||||
};
|
||||
return HelpPages;
|
||||
@@ -284,6 +292,28 @@ cString cPluginSatip::SVDRPCommand(const char *commandP, const char *optionP, in
|
||||
else if (strcasecmp(commandP, "CONT") == 0) {
|
||||
return cString::sprintf("SAT>IP device count: %u", cSatipDevice::Count());
|
||||
}
|
||||
else if (strcasecmp(commandP, "OPER") == 0) {
|
||||
cString mode;
|
||||
SatipConfig.ToggleOperatingMode();
|
||||
switch (SatipConfig.GetOperatingMode()) {
|
||||
case cSatipConfig::eOperatingModeOff:
|
||||
mode = "off";
|
||||
break;
|
||||
case cSatipConfig::eOperatingModeLow:
|
||||
mode = "low";
|
||||
break;
|
||||
case cSatipConfig::eOperatingModeNormal:
|
||||
mode = "normal";
|
||||
break;
|
||||
case cSatipConfig::eOperatingModeHigh:
|
||||
mode = "high";
|
||||
break;
|
||||
default:
|
||||
mode = "unknown";
|
||||
break;
|
||||
}
|
||||
return cString::sprintf("SAT>IP operating mode: %s\n", *mode);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
||||
secLenM(0),
|
||||
tsFeedpM(0),
|
||||
pidM(pidP),
|
||||
ringBufferM(new cRingBufferFrame(eDmxMaxSectionCount * eDmxMaxSectionSize)),
|
||||
deviceIndexM(deviceIndexP)
|
||||
{
|
||||
//debug("cSatipSectionFilter::%s(%d, %d)", __FUNCTION__, deviceIndexM, pidM);
|
||||
@@ -33,11 +34,11 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
||||
filterMaskM[0] = maskP;
|
||||
|
||||
// Invert the filter
|
||||
for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i)
|
||||
for (i = 0; i < eDmxMaxFilterSize; ++i)
|
||||
filterValueM[i] ^= 0xFF;
|
||||
|
||||
uint8_t mask, mode, doneq = 0;
|
||||
for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i) {
|
||||
for (i = 0; i < eDmxMaxFilterSize; ++i) {
|
||||
mode = filterModeM[i];
|
||||
mask = filterMaskM[i];
|
||||
maskAndModeM[i] = (uint8_t)(mask & mode);
|
||||
@@ -48,7 +49,7 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
||||
|
||||
// Create sockets
|
||||
socketM[0] = socketM[1] = -1;
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socketM) != 0) {
|
||||
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socketM) != 0) {
|
||||
char tmp[64];
|
||||
error("Opening section filter sockets failed (device=%d pid=%d): %s", deviceIndexM, pidM, strerror_r(errno, tmp, sizeof(tmp)));
|
||||
}
|
||||
@@ -70,6 +71,7 @@ cSatipSectionFilter::~cSatipSectionFilter()
|
||||
if (tmp >= 0)
|
||||
close(tmp);
|
||||
secBufM = NULL;
|
||||
DELETENULL(ringBufferM);
|
||||
}
|
||||
|
||||
inline uint16_t cSatipSectionFilter::GetLength(const uint8_t *dataP)
|
||||
@@ -89,7 +91,7 @@ int cSatipSectionFilter::Filter(void)
|
||||
int i;
|
||||
uint8_t neq = 0;
|
||||
|
||||
for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i) {
|
||||
for (i = 0; i < eDmxMaxFilterSize; ++i) {
|
||||
uint8_t calcxor = (uint8_t)(filterValueM[i] ^ secBufM[i]);
|
||||
if (maskAndModeM[i] & calcxor)
|
||||
return 0;
|
||||
@@ -99,13 +101,8 @@ int cSatipSectionFilter::Filter(void)
|
||||
if (doneqM && !neq)
|
||||
return 0;
|
||||
|
||||
// There is no data in the read socket, more can be written
|
||||
if ((socketM[0] >= 0) && (socketM[1] >= 0) /*&& !select_single_desc(socketM[0], 0, false)*/) {
|
||||
ssize_t len = write(socketM[1], secBufM, secLenM);
|
||||
ERROR_IF(len < 0, "write()");
|
||||
// Update statistics
|
||||
AddSectionStatistic(len, 1);
|
||||
}
|
||||
if (ringBufferM && (secLenM > 0))
|
||||
ringBufferM->Put(new cFrame(secBufM, secLenM));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -122,11 +119,11 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
|
||||
{
|
||||
uint16_t limit, seclen, n;
|
||||
|
||||
if (tsFeedpM >= DMX_MAX_SECFEED_SIZE)
|
||||
if (tsFeedpM >= eDmxMaxSectionFeedSize)
|
||||
return 0;
|
||||
|
||||
if (tsFeedpM + lenP > DMX_MAX_SECFEED_SIZE)
|
||||
lenP = (uint8_t)(DMX_MAX_SECFEED_SIZE - tsFeedpM);
|
||||
if (tsFeedpM + lenP > eDmxMaxSectionFeedSize)
|
||||
lenP = (uint8_t)(eDmxMaxSectionFeedSize - tsFeedpM);
|
||||
|
||||
if (lenP <= 0)
|
||||
return 0;
|
||||
@@ -135,7 +132,7 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
|
||||
tsFeedpM = uint16_t(tsFeedpM + lenP);
|
||||
|
||||
limit = tsFeedpM;
|
||||
if (limit > DMX_MAX_SECFEED_SIZE)
|
||||
if (limit > eDmxMaxSectionFeedSize)
|
||||
return -1; // internal error should never happen
|
||||
|
||||
// Always set secbuf
|
||||
@@ -143,7 +140,7 @@ int cSatipSectionFilter::CopyDump(const uint8_t *bufP, uint8_t lenP)
|
||||
|
||||
for (n = 0; secBufpM + 2 < limit; ++n) {
|
||||
seclen = GetLength(secBufM);
|
||||
if ((seclen <= 0) || (seclen > DMX_MAX_SECTION_SIZE) || ((seclen + secBufpM) > limit))
|
||||
if ((seclen <= 0) || (seclen > eDmxMaxSectionSize) || ((seclen + secBufpM) > limit))
|
||||
return 0;
|
||||
secLenM = seclen;
|
||||
if (pusiSeenM)
|
||||
@@ -211,13 +208,33 @@ void cSatipSectionFilter::Process(const uint8_t* dataP)
|
||||
}
|
||||
}
|
||||
|
||||
bool cSatipSectionFilter::Send(void)
|
||||
{
|
||||
bool result = false;
|
||||
cFrame *section = ringBufferM->Get();
|
||||
if (section) {
|
||||
uchar *data = section->Data();
|
||||
int count = section->Count();
|
||||
if (data && (count > 0) && (socketM[1] >= 0) && (socketM[0] >= 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
|
||||
AddSectionStatistic(len, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP)
|
||||
: cThread("SAT>IP section handler", true),
|
||||
: cThread("SAT>IP section handler"),
|
||||
ringBufferM(new cRingBufferLinear(bufferLenP, TS_SIZE, false, *cString::sprintf("SAT>IP SECTION HANDLER %d", deviceIndexP))),
|
||||
mutexM(),
|
||||
deviceIndexM(deviceIndexP),
|
||||
processedM(false),
|
||||
ringBufferM(new cRingBufferLinear(bufferLenP, TS_SIZE, false, *cString::sprintf("SAT>IP SECTION HANDLER %d", deviceIndexP)))
|
||||
deviceIndexM(deviceIndexP)
|
||||
{
|
||||
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
||||
|
||||
@@ -238,8 +255,9 @@ cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigne
|
||||
cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
||||
{
|
||||
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
||||
Stop();
|
||||
|
||||
// Stop thread
|
||||
if (Running())
|
||||
Cancel(3);
|
||||
DELETE_POINTER(ringBufferM);
|
||||
|
||||
// Destroy all filters
|
||||
@@ -248,26 +266,28 @@ cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
||||
Delete(i);
|
||||
}
|
||||
|
||||
bool cSatipSectionFilterHandler::Stop(void)
|
||||
{
|
||||
debug("cSatipSectionFilterHandler::%s(%d): entering", __FUNCTION__, deviceIndexM);
|
||||
// Stop thread
|
||||
if (Running())
|
||||
Cancel(3);
|
||||
return true;
|
||||
}
|
||||
|
||||
void cSatipSectionFilterHandler::Action(void)
|
||||
{
|
||||
debug("cSatipSectionFilterHandler::%s(%d): entering", __FUNCTION__, deviceIndexM);
|
||||
bool processed = false;
|
||||
// Do the thread loop
|
||||
while (Running()) {
|
||||
// Send demuxed section packets through all filters
|
||||
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 (processedM) {
|
||||
if (processed) {
|
||||
ringBufferM->Del(TS_SIZE);
|
||||
processedM = false;
|
||||
processed = false;
|
||||
}
|
||||
uchar *p = ringBufferM->Get(len);
|
||||
if (p && (len >= TS_SIZE)) {
|
||||
@@ -289,7 +309,7 @@ void cSatipSectionFilterHandler::Action(void)
|
||||
filtersM[i]->Process(p);
|
||||
}
|
||||
mutexM.Unlock();
|
||||
processedM = true;
|
||||
processed = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@@ -8,9 +8,6 @@
|
||||
#ifndef __SATIP_SECTIONFILTER_H
|
||||
#define __SATIP_SECTIONFILTER_H
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/socket.h>
|
||||
#endif // __FreeBSD__
|
||||
#include <vdr/device.h>
|
||||
|
||||
#include "common.h"
|
||||
@@ -18,10 +15,11 @@
|
||||
|
||||
class cSatipSectionFilter : public cSatipSectionStatistics {
|
||||
private:
|
||||
enum dmx_limits {
|
||||
DMX_MAX_FILTER_SIZE = 18,
|
||||
DMX_MAX_SECTION_SIZE = 4096,
|
||||
DMX_MAX_SECFEED_SIZE = (DMX_MAX_SECTION_SIZE + TS_SIZE)
|
||||
enum {
|
||||
eDmxMaxFilterSize = 18,
|
||||
eDmxMaxSectionCount = 64,
|
||||
eDmxMaxSectionSize = 4096,
|
||||
eDmxMaxSectionFeedSize = (eDmxMaxSectionSize + TS_SIZE)
|
||||
};
|
||||
|
||||
int pusiSeenM;
|
||||
@@ -29,21 +27,22 @@ private:
|
||||
int doneqM;
|
||||
|
||||
uint8_t *secBufM;
|
||||
uint8_t secBufBaseM[DMX_MAX_SECFEED_SIZE];
|
||||
uint8_t secBufBaseM[eDmxMaxSectionFeedSize];
|
||||
uint16_t secBufpM;
|
||||
uint16_t secLenM;
|
||||
uint16_t tsFeedpM;
|
||||
uint16_t pidM;
|
||||
|
||||
cRingBufferFrame *ringBufferM;
|
||||
int deviceIndexM;
|
||||
int socketM[2];
|
||||
|
||||
uint8_t filterValueM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t filterMaskM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t filterModeM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t filterValueM[eDmxMaxFilterSize];
|
||||
uint8_t filterMaskM[eDmxMaxFilterSize];
|
||||
uint8_t filterModeM[eDmxMaxFilterSize];
|
||||
|
||||
uint8_t maskAndModeM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t maskAndNotModeM[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t maskAndModeM[eDmxMaxFilterSize];
|
||||
uint8_t maskAndNotModeM[eDmxMaxFilterSize];
|
||||
|
||||
inline uint16_t GetLength(const uint8_t *dataP);
|
||||
void New(void);
|
||||
@@ -56,6 +55,7 @@ public:
|
||||
cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_t tidP, uint8_t maskP);
|
||||
virtual ~cSatipSectionFilter();
|
||||
void Process(const uint8_t* dataP);
|
||||
bool Send(void);
|
||||
int GetFd(void) { return socketM[0]; }
|
||||
uint16_t GetPid(void) const { return pidM; }
|
||||
};
|
||||
@@ -65,10 +65,9 @@ private:
|
||||
enum {
|
||||
eMaxSecFilterCount = 32
|
||||
};
|
||||
cRingBufferLinear *ringBufferM;
|
||||
cMutex mutexM;
|
||||
int deviceIndexM;
|
||||
bool processedM;
|
||||
cRingBufferLinear *ringBufferM;
|
||||
cSatipSectionFilter *filtersM[eMaxSecFilterCount];
|
||||
|
||||
bool Delete(unsigned int indexP);
|
||||
@@ -80,7 +79,6 @@ protected:
|
||||
public:
|
||||
cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP);
|
||||
virtual ~cSatipSectionFilterHandler();
|
||||
bool Stop(void);
|
||||
cString GetInformation(void);
|
||||
int Open(u_short pidP, u_char tidP, u_char maskP);
|
||||
void Close(int handleP);
|
||||
|
177
server.c
Normal file
177
server.c
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* server.c: SAT>IP plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <vdr/sources.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "server.h"
|
||||
|
||||
// --- cSatipServer -----------------------------------------------------------
|
||||
|
||||
cSatipServer::cSatipServer(const char *addressP, const char *descriptionP, const char *modelP)
|
||||
: addressM(addressP),
|
||||
descriptionM(descriptionP),
|
||||
modelM(modelP),
|
||||
modelTypeM(eSatipModelTypeMask),
|
||||
useCountM(0),
|
||||
createdM(time(NULL)),
|
||||
lastSeenM(0)
|
||||
{
|
||||
memset(modelCountM, 0, sizeof(modelCountM));
|
||||
if (isempty(*modelM))
|
||||
modelM = "DVBS-1";
|
||||
char *s, *p = strdup(*modelM);
|
||||
char *r = strtok_r(p, ",", &s);
|
||||
while (r) {
|
||||
if (strstr(r, "DVBS2")) {
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBS2;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipModuleDVBS2] = atoi(++c);
|
||||
else
|
||||
modelCountM[eSatipModuleDVBS2] = 1;
|
||||
}
|
||||
if (strstr(r, "DVBT2")) {
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBT | cSatipServer::eSatipModelTypeDVBT2;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipModuleDVBT2] = atoi(++c);
|
||||
else
|
||||
modelCountM[eSatipModuleDVBT2] = 1;
|
||||
// Add model quirks here
|
||||
if (strstr(*addressM, "OctopusNet"))
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBC;
|
||||
}
|
||||
if (strstr(r, "DVBT")) {
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBT;
|
||||
if (char *c = strstr(r, "-"))
|
||||
modelCountM[eSatipModuleDVBT] = atoi(++c);
|
||||
else
|
||||
modelCountM[eSatipModuleDVBT] = 1;
|
||||
// Add model quirks here
|
||||
if (strstr(*addressM, "OctopusNet"))
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBC;
|
||||
}
|
||||
r = strtok_r(NULL, ",", &s);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
cSatipServer::~cSatipServer()
|
||||
{
|
||||
}
|
||||
|
||||
int cSatipServer::Compare(const cListObject &listObjectP) const
|
||||
{
|
||||
const cSatipServer *s = (const cSatipServer *)&listObjectP;
|
||||
return strcasecmp(*addressM, *s->addressM);
|
||||
}
|
||||
|
||||
void cSatipServer::Use(bool onOffP)
|
||||
{
|
||||
if (onOffP)
|
||||
++useCountM;
|
||||
else
|
||||
--useCountM;
|
||||
}
|
||||
|
||||
// --- cSatipServers ----------------------------------------------------------
|
||||
|
||||
cSatipServer *cSatipServers::Find(cSatipServer *serverP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP)
|
||||
return s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cSatipServer *cSatipServers::Find(int sourceP, int systemP)
|
||||
{
|
||||
cSatipServer *result = NULL;
|
||||
int model = 0;
|
||||
if (cSource::IsType(sourceP, 'S'))
|
||||
model |= cSatipServer::eSatipModelTypeDVBS2;
|
||||
else if (cSource::IsType(sourceP, 'T')) {
|
||||
if (systemP < 0)
|
||||
model |= cSatipServer::eSatipModelTypeDVBT2 | cSatipServer::eSatipModelTypeDVBT;
|
||||
else
|
||||
model |= systemP ? cSatipServer::eSatipModelTypeDVBT2 : cSatipServer::eSatipModelTypeDVBT;
|
||||
}
|
||||
else if (cSource::IsType(sourceP, 'C'))
|
||||
model |= cSatipServer::eSatipModelTypeDVBC;
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s->Match(model)) {
|
||||
result = s;
|
||||
if (!s->Used()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
cSatipServer *cSatipServers::Update(cSatipServer *serverP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s->Compare(*serverP) == 0) {
|
||||
s->Update();
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void cSatipServers::Use(cSatipServer *serverP, bool onOffP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP) {
|
||||
s->Use(onOffP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cSatipServers::Cleanup(uint64_t intervalMsP)
|
||||
{
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (!intervalMsP || (s->LastSeen() > intervalMsP)) {
|
||||
info("Removing device %s (%s %s)", s->Description(), s->Address(), s->Model());
|
||||
Del(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cString cSatipServers::GetString(cSatipServer *serverP)
|
||||
{
|
||||
cString list = "";
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP) {
|
||||
list = cString::sprintf("%s|%s|%s", s->Address(), s->Model(), s->Description());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
cString cSatipServers::List(void)
|
||||
{
|
||||
cString list = "";
|
||||
for (cSatipServer *s = First(); s; s = Next(s))
|
||||
list = cString::sprintf("%s%s|%s|%s\n", *list, s->Address(), s->Model(), s->Description());
|
||||
return list;
|
||||
}
|
||||
|
||||
int cSatipServers::NumProvidedSystems(void)
|
||||
{
|
||||
int count = 0;
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
// DVB-S*: qpsk, 8psk
|
||||
count += s->Satellite() * 4;
|
||||
// DVB-T*: qpsk, qam16, qam64, qam256
|
||||
count += (s->Terrestrial2() ? s->Terrestrial2() : s->Terrestrial()) * 4;
|
||||
}
|
||||
return count;
|
||||
}
|
71
server.h
Normal file
71
server.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* server.h: SAT>IP plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SATIP_SERVER_H
|
||||
#define __SATIP_SERVER_H
|
||||
|
||||
// --- cSatipServer -----------------------------------------------------------
|
||||
|
||||
class cSatipServer : public cListObject {
|
||||
private:
|
||||
enum eSatipModule {
|
||||
eSatipModuleDVBS2 = 0,
|
||||
eSatipModuleDVBT,
|
||||
eSatipModuleDVBT2,
|
||||
eSatipModuleCount
|
||||
};
|
||||
cString addressM;
|
||||
cString descriptionM;
|
||||
cString modelM;
|
||||
int modelCountM[eSatipModuleCount];
|
||||
int modelTypeM;
|
||||
int useCountM;
|
||||
time_t createdM;
|
||||
cTimeMs lastSeenM;
|
||||
|
||||
public:
|
||||
enum eSatipModelType {
|
||||
eSatipModelTypeDVBS2 = 0x01,
|
||||
eSatipModelTypeDVBT = 0x02,
|
||||
eSatipModelTypeDVBT2 = 0x04,
|
||||
eSatipModelTypeDVBC = 0x08,
|
||||
eSatipModelTypeMask = 0x0F
|
||||
};
|
||||
cSatipServer(const char *addressP, const char *descriptionP, const char *modelP);
|
||||
virtual ~cSatipServer();
|
||||
virtual int Compare(const cListObject &listObjectP) const;
|
||||
void Use(bool onOffP);
|
||||
bool Used(void) { return !!useCountM; }
|
||||
const char *Description() { return *descriptionM; }
|
||||
const char *Address() { return *addressM; }
|
||||
const char *Model(void) { return modelM; }
|
||||
int ModelType(void) { return modelTypeM; }
|
||||
bool Match(int modelP) { return ((modelP & eSatipModelTypeMask) & modelTypeM); }
|
||||
int Cable() { return Match(eSatipModelTypeDVBC) ? (Match(eSatipModelTypeDVBT2) ? modelCountM[eSatipModuleDVBT2] : modelCountM[eSatipModuleDVBT]) : 0; } // an ugly hack
|
||||
int Satellite() { return Match(eSatipModelTypeDVBS2) ? modelCountM[eSatipModuleDVBS2] : 0; }
|
||||
int Terrestrial() { return Match(eSatipModelTypeDVBT) ? modelCountM[eSatipModuleDVBT] : 0; }
|
||||
int Terrestrial2() { return Match(eSatipModelTypeDVBT2) ? modelCountM[eSatipModuleDVBT2] : 0; }
|
||||
void Update(void) { lastSeenM.Set(); }
|
||||
uint64_t LastSeen(void) { return lastSeenM.Elapsed(); }
|
||||
time_t Created(void) { return createdM; }
|
||||
};
|
||||
|
||||
// --- cSatipServers ----------------------------------------------------------
|
||||
|
||||
class cSatipServers : public cList<cSatipServer> {
|
||||
public:
|
||||
cSatipServer *Find(cSatipServer *serverP);
|
||||
cSatipServer *Find(int sourceP, int systemP);
|
||||
cSatipServer *Update(cSatipServer *serverP);
|
||||
void Use(cSatipServer *serverP, bool onOffP);
|
||||
void Cleanup(uint64_t intervalMsP = 0);
|
||||
cString GetString(cSatipServer *serverP);
|
||||
cString List(void);
|
||||
int NumProvidedSystems(void);
|
||||
};
|
||||
|
||||
#endif // __SATIP_SERVER_H
|
118
setup.c
118
setup.c
@@ -14,68 +14,61 @@
|
||||
#include "discover.h"
|
||||
#include "setup.h"
|
||||
|
||||
// --- cSatipMenuScan ---------------------------------------------------------
|
||||
// --- cSatipServerInfo -------------------------------------------------------
|
||||
|
||||
class cSatipMenuScan : public cOsdMenu
|
||||
class cSatipServerInfo : public cOsdMenu
|
||||
{
|
||||
private:
|
||||
enum {
|
||||
INFO_TIMEOUT_MS = 2000
|
||||
};
|
||||
cString textM;
|
||||
cTimeMs timeoutM;
|
||||
cString addressM;
|
||||
cString modelM;
|
||||
cString descriptionM;
|
||||
uint64_t createdM;
|
||||
void Setup(void);
|
||||
|
||||
public:
|
||||
cSatipMenuScan(cSatipServer *serverP);
|
||||
virtual ~cSatipMenuScan();
|
||||
virtual void Display(void);
|
||||
cSatipServerInfo(cSatipServer *serverP);
|
||||
virtual ~cSatipServerInfo();
|
||||
virtual eOSState ProcessKey(eKeys keyP);
|
||||
};
|
||||
|
||||
cSatipMenuScan::cSatipMenuScan(cSatipServer *serverP)
|
||||
: cOsdMenu(tr("SAT>IP Device")),
|
||||
textM("")
|
||||
cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP)
|
||||
: cOsdMenu(tr("SAT>IP Device"), 20),
|
||||
addressM(serverP ? serverP->Address() : "---"),
|
||||
modelM(serverP ? serverP->Model() : "---"),
|
||||
descriptionM(serverP ? serverP->Description() : "---"),
|
||||
createdM(serverP ? serverP->Created() : 0)
|
||||
{
|
||||
SetMenuCategory(mcText);
|
||||
if (serverP) {
|
||||
if (serverP->Model())
|
||||
textM = cString::sprintf("%s\nModel:\t%s", *textM, serverP->Model());
|
||||
if (serverP->Address())
|
||||
textM = cString::sprintf("%s\nAddress:\t%s", *textM, serverP->Address());
|
||||
if (serverP->Description())
|
||||
textM = cString::sprintf("%s\nDescription:\t%s", *textM, serverP->Description());
|
||||
}
|
||||
SetHelp(tr("Button$Scan"), NULL, NULL, NULL);
|
||||
SetMenuCategory(mcSetupPlugins);
|
||||
Setup();
|
||||
SetHelp(NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
cSatipMenuScan::~cSatipMenuScan()
|
||||
cSatipServerInfo::~cSatipServerInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void cSatipMenuScan::Display(void)
|
||||
void cSatipServerInfo::Setup(void)
|
||||
{
|
||||
cOsdMenu::Display();
|
||||
DisplayMenu()->SetText(textM, true);
|
||||
if (*textM)
|
||||
cStatus::MsgOsdTextItem(textM);
|
||||
Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Address"), *addressM), osUnknown, false));
|
||||
Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Model"), *modelM), osUnknown, false));
|
||||
Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Description"), *descriptionM), osUnknown, false));
|
||||
Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Creation date"), *DayDateTime(createdM)), osUnknown, false));
|
||||
}
|
||||
|
||||
eOSState cSatipMenuScan::ProcessKey(eKeys keyP)
|
||||
eOSState cSatipServerInfo::ProcessKey(eKeys keyP)
|
||||
{
|
||||
eOSState state = cOsdMenu::ProcessKey(keyP);
|
||||
|
||||
if (state == osUnknown) {
|
||||
switch (keyP) {
|
||||
case kOk: return osBack;
|
||||
case kRed:
|
||||
default: state = osContinue;
|
||||
break;
|
||||
case kOk: state = osBack; break;
|
||||
default: state = osContinue; break;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
// --- cSatipMenuInfo ---------------------------------------------------------
|
||||
// --- cSatipServerItem -------------------------------------------------------
|
||||
|
||||
class cSatipServerItem : public cOsdItem {
|
||||
private:
|
||||
@@ -107,7 +100,7 @@ class cSatipMenuInfo : public cOsdMenu
|
||||
{
|
||||
private:
|
||||
enum {
|
||||
INFO_TIMEOUT_MS = 2000
|
||||
eInfoTimeoutMs = 2000
|
||||
};
|
||||
cString textM;
|
||||
cTimeMs timeoutM;
|
||||
@@ -128,7 +121,7 @@ cSatipMenuInfo::cSatipMenuInfo()
|
||||
pageM(SATIP_DEVICE_INFO_GENERAL)
|
||||
{
|
||||
SetMenuCategory(mcText);
|
||||
timeoutM.Set(INFO_TIMEOUT_MS);
|
||||
timeoutM.Set(eInfoTimeoutMs);
|
||||
UpdateInfo();
|
||||
SetHelp(tr("General"), tr("Pids"), tr("Filters"), tr("Bits/bytes"));
|
||||
}
|
||||
@@ -145,7 +138,7 @@ void cSatipMenuInfo::UpdateInfo()
|
||||
else
|
||||
textM = cString(tr("SAT>IP information not available!"));
|
||||
Display();
|
||||
timeoutM.Set(INFO_TIMEOUT_MS);
|
||||
timeoutM.Set(eInfoTimeoutMs);
|
||||
}
|
||||
|
||||
void cSatipMenuInfo::Display(void)
|
||||
@@ -203,10 +196,15 @@ eOSState cSatipMenuInfo::ProcessKey(eKeys keyP)
|
||||
|
||||
cSatipPluginSetup::cSatipPluginSetup()
|
||||
: deviceCountM(0),
|
||||
operatingModeM(SatipConfig.GetOperatingMode()),
|
||||
eitScanM(SatipConfig.GetEITScan()),
|
||||
numDisabledFiltersM(SatipConfig.GetDisabledFiltersCount())
|
||||
{
|
||||
debug("cSatipPluginSetup::%s()", __FUNCTION__);
|
||||
operatingModeTextsM[cSatipConfig::eOperatingModeOff] = tr("off");
|
||||
operatingModeTextsM[cSatipConfig::eOperatingModeLow] = tr("low");
|
||||
operatingModeTextsM[cSatipConfig::eOperatingModeNormal] = tr("normal");
|
||||
operatingModeTextsM[cSatipConfig::eOperatingModeHigh] = tr("high");
|
||||
if (numDisabledFiltersM > SECTION_FILTER_TABLE_SIZE)
|
||||
numDisabledFiltersM = SECTION_FILTER_TABLE_SIZE;
|
||||
for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i) {
|
||||
@@ -215,7 +213,7 @@ cSatipPluginSetup::cSatipPluginSetup()
|
||||
}
|
||||
SetMenuCategory(mcSetupPlugins);
|
||||
Setup();
|
||||
SetHelp(NULL, NULL, NULL, trVDR("Button$Info"));
|
||||
SetHelp(trVDR("Button$Scan"), NULL, NULL, trVDR("Button$Info"));
|
||||
}
|
||||
|
||||
void cSatipPluginSetup::Setup(void)
|
||||
@@ -225,17 +223,21 @@ void cSatipPluginSetup::Setup(void)
|
||||
Clear();
|
||||
helpM.Clear();
|
||||
|
||||
Add(new cMenuEditBoolItem(tr("Enable EPG scanning"), &eitScanM));
|
||||
helpM.Append(tr("Define whether the EPG background scanning shall be used.\n\nThis setting disables the automatic EIT scanning functionality for all SAT>IP devices."));
|
||||
Add(new cMenuEditStraItem(tr("Operating mode"), &operatingModeM, ELEMENTS(operatingModeTextsM), operatingModeTextsM));
|
||||
helpM.Append(tr("Define the used operating mode for all SAT>IP devices:\n\noff - devices are disabled\nlow - devices are working at the lowest priority\nnormal - devices are working within normal parameters\nhigh - devices are working at the highest priority"));
|
||||
|
||||
Add(new cMenuEditIntItem(tr("Disabled filters"), &numDisabledFiltersM, 0, SECTION_FILTER_TABLE_SIZE, tr("none")));
|
||||
helpM.Append(tr("Define number of section filters to be disabled.\n\nCertain section filters might cause some unwanted behaviour to VDR such as time being falsely synchronized. By black-listing the filters here useful section data can be left intact for VDR to process."));
|
||||
if (operatingModeM) {
|
||||
Add(new cMenuEditBoolItem(tr("Enable EPG scanning"), &eitScanM));
|
||||
helpM.Append(tr("Define whether the EPG background scanning shall be used.\n\nThis setting disables the automatic EIT scanning functionality for all SAT>IP devices."));
|
||||
|
||||
for (int i = 0; i < numDisabledFiltersM; ++i) {
|
||||
Add(new cMenuEditStraItem(*cString::sprintf(" %s %d", tr("Filter"), i + 1), &disabledFilterIndexesM[i], SECTION_FILTER_TABLE_SIZE, disabledFilterNamesM));
|
||||
helpM.Append(tr("Define an ill-behaving filter to be blacklisted."));
|
||||
}
|
||||
Add(new cMenuEditIntItem(tr("Disabled filters"), &numDisabledFiltersM, 0, SECTION_FILTER_TABLE_SIZE, tr("none")));
|
||||
helpM.Append(tr("Define number of section filters to be disabled.\n\nCertain section filters might cause some unwanted behaviour to VDR such as time being falsely synchronized. By black-listing the filters here useful section data can be left intact for VDR to process."));
|
||||
|
||||
for (int i = 0; i < numDisabledFiltersM; ++i) {
|
||||
Add(new cMenuEditStraItem(*cString::sprintf(" %s %d", tr("Filter"), i + 1), &disabledFilterIndexesM[i], SECTION_FILTER_TABLE_SIZE, disabledFilterNamesM));
|
||||
helpM.Append(tr("Define an ill-behaving filter to be blacklisted."));
|
||||
}
|
||||
}
|
||||
Add(new cOsdItem(tr("Active SAT>IP devices:"), osUnknown, false));
|
||||
helpM.Append("");
|
||||
|
||||
@@ -250,15 +252,23 @@ void cSatipPluginSetup::Setup(void)
|
||||
Display();
|
||||
}
|
||||
|
||||
eOSState cSatipPluginSetup::ChannelScan(void)
|
||||
eOSState cSatipPluginSetup::DeviceScan(void)
|
||||
{
|
||||
debug("cSatipPluginSetup::%s()", __FUNCTION__);
|
||||
cSatipDiscover::GetInstance()->TriggerScan();
|
||||
|
||||
return osContinue;
|
||||
}
|
||||
|
||||
eOSState cSatipPluginSetup::DeviceInfo(void)
|
||||
{
|
||||
debug("cSatipPluginSetup::%s()", __FUNCTION__);
|
||||
if (HasSubMenu() || Count() == 0)
|
||||
return osContinue;
|
||||
|
||||
cSatipServerItem *item = reinterpret_cast<cSatipServerItem *>(Get(Current()));
|
||||
if (item && cSatipDiscover::GetInstance()->IsValidServer(item->Server()))
|
||||
return AddSubMenu(new cSatipMenuScan(item->Server()));
|
||||
if (item && !!cSatipDiscover::GetInstance()->GetServer(item->Server()))
|
||||
return AddSubMenu(new cSatipServerInfo(item->Server()));
|
||||
|
||||
return osContinue;
|
||||
}
|
||||
@@ -275,16 +285,18 @@ eOSState cSatipPluginSetup::ShowInfo(void)
|
||||
eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
|
||||
{
|
||||
bool hadSubMenu = HasSubMenu();
|
||||
int oldOperatingMode = operatingModeM;
|
||||
int oldNumDisabledFilters = numDisabledFiltersM;
|
||||
eOSState state = cMenuSetupPage::ProcessKey(keyP);
|
||||
|
||||
// Ugly hack with hardcoded '#' character :(
|
||||
const char *p = Get(Current())->Text();
|
||||
if (!hadSubMenu && !HasSubMenu() && (*p == '#') && (keyP == kOk))
|
||||
return ChannelScan();
|
||||
return DeviceInfo();
|
||||
|
||||
if (state == osUnknown) {
|
||||
switch (keyP) {
|
||||
case kRed: return DeviceScan();
|
||||
case kBlue: return ShowInfo();
|
||||
case kInfo: if (Current() < helpM.Size())
|
||||
return AddSubMenu(new cMenuText(cString::sprintf("%s - %s '%s'", tr("Help"), trVDR("Plugin"), PLUGIN_NAME_I18N), helpM[Current()]));
|
||||
@@ -295,7 +307,7 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
|
||||
if ((keyP == kNone) && (cSatipDiscover::GetInstance()->GetServers()->Count() != deviceCountM))
|
||||
Setup();
|
||||
|
||||
if ((keyP != kNone) && (numDisabledFiltersM != oldNumDisabledFilters)) {
|
||||
if ((keyP != kNone) && ((numDisabledFiltersM != oldNumDisabledFilters) || (operatingModeM != oldOperatingMode))) {
|
||||
while ((numDisabledFiltersM < oldNumDisabledFilters) && (oldNumDisabledFilters > 0))
|
||||
disabledFilterIndexesM[--oldNumDisabledFilters] = -1;
|
||||
Setup();
|
||||
@@ -326,9 +338,11 @@ void cSatipPluginSetup::StoreFilters(const char *nameP, int *valuesP)
|
||||
void cSatipPluginSetup::Store(void)
|
||||
{
|
||||
// Store values into setup.conf
|
||||
SetupStore("OperatingMode", operatingModeM);
|
||||
SetupStore("EnableEITScan", eitScanM);
|
||||
StoreFilters("DisabledFilters", disabledFilterIndexesM);
|
||||
// Update global config
|
||||
SatipConfig.SetOperatingMode(operatingModeM);
|
||||
SatipConfig.SetEITScan(eitScanM);
|
||||
for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i)
|
||||
SatipConfig.SetDisabledFilters(i, disabledFilterIndexesM[i]);
|
||||
|
5
setup.h
5
setup.h
@@ -16,13 +16,16 @@ class cSatipPluginSetup : public cMenuSetupPage
|
||||
{
|
||||
private:
|
||||
int deviceCountM;
|
||||
int operatingModeM;
|
||||
const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
|
||||
int eitScanM;
|
||||
int numDisabledFiltersM;
|
||||
int disabledFilterIndexesM[SECTION_FILTER_TABLE_SIZE];
|
||||
const char *disabledFilterNamesM[SECTION_FILTER_TABLE_SIZE];
|
||||
cVector<const char*> helpM;
|
||||
|
||||
eOSState ChannelScan(void);
|
||||
eOSState DeviceScan(void);
|
||||
eOSState DeviceInfo(void);
|
||||
eOSState ShowInfo(void);
|
||||
void Setup(void);
|
||||
void StoreFilters(const char *nameP, int *valuesP);
|
||||
|
26
socket.c
26
socket.c
@@ -20,7 +20,10 @@
|
||||
|
||||
cSatipSocket::cSatipSocket()
|
||||
: socketPortM(0),
|
||||
socketDescM(-1)
|
||||
socketDescM(-1),
|
||||
lastErrorReportM(0),
|
||||
packetErrorsM(0),
|
||||
sequenceNumberM(-1)
|
||||
{
|
||||
debug("cSatipSocket::%s()", __FUNCTION__);
|
||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||
@@ -72,8 +75,14 @@ void cSatipSocket::Close(void)
|
||||
close(socketDescM);
|
||||
socketDescM = -1;
|
||||
socketPortM = 0;
|
||||
sequenceNumberM = -1;
|
||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||
}
|
||||
if (packetErrorsM) {
|
||||
info("detected %d RTP packet errors", packetErrorsM);
|
||||
packetErrorsM = 0;
|
||||
lastErrorReportM = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool cSatipSocket::Flush(void)
|
||||
@@ -150,6 +159,21 @@ int cSatipSocket::ReadVideo(unsigned char *bufferAddrP, unsigned int bufferLenP)
|
||||
unsigned int cc = bufferAddrP[0] & 0x0F;
|
||||
// Payload type: MPEG2 TS = 33
|
||||
//unsigned int pt = bufferAddrP[1] & 0x7F;
|
||||
// Sequence number
|
||||
int seq = ((bufferAddrP[2] & 0xFF) << 8) | (bufferAddrP[3] & 0xFF);
|
||||
if ((((sequenceNumberM + 1) % 0xFFFF) == 0) && (seq == 0xFFFF))
|
||||
sequenceNumberM = -1;
|
||||
else if ((sequenceNumberM >= 0) && (((sequenceNumberM + 1) % 0xFFFF) != seq)) {
|
||||
packetErrorsM++;
|
||||
if (time(NULL) - lastErrorReportM > eReportIntervalS) {
|
||||
info("detected %d RTP packet errors", packetErrorsM);
|
||||
packetErrorsM = 0;
|
||||
lastErrorReportM = time(NULL);
|
||||
}
|
||||
sequenceNumberM = seq;
|
||||
}
|
||||
else
|
||||
sequenceNumberM = seq;
|
||||
// Header lenght
|
||||
unsigned int headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t);
|
||||
// Check if extension
|
||||
|
6
socket.h
6
socket.h
@@ -12,9 +12,15 @@
|
||||
|
||||
class cSatipSocket {
|
||||
private:
|
||||
enum {
|
||||
eReportIntervalS = 300 // in seconds
|
||||
};
|
||||
int socketPortM;
|
||||
int socketDescM;
|
||||
struct sockaddr_in sockAddrM;
|
||||
time_t lastErrorReportM;
|
||||
int packetErrorsM;
|
||||
int sequenceNumberM;
|
||||
|
||||
public:
|
||||
cSatipSocket();
|
||||
|
384
source.c
384
source.c
@@ -1,384 +0,0 @@
|
||||
/*
|
||||
* source.c: SAT>IP plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "common.h"
|
||||
#include "source.h"
|
||||
|
||||
// --- cSatipParameterMaps ----------------------------------------------------
|
||||
|
||||
static const tSatipParameterMap SatipBandwidthValues[] = {
|
||||
{ 5, "5 MHz", "bw=5" },
|
||||
{ 6, "6 MHz", "bw=6" },
|
||||
{ 7, "7 MHz", "bw=7" },
|
||||
{ 8, "8 MHz", "bw=8" },
|
||||
{ 10, "10 MHz", "bw=10" },
|
||||
{ 1712, "1.712 MHz", "bw=1.712" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipPilotTonesValues[] = {
|
||||
{ 0, trNOOP("off"), "plts=off" },
|
||||
{ 1, trNOOP("on"), "plts=on" },
|
||||
{ 999, trNOOP("auto"), "" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSisoMisoValues[] = {
|
||||
{ 0, trNOOP("SISO"), "sm=0" },
|
||||
{ 1, trNOOP("MISO"), "sm=1" },
|
||||
{ 999, trNOOP("auto"), "" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipCodeRateValues[] = {
|
||||
{ 0, trNOOP("none"), "" },
|
||||
{ 12, "1/2", "fec=12" },
|
||||
{ 23, "2/3", "fec=23" },
|
||||
{ 34, "3/4", "fec=34" },
|
||||
{ 35, "3/5", "fec=35" },
|
||||
{ 45, "4/5", "fec=45" },
|
||||
{ 56, "5/6", "fec=56" },
|
||||
{ 78, "7/8", "fec=78" },
|
||||
{ 89, "8/9", "fec=89" },
|
||||
{ 910, "9/10", "fec=910" },
|
||||
{ 999, trNOOP("auto"), "" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipModulationValues[] = {
|
||||
{ 2, "QPSK", "mtype=qpsk" },
|
||||
{ 5, "8PSK", "mtype=8psk" },
|
||||
{ 16, "QAM16", "mtype=16qam" },
|
||||
{ 64, "QAM64", "mtype=64qam" },
|
||||
{ 256, "QAM256", "mtype=256qam" },
|
||||
{ 999, trNOOP("auto"), "" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSystemValuesSat[] = {
|
||||
{ 0, "DVB-S", "msys=dvbs" },
|
||||
{ 1, "DVB-S2", "msys=dvbs2" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipSystemValuesTerr[] = {
|
||||
{ 0, "DVB-T", "msys=dvbt" },
|
||||
{ 1, "DVB-T2", "msys=dvbt2" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipTransmissionValues[] = {
|
||||
{ 1, "1K", "tmode=1k" },
|
||||
{ 2, "2K", "tmode=2k" },
|
||||
{ 4, "4K", "tmode=4k" },
|
||||
{ 8, "8K", "tmode=8k" },
|
||||
{ 16, "16K", "tmode=16k" },
|
||||
{ 32, "32K", "tmode=32k" },
|
||||
{ 999, trNOOP("auto"), "" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipGuardValues[] = {
|
||||
{ 4, "1/4", "gi=14" },
|
||||
{ 8, "1/8", "gi=18" },
|
||||
{ 16, "1/16", "gi=116" },
|
||||
{ 32, "1/32", "gi=132" },
|
||||
{ 128, "1/128", "gi=1128" },
|
||||
{ 19128, "19/128", "gi=19128" },
|
||||
{ 19256, "19/256", "gi=19256" },
|
||||
{ 999, trNOOP("auto"), "" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const tSatipParameterMap SatipRollOffValues[] = {
|
||||
{ 0, trNOOP("auto"), "" },
|
||||
{ 20, "0.20", "ro=0.20" },
|
||||
{ 25, "0.25", "ro=0.25" },
|
||||
{ 35, "0.35", "ro=0.35" },
|
||||
{ -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static int SatipUserIndex(int valueP, const tSatipParameterMap *mapP)
|
||||
{
|
||||
const tSatipParameterMap *map = mapP;
|
||||
while (map && map->userValue != -1) {
|
||||
if (map->userValue == valueP)
|
||||
return map - mapP;
|
||||
map++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int SatipMapToUser(int valueP, const tSatipParameterMap *mapP, const char **strP)
|
||||
{
|
||||
int n = SatipUserIndex(valueP, mapP);
|
||||
if (n >= 0) {
|
||||
if (strP)
|
||||
*strP = tr(mapP[n].userString);
|
||||
return mapP[n].userValue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// --- cMenuEditSatipItem -----------------------------------------------------
|
||||
|
||||
class cMenuEditSatipItem : public cMenuEditItem {
|
||||
protected:
|
||||
int *valueM;
|
||||
const tSatipParameterMap *mapM;
|
||||
const char *zeroStringM;
|
||||
virtual void Set(void);
|
||||
|
||||
public:
|
||||
cMenuEditSatipItem(const char *nameP, int *valueP, const tSatipParameterMap *mapP, const char *zeroStringP = NULL);
|
||||
virtual eOSState ProcessKey(eKeys keyP);
|
||||
};
|
||||
|
||||
cMenuEditSatipItem::cMenuEditSatipItem(const char *nameP, int *valueP, const tSatipParameterMap *mapP, const char *zeroStringP)
|
||||
: cMenuEditItem(nameP)
|
||||
{
|
||||
valueM = valueP;
|
||||
mapM = mapP;
|
||||
zeroStringM = zeroStringP;
|
||||
Set();
|
||||
}
|
||||
|
||||
void cMenuEditSatipItem::Set(void)
|
||||
{
|
||||
const char *s = NULL;
|
||||
int n = SatipMapToUser(*valueM, mapM, &s);
|
||||
if (n == 0 && zeroStringM)
|
||||
SetValue(zeroStringM);
|
||||
else if (n >= 0) {
|
||||
if (s)
|
||||
SetValue(s);
|
||||
else {
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "%d", n);
|
||||
SetValue(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
SetValue("???");
|
||||
}
|
||||
|
||||
eOSState cMenuEditSatipItem::ProcessKey(eKeys keyP)
|
||||
{
|
||||
eOSState state = cMenuEditItem::ProcessKey(keyP);
|
||||
|
||||
if (state == osUnknown) {
|
||||
int newValue = *valueM;
|
||||
int n = SatipUserIndex(*valueM, mapM);
|
||||
if (NORMALKEY(keyP) == kLeft) { // TODO might want to increase the delta if repeated quickly?
|
||||
if (n-- > 0)
|
||||
newValue = mapM[n].userValue;
|
||||
}
|
||||
else if (NORMALKEY(keyP) == kRight) {
|
||||
if (mapM[++n].userValue >= 0)
|
||||
newValue = mapM[n].userValue;
|
||||
}
|
||||
else
|
||||
return state;
|
||||
if (newValue != *valueM) {
|
||||
*valueM = newValue;
|
||||
Set();
|
||||
}
|
||||
state = osContinue;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
// --- cSatipTransponderParameters --------------------------------------------
|
||||
|
||||
cSatipTransponderParameters::cSatipTransponderParameters(const char *parametersP)
|
||||
: polarizationM('H'),
|
||||
bandwidthM(8),
|
||||
coderateHM(0),
|
||||
systemM(0),
|
||||
modulationM(999),
|
||||
transmissionM(8),
|
||||
guardM(999),
|
||||
rollOffM(0),
|
||||
streamIdM(0),
|
||||
t2SystemIdM(0),
|
||||
sisoMisoM(999),
|
||||
pilotTonesM(0),
|
||||
signalSourceM(1)
|
||||
{
|
||||
Parse(parametersP);
|
||||
}
|
||||
|
||||
int cSatipTransponderParameters::PrintParameter(char *ptrP, char nameP, int valueP) const
|
||||
{
|
||||
return (valueP >= 0 && valueP != 999) ? sprintf(ptrP, "%c%d", nameP, valueP) : 0;
|
||||
}
|
||||
|
||||
int cSatipTransponderParameters::PrintString(char *ptrP, int valueP, const tSatipParameterMap *mapP)
|
||||
{
|
||||
int n = SatipUserIndex(valueP, mapP);
|
||||
return (n >= 0) ? sprintf(ptrP, "&%s", tr(mapP[n].satipString)) : 0;
|
||||
}
|
||||
|
||||
cString cSatipTransponderParameters::UrlParameters(char typeP)
|
||||
{
|
||||
char buffer[255];
|
||||
char *q = buffer;
|
||||
*q = 0;
|
||||
#define ST(s) if (strchr(s, typeP) && (strchr(s, '0' + systemM + 1) || strchr(s, '*')))
|
||||
ST("Z *") q += sprintf(q, "&src=%d", signalSourceM);
|
||||
ST("Z *") q += sprintf(q, "&pol=%c", tolower(polarizationM));
|
||||
ST(" Y2") q += sprintf(q, "&plp=%d", streamIdM);
|
||||
ST(" Y2") q += sprintf(q, "&t2id=%d", t2SystemIdM);
|
||||
ST(" Y*") q += PrintString(q, bandwidthM, SatipBandwidthValues);
|
||||
ST(" Y*") q += PrintString(q, guardM, SatipGuardValues);
|
||||
ST("ZY*") q += PrintString(q, coderateHM, SatipCodeRateValues);
|
||||
ST("Z 2") q += PrintString(q, pilotTonesM, SatipPilotTonesValues);
|
||||
ST("Z 2") q += PrintString(q, modulationM, SatipModulationValues);
|
||||
ST(" Y*") q += PrintString(q, modulationM, SatipModulationValues);
|
||||
ST("Z 2") q += PrintString(q, rollOffM, SatipRollOffValues);
|
||||
ST("Z *") q += PrintString(q, systemM, SatipSystemValuesSat);
|
||||
ST(" Y*") q += PrintString(q, systemM, SatipSystemValuesTerr);
|
||||
ST(" Y*") q += PrintString(q, transmissionM, SatipTransmissionValues);
|
||||
ST(" Y2") q += PrintString(q, sisoMisoM, SatipSisoMisoValues);
|
||||
#undef ST
|
||||
return buffer;
|
||||
}
|
||||
|
||||
cString cSatipTransponderParameters::ToString(char typeP) const
|
||||
{
|
||||
char buffer[64];
|
||||
char *q = buffer;
|
||||
*q = 0;
|
||||
#define ST(s) if (strchr(s, typeP) && (strchr(s, '0' + systemM + 1) || strchr(s, '*')))
|
||||
ST("Z *") q += sprintf(q, "%c", polarizationM);
|
||||
ST(" Y*") q += PrintParameter(q, 'B', bandwidthM);
|
||||
ST("ZY*") q += PrintParameter(q, 'C', coderateHM);
|
||||
ST(" Y*") q += PrintParameter(q, 'G', guardM);
|
||||
ST("Z 2") q += PrintParameter(q, 'M', modulationM);
|
||||
ST(" Y*") q += PrintParameter(q, 'M', modulationM);
|
||||
ST("Z 2") q += PrintParameter(q, 'N', pilotTonesM);
|
||||
ST("Z 2") q += PrintParameter(q, 'O', rollOffM);
|
||||
ST(" Y2") q += PrintParameter(q, 'P', streamIdM);
|
||||
ST(" Y2") q += PrintParameter(q, 'Q', t2SystemIdM);
|
||||
ST("ZY*") q += PrintParameter(q, 'S', systemM);
|
||||
ST(" Y*") q += PrintParameter(q, 'T', transmissionM);
|
||||
ST(" Y2") q += PrintParameter(q, 'X', sisoMisoM);
|
||||
ST("Z *") q += PrintParameter(q, 'Z', signalSourceM);
|
||||
#undef ST
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const char *cSatipTransponderParameters::ParseParameter(const char *strP, int &valueP)
|
||||
{
|
||||
if (*++strP) {
|
||||
char *p = NULL;
|
||||
errno = 0;
|
||||
int n = strtol(strP, &p, 10);
|
||||
if (!errno && p != strP) {
|
||||
valueP = n;
|
||||
if (valueP >= 0)
|
||||
return p;
|
||||
}
|
||||
}
|
||||
error("invalid value for parameter '%c'", *(strP - 1));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool cSatipTransponderParameters::Parse(const char *strP)
|
||||
{
|
||||
while (strP && *strP) {
|
||||
int ignoreThis;
|
||||
switch (toupper(*strP)) {
|
||||
case 'B': strP = ParseParameter(strP, bandwidthM); break;
|
||||
case 'C': strP = ParseParameter(strP, coderateHM); break;
|
||||
case 'G': strP = ParseParameter(strP, guardM); break;
|
||||
case 'H': polarizationM = 'H'; strP++; break;
|
||||
case 'L': polarizationM = 'L'; strP++; break;
|
||||
case 'M': strP = ParseParameter(strP, modulationM); break;
|
||||
case 'N': strP = ParseParameter(strP, pilotTonesM); break;
|
||||
case 'O': strP = ParseParameter(strP, rollOffM); break;
|
||||
case 'P': strP = ParseParameter(strP, streamIdM); break;
|
||||
case 'Q': strP = ParseParameter(strP, t2SystemIdM); break;
|
||||
case 'R': polarizationM = 'R'; strP++; break;
|
||||
case 'S': strP = ParseParameter(strP, systemM); break;
|
||||
case 'T': strP = ParseParameter(strP, transmissionM); break;
|
||||
case 'V': polarizationM = 'V'; strP++; break;
|
||||
case 'X': strP = ParseParameter(strP, sisoMisoM); break;
|
||||
case 'Z': strP = ParseParameter(strP, signalSourceM); break;
|
||||
case 'D': strP = ParseParameter(strP, ignoreThis); break; /* silently ignore coderate low priority */
|
||||
case 'I': strP = ParseParameter(strP, ignoreThis); break; /* silently ignore inversion */
|
||||
case 'Y': strP = ParseParameter(strP, ignoreThis); break; /* silently ignore hierarchy */
|
||||
default: esyslog("ERROR: unknown parameter key '%c'", *strP);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// --- cSatipSourceParam ------------------------------------------------------
|
||||
|
||||
cSatipSourceParam::cSatipSourceParam(char sourceP, const char *descriptionP)
|
||||
: cSourceParam(sourceP, descriptionP),
|
||||
paramM(0),
|
||||
nidM(0),
|
||||
tidM(0),
|
||||
ridM(0),
|
||||
srateM(0),
|
||||
dataM(),
|
||||
stpM()
|
||||
{
|
||||
debug("cSatipSourceParam::%s(%c, %s)", __FUNCTION__, sourceP, descriptionP);
|
||||
}
|
||||
|
||||
void cSatipSourceParam::SetData(cChannel *channelP)
|
||||
{
|
||||
debug("cSatipSourceParam::%s(%s)", __FUNCTION__, channelP->Parameters());
|
||||
dataM = *channelP;
|
||||
nidM = dataM.Nid();
|
||||
tidM = dataM.Tid();
|
||||
ridM = dataM.Rid();
|
||||
srateM = dataM.Srate();
|
||||
stpM.Parse(dataM.Parameters());
|
||||
paramM = 0;
|
||||
}
|
||||
|
||||
void cSatipSourceParam::GetData(cChannel *channelP)
|
||||
{
|
||||
debug("cSatipSourceParam::%s(%s)", __FUNCTION__, channelP->Parameters());
|
||||
channelP->SetTransponderData(channelP->Source(), channelP->Frequency(), srateM, stpM.ToString(Source()), true);
|
||||
channelP->SetId(nidM, tidM, channelP->Sid(), ridM);
|
||||
}
|
||||
|
||||
cOsdItem *cSatipSourceParam::GetOsdItem(void)
|
||||
{
|
||||
char type = Source();
|
||||
const tSatipParameterMap *SatipSystemValues = type == 'Z' ? SatipSystemValuesSat : SatipSystemValuesTerr;
|
||||
#define ST(s) if (strchr(s, type))
|
||||
switch (paramM++) {
|
||||
case 0: return new cMenuEditIntItem( tr("Nid"), &nidM, 0);
|
||||
case 1: return new cMenuEditIntItem( tr("Tid"), &tidM, 0);
|
||||
case 2: return new cMenuEditIntItem( tr("Rid"), &ridM, 0);
|
||||
case 3: ST("Z ") return new cMenuEditIntItem( trVDR("Srate"), &srateM); else return GetOsdItem();
|
||||
case 4: ST("Z ") return new cMenuEditIntItem( tr("SignalSource"), &stpM.signalSourceM, 1, 255); else return GetOsdItem();
|
||||
case 5: ST("Z ") return new cMenuEditChrItem( trVDR("Polarization"), &stpM.polarizationM, "HVLR"); else return GetOsdItem();
|
||||
case 6: ST("Z ") return new cMenuEditSatipItem(trVDR("Rolloff"), &stpM.rollOffM, SatipRollOffValues); else return GetOsdItem();
|
||||
case 7: ST("Z ") return new cMenuEditSatipItem( tr("PilotTones"), &stpM.pilotTonesM, SatipPilotTonesValues); else return GetOsdItem();
|
||||
case 8: ST("ZY") return new cMenuEditSatipItem(trVDR("System"), &stpM.systemM, SatipSystemValues); else return GetOsdItem();
|
||||
case 9: ST("ZY") return new cMenuEditSatipItem(trVDR("Modulation"), &stpM.modulationM, SatipModulationValues); else return GetOsdItem();
|
||||
case 10: ST("ZY") return new cMenuEditSatipItem(trVDR("CoderateH"), &stpM.coderateHM, SatipCodeRateValues); else return GetOsdItem();
|
||||
case 11: ST(" Y") return new cMenuEditSatipItem(trVDR("Bandwidth"), &stpM.bandwidthM, SatipBandwidthValues); else return GetOsdItem();
|
||||
case 12: ST(" Y") return new cMenuEditSatipItem(trVDR("Transmission"), &stpM.transmissionM, SatipTransmissionValues); else return GetOsdItem();
|
||||
case 13: ST(" Y") return new cMenuEditSatipItem(trVDR("Guard"), &stpM.guardM, SatipGuardValues); else return GetOsdItem();
|
||||
case 14: ST(" Y") return new cMenuEditIntItem( trVDR("StreamId"), &stpM.streamIdM, 0, 255); else return GetOsdItem();
|
||||
case 15: ST(" Y") return new cMenuEditIntItem( tr("T2SystemId"), &stpM.t2SystemIdM, 0, 65535); else return GetOsdItem();
|
||||
case 16: ST(" Y") return new cMenuEditSatipItem( tr("SISO/MISO"), &stpM.sisoMisoM, SatipSisoMisoValues); else return GetOsdItem();
|
||||
default: return NULL;
|
||||
}
|
||||
#undef ST
|
||||
return NULL;
|
||||
}
|
93
source.h
93
source.h
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* source.h: SAT>IP plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SATIP_SOURCE_H
|
||||
#define __SATIP_SOURCE_H
|
||||
|
||||
#include <vdr/menuitems.h>
|
||||
#include <vdr/sourceparams.h>
|
||||
#include "common.h"
|
||||
|
||||
struct tSatipParameterMap {
|
||||
int userValue;
|
||||
const char *userString;
|
||||
const char *satipString;
|
||||
};
|
||||
|
||||
class cSatipTransponderParameters {
|
||||
friend class cSatipSourceParam;
|
||||
|
||||
private:
|
||||
char polarizationM;
|
||||
int bandwidthM;
|
||||
int coderateHM;
|
||||
int systemM;
|
||||
int modulationM;
|
||||
int transmissionM;
|
||||
int guardM;
|
||||
int rollOffM;
|
||||
int streamIdM;
|
||||
int t2SystemIdM;
|
||||
int sisoMisoM;
|
||||
int pilotTonesM;
|
||||
int signalSourceM;
|
||||
int PrintParameter(char *ptrP, char nameP, int valueP) const;
|
||||
int PrintString(char *ptrP, int valueP, const tSatipParameterMap *mapP);
|
||||
const char *ParseParameter(const char *strP, int &valueP);
|
||||
|
||||
public:
|
||||
cSatipTransponderParameters(const char *parametersP = NULL);
|
||||
char Polarization(void) const { return polarizationM; }
|
||||
int Bandwidth(void) const { return bandwidthM; }
|
||||
int CoderateH(void) const { return coderateHM; }
|
||||
int System(void) const { return systemM; }
|
||||
int Modulation(void) const { return modulationM; }
|
||||
int Transmission(void) const { return transmissionM; }
|
||||
int Guard(void) const { return guardM; }
|
||||
int RollOff(void) const { return rollOffM; }
|
||||
int StreamId(void) const { return streamIdM; }
|
||||
int T2SystemId(void) const { return t2SystemIdM; }
|
||||
int SisoMiso(void) const { return sisoMisoM; }
|
||||
int PilotTones(void) const { return pilotTonesM; }
|
||||
int SignalSource(void) const { return signalSourceM; }
|
||||
void SetPolarization(char polarizationP) { polarizationM = polarizationP; }
|
||||
void SetBandwidth(int bandwidthP) { bandwidthM = bandwidthP; }
|
||||
void SetCoderateH(int coderateHP) { coderateHM = coderateHP; }
|
||||
void SetSystem(int systemP) { systemM = systemP; }
|
||||
void SetModulation(int modulationP) { modulationM = modulationP; }
|
||||
void SetTransmission(int transmissionP) { transmissionM = transmissionP; }
|
||||
void SetGuard(int guardP) { guardM = guardP; }
|
||||
void SetRollOff(int rollOffP) { rollOffM = rollOffP; }
|
||||
void SetStreamId(int streamIdP) { streamIdM = streamIdP; }
|
||||
void SetT2SystemId(int t2SystemIdP) { t2SystemIdM = t2SystemIdP; }
|
||||
void SetSisoMiso(int sisoMisoP) { sisoMisoM = sisoMisoP; }
|
||||
void SetPilotTones(int pilotTonesP) { pilotTonesM = pilotTonesP; }
|
||||
void SetSignalSource(int signalSourceP) { signalSourceM = signalSourceP; }
|
||||
cString UrlParameters(char typeP);
|
||||
cString ToString(char typeP) const;
|
||||
bool Parse(const char *strP);
|
||||
};
|
||||
|
||||
class cSatipSourceParam : public cSourceParam
|
||||
{
|
||||
private:
|
||||
int paramM;
|
||||
int nidM;
|
||||
int tidM;
|
||||
int ridM;
|
||||
int srateM;
|
||||
cChannel dataM;
|
||||
cSatipTransponderParameters stpM;
|
||||
|
||||
public:
|
||||
cSatipSourceParam(char sourceP, const char *descriptionP);
|
||||
virtual void SetData(cChannel *channelP);
|
||||
virtual void GetData(cChannel *channelP);
|
||||
virtual cOsdItem *GetOsdItem(void);
|
||||
};
|
||||
|
||||
#endif // __SATIP_SOURCE_H
|
156
tuner.c
156
tuner.c
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "discover.h"
|
||||
#include "tuner.h"
|
||||
|
||||
cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
||||
@@ -18,12 +19,15 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
||||
rtcpSocketM(new cSatipSocket()),
|
||||
streamAddrM(""),
|
||||
streamParamM(""),
|
||||
currentServerM(NULL),
|
||||
nextServerM(NULL),
|
||||
mutexM(),
|
||||
handleM(NULL),
|
||||
headerListM(NULL),
|
||||
keepAliveM(),
|
||||
pidUpdateCacheM(),
|
||||
timeoutM(eKeepAliveIntervalMs),
|
||||
sessionM(),
|
||||
timeoutM(eMinKeepAliveIntervalMs),
|
||||
openedM(false),
|
||||
tunedM(false),
|
||||
hasLockM(false),
|
||||
@@ -33,20 +37,20 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
||||
pidUpdatedM(false),
|
||||
pidsM()
|
||||
{
|
||||
debug("cSatipTuner::%s(%d)", __FUNCTION__, packetBufferLenM);
|
||||
debug("cSatipTuner::%s(%d) [device %d]", __FUNCTION__, packetBufferLenM, deviceM->GetId());
|
||||
// Allocate packet buffer
|
||||
packetBufferM = MALLOC(unsigned char, packetBufferLenM);
|
||||
if (packetBufferM)
|
||||
memset(packetBufferM, 0, packetBufferLenM);
|
||||
else
|
||||
error("MALLOC() failed for packet buffer");
|
||||
error("MALLOC() failed for packet buffer [device %d]", deviceM->GetId());
|
||||
// Start thread
|
||||
Start();
|
||||
}
|
||||
|
||||
cSatipTuner::~cSatipTuner()
|
||||
{
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
// Stop thread
|
||||
sleepM.Signal();
|
||||
if (Running())
|
||||
@@ -64,34 +68,36 @@ size_t cSatipTuner::HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void
|
||||
size_t len = sizeP * nmembP;
|
||||
//debug("cSatipTuner::%s(%zu)", __FUNCTION__, len);
|
||||
|
||||
int id = -1, timeout = -1;
|
||||
char *s, *p = (char *)ptrP;
|
||||
char *r = strtok_r(p, "\r\n", &s);
|
||||
|
||||
while (r) {
|
||||
while (obj && r) {
|
||||
//debug("cSatipTuner::%s(%zu): %s", __FUNCTION__, len, r);
|
||||
r = skipspace(r);
|
||||
if (strstr(r, "com.ses.streamID")) {
|
||||
if (sscanf(r, "com.ses.streamID: %11d", &id) != 1)
|
||||
id = -1;
|
||||
int streamid = -1;
|
||||
if (sscanf(r, "com.ses.streamID:%11d", &streamid) == 1)
|
||||
obj->SetStreamId(streamid);
|
||||
}
|
||||
else if (strstr(r, "Session:")) {
|
||||
int session = -1;
|
||||
if (sscanf(r, "Session: %11d;timeout=%11d", &session, &timeout) != 2)
|
||||
timeout = -1;
|
||||
int timeout = -1;
|
||||
char *session = NULL;
|
||||
if (sscanf(r, "Session:%m[^;];timeout=%11d", &session, &timeout) == 2)
|
||||
obj->SetSessionTimeout(skipspace(session), timeout * 1000);
|
||||
else if (sscanf(r, "Session:%m[^;]", &session) == 1)
|
||||
obj->SetSessionTimeout(skipspace(session));
|
||||
FREE_POINTER(session);
|
||||
}
|
||||
r = strtok_r(NULL, "\r\n", &s);
|
||||
}
|
||||
|
||||
if (id >= 0 && obj)
|
||||
obj->SetStreamInfo(id, timeout);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void cSatipTuner::Action(void)
|
||||
{
|
||||
debug("cSatipTuner::%s(): entering", __FUNCTION__);
|
||||
cTimeMs timeout(0);
|
||||
debug("cSatipTuner::%s(): entering [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
cTimeMs timeout(eReConnectTimeoutMs);
|
||||
// Increase priority
|
||||
SetPriority(-1);
|
||||
// Do the thread loop
|
||||
@@ -123,7 +129,7 @@ void cSatipTuner::Action(void)
|
||||
}
|
||||
else {
|
||||
// Reconnect if necessary
|
||||
if (openedM && !tunedM && timeout.TimedOut()) {
|
||||
if (openedM && timeout.TimedOut()) {
|
||||
Disconnect();
|
||||
Connect();
|
||||
timeout.Set(eReConnectTimeoutMs);
|
||||
@@ -131,12 +137,12 @@ void cSatipTuner::Action(void)
|
||||
sleepM.Wait(10); // to avoid busy loop and reduce cpu load
|
||||
}
|
||||
}
|
||||
debug("cSatipTuner::%s(): exiting", __FUNCTION__);
|
||||
debug("cSatipTuner::%s(): exiting [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
}
|
||||
|
||||
bool cSatipTuner::Open(void)
|
||||
{
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
if (Connect()) {
|
||||
openedM = true;
|
||||
return true;
|
||||
@@ -146,7 +152,7 @@ bool cSatipTuner::Open(void)
|
||||
|
||||
bool cSatipTuner::Close(void)
|
||||
{
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
openedM = false;
|
||||
Disconnect();
|
||||
return true;
|
||||
@@ -155,7 +161,7 @@ bool cSatipTuner::Close(void)
|
||||
bool cSatipTuner::Connect(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
|
||||
// Initialize the curl session
|
||||
if (!handleM)
|
||||
@@ -167,7 +173,7 @@ bool cSatipTuner::Connect(void)
|
||||
|
||||
// Just retune
|
||||
if (tunedM && (streamIdM >= 0)) {
|
||||
debug("cSatipTuner::%s(): retune", __FUNCTION__);
|
||||
debug("cSatipTuner::%s(): retune [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||
@@ -177,7 +183,6 @@ bool cSatipTuner::Connect(void)
|
||||
// Flush any old content
|
||||
if (rtpSocketM)
|
||||
rtpSocketM->Flush();
|
||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -186,11 +191,6 @@ bool cSatipTuner::Connect(void)
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_VERBOSE, 1L);
|
||||
#endif
|
||||
|
||||
// Set callback
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, cSatipTuner::HeaderCallback);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
|
||||
|
||||
// No progress meter and no signaling
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_NOPROGRESS, 1L);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_NOSIGNAL, 1L);
|
||||
@@ -200,7 +200,7 @@ bool cSatipTuner::Connect(void)
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_CONNECTTIMEOUT_MS, (long)eConnectTimeoutMs);
|
||||
|
||||
// Set user-agent
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s", PLUGIN_NAME_I18N, VERSION));
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s (device %d)", PLUGIN_NAME_I18N, VERSION, deviceM->GetId()));
|
||||
|
||||
// Set URL
|
||||
char *p = curl_easy_unescape(handleM, *streamAddrM, 0, NULL);
|
||||
@@ -218,36 +218,53 @@ bool cSatipTuner::Connect(void)
|
||||
rtcpSocketM->Close();
|
||||
}
|
||||
if ((rtpSocketM->Port() <= 0) || (rtcpSocketM->Port() <= 0)) {
|
||||
error("Cannot open required ports!");
|
||||
error("Cannot open required RTP/RTCP ports [device %d]", deviceM->GetId());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Request server options: "&pids=all" for the whole mux
|
||||
uri = cString::sprintf("rtsp://%s/?%s&pids=0", *streamAddrM, *streamParamM);
|
||||
// Request server options
|
||||
keepAliveM.Set(timeoutM);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (!ValidateLatestResponse())
|
||||
return false;
|
||||
|
||||
// Setup media stream
|
||||
// Setup media stream: "&pids=all" for the whole mux
|
||||
uri = cString::sprintf("rtsp://%s/?%s", *streamAddrM, *streamParamM);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
transport = cString::sprintf("RTP/AVP;unicast;client_port=%d-%d", rtpSocketM->Port(), rtcpSocketM->Port());
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_TRANSPORT, *transport);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_SETUP);
|
||||
// Set header callback for catching the session and timeout
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, cSatipTuner::HeaderCallback);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
// Session id is now known - disable header parsing
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, NULL);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, NULL);
|
||||
//SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, *sessionM);
|
||||
if (!ValidateLatestResponse())
|
||||
return false;
|
||||
|
||||
// Start playing
|
||||
uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (!ValidateLatestResponse())
|
||||
return false;
|
||||
if (pidsM.Size()) {
|
||||
uri = cString::sprintf("rtsp://%s/stream=%d?pids=", *streamAddrM, streamIdM);
|
||||
for (int i = 0; i < pidsM.Size(); ++i)
|
||||
uri = cString::sprintf("%s%d%s", *uri, pidsM[i], (i == (pidsM.Size() - 1)) ? "" : ",");
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (!ValidateLatestResponse())
|
||||
return false;
|
||||
}
|
||||
|
||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
||||
tunedM = true;
|
||||
if (nextServerM) {
|
||||
cSatipDiscover::GetInstance()->UseServer(nextServerM, true);
|
||||
currentServerM = nextServerM;
|
||||
nextServerM = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -257,7 +274,7 @@ bool cSatipTuner::Connect(void)
|
||||
bool cSatipTuner::Disconnect(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
|
||||
// Terminate curl session
|
||||
if (handleM) {
|
||||
@@ -290,14 +307,18 @@ bool cSatipTuner::Disconnect(void)
|
||||
signalStrengthM = -1;
|
||||
signalQualityM = -1;
|
||||
|
||||
if (currentServerM)
|
||||
cSatipDiscover::GetInstance()->UseServer(currentServerM, false);
|
||||
tunedM = false;
|
||||
timeoutM = eMinKeepAliveIntervalMs;
|
||||
pidUpdatedM = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cSatipTuner::ValidateLatestResponse(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
if (handleM) {
|
||||
long rc = 0;
|
||||
CURLcode res = CURLE_OK;
|
||||
@@ -305,7 +326,7 @@ bool cSatipTuner::ValidateLatestResponse(void)
|
||||
if (rc == 200)
|
||||
return true;
|
||||
else if (rc != 0)
|
||||
error("Tuner detected invalid status code: %ld", rc);
|
||||
error("Tuner detected invalid status code %ld [device %d]", rc, deviceM->GetId());
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -313,7 +334,7 @@ bool cSatipTuner::ValidateLatestResponse(void)
|
||||
|
||||
void cSatipTuner::ParseReceptionParameters(const char *paramP)
|
||||
{
|
||||
debug("cSatipTuner::%s(%s)", __FUNCTION__, paramP);
|
||||
//debug("cSatipTuner::%s(%s) [device %d]", __FUNCTION__, paramP, deviceM->GetId());
|
||||
// DVB-S2:
|
||||
// ver=<major>.<minor>;src=<srcID>;tuner=<feID>,<level>,<lock>,<quality>,<frequency>,<polarisation>,<system>,<type>,<pilots>,<roll_off>,<symbol_rate>,<fec_inner>;pids=<pid0>,...,<pidn>
|
||||
// DVB-T2:
|
||||
@@ -357,20 +378,29 @@ void cSatipTuner::ParseReceptionParameters(const char *paramP)
|
||||
}
|
||||
}
|
||||
|
||||
void cSatipTuner::SetStreamInfo(int idP, int timeoutP)
|
||||
void cSatipTuner::SetStreamId(int streamIdP)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
debug("cSatipTuner::%s(%d, %d)", __FUNCTION__, idP, timeoutP);
|
||||
streamIdM = idP;
|
||||
timeoutM = timeoutP > 0 ? timeoutP * 1000L : eKeepAliveIntervalMs;
|
||||
debug("cSatipTuner::%s(%d) [device %d]", __FUNCTION__, streamIdP, deviceM->GetId());
|
||||
streamIdM = streamIdP;
|
||||
}
|
||||
|
||||
bool cSatipTuner::SetSource(const char* addressP, const char *parameterP, const int indexP)
|
||||
void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
|
||||
{
|
||||
debug("cSatipTuner::%s(%s, %s, %d)", __FUNCTION__, addressP, parameterP, indexP);
|
||||
if (!isempty(addressP) && !isempty(parameterP)) {
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
debug("cSatipTuner::%s(%s, %d) [device %d]", __FUNCTION__, sessionP, timeoutP, deviceM->GetId());
|
||||
sessionM = sessionP;
|
||||
timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs;
|
||||
}
|
||||
|
||||
bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const int indexP)
|
||||
{
|
||||
debug("cSatipTuner::%s(%s, %d) [device %d]", __FUNCTION__, parameterP, indexP, deviceM->GetId());
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
nextServerM = cSatipDiscover::GetInstance()->GetServer(serverP);
|
||||
if (nextServerM && !isempty(nextServerM->Address()) && !isempty(parameterP)) {
|
||||
// Update stream address and parameter
|
||||
streamAddrM = addressP;
|
||||
streamAddrM = nextServerM->Address();
|
||||
streamParamM = parameterP;
|
||||
// Reconnect
|
||||
Connect();
|
||||
@@ -380,7 +410,7 @@ bool cSatipTuner::SetSource(const char* addressP, const char *parameterP, const
|
||||
|
||||
bool cSatipTuner::SetPid(int pidP, int typeP, bool onP)
|
||||
{
|
||||
debug("cSatipTuner::%s(%d, %d, %d)", __FUNCTION__, pidP, typeP, onP);
|
||||
//debug("cSatipTuner::%s(%d, %d, %d) [device %d]", __FUNCTION__, pidP, typeP, onP, deviceM->GetId());
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
bool found = false;
|
||||
for (int i = 0; i < pidsM.Size(); ++i) {
|
||||
@@ -405,7 +435,7 @@ bool cSatipTuner::UpdatePids(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
if (pidUpdateCacheM.TimedOut() && pidUpdatedM && pidsM.Size() && tunedM && handleM && !isempty(*streamAddrM) && (streamIdM > 0)) {
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
CURLcode res = CURLE_OK;
|
||||
//cString uri = cString::sprintf("rtsp://%s/stream=%d?%spids=%d", *streamAddrM, streamIdM, onP ? "add" : "del", pidP);
|
||||
cString uri = cString::sprintf("rtsp://%s/stream=%d?pids=", *streamAddrM, streamIdM);
|
||||
@@ -416,10 +446,8 @@ bool cSatipTuner::UpdatePids(void)
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (ValidateLatestResponse()) {
|
||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
||||
if (ValidateLatestResponse())
|
||||
pidUpdatedM = false;
|
||||
}
|
||||
else
|
||||
Disconnect();
|
||||
|
||||
@@ -433,7 +461,7 @@ bool cSatipTuner::KeepAlive(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
if (tunedM && handleM && keepAliveM.TimedOut()) {
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
CURLcode res = CURLE_OK;
|
||||
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||
|
||||
@@ -441,7 +469,7 @@ bool cSatipTuner::KeepAlive(void)
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (ValidateLatestResponse())
|
||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
||||
keepAliveM.Set(timeoutM);
|
||||
else
|
||||
Disconnect();
|
||||
|
||||
@@ -453,30 +481,30 @@ bool cSatipTuner::KeepAlive(void)
|
||||
|
||||
int cSatipTuner::SignalStrength(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return signalStrengthM;
|
||||
}
|
||||
|
||||
int cSatipTuner::SignalQuality(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return signalQualityM;
|
||||
}
|
||||
|
||||
bool cSatipTuner::HasLock(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return tunedM && hasLockM;
|
||||
}
|
||||
|
||||
cString cSatipTuner::GetSignalStatus(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return cString::sprintf("lock=%d strength=%d quality=%d", HasLock(), SignalStrength(), SignalQuality());
|
||||
}
|
||||
|
||||
cString cSatipTuner::GetInformation(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return tunedM ? cString::sprintf("rtsp://%s/?%s [stream=%d]", *streamAddrM, *streamParamM, streamIdM) : "connection failed";
|
||||
}
|
||||
|
17
tuner.h
17
tuner.h
@@ -19,16 +19,17 @@
|
||||
#include <vdr/tools.h>
|
||||
|
||||
#include "deviceif.h"
|
||||
#include "server.h"
|
||||
#include "statistics.h"
|
||||
#include "socket.h"
|
||||
|
||||
class cSatipTuner : public cThread, public cSatipTunerStatistics {
|
||||
private:
|
||||
enum {
|
||||
eConnectTimeoutMs = 1500, // in milliseconds
|
||||
ePidUpdateIntervalMs = 100, // in milliseconds
|
||||
eReConnectTimeoutMs = 5000, // in milliseconds
|
||||
eKeepAliveIntervalMs = 600000 // in milliseconds
|
||||
eConnectTimeoutMs = 1500, // in milliseconds
|
||||
ePidUpdateIntervalMs = 100, // in milliseconds
|
||||
eReConnectTimeoutMs = 5000, // in milliseconds
|
||||
eMinKeepAliveIntervalMs = 30000 // in milliseconds
|
||||
};
|
||||
|
||||
static size_t HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
||||
@@ -41,12 +42,15 @@ private:
|
||||
cSatipSocket *rtcpSocketM;
|
||||
cString streamAddrM;
|
||||
cString streamParamM;
|
||||
cSatipServer *currentServerM;
|
||||
cSatipServer *nextServerM;
|
||||
cMutex mutexM;
|
||||
CURL *handleM;
|
||||
struct curl_slist *headerListM;
|
||||
cTimeMs keepAliveM;
|
||||
cTimeMs signalInfoCacheM;
|
||||
cTimeMs pidUpdateCacheM;
|
||||
cString sessionM;
|
||||
int timeoutM;
|
||||
bool openedM;
|
||||
bool tunedM;
|
||||
@@ -61,7 +65,8 @@ private:
|
||||
bool Disconnect(void);
|
||||
bool ValidateLatestResponse(void);
|
||||
void ParseReceptionParameters(const char *paramP);
|
||||
void SetStreamInfo(int idP, int timeoutP);
|
||||
void SetStreamId(int streamIdP);
|
||||
void SetSessionTimeout(const char *sessionP, int timeoutP = 0);
|
||||
bool KeepAlive(void);
|
||||
bool UpdateSignalInfoCache(void);
|
||||
bool UpdatePids(void);
|
||||
@@ -73,7 +78,7 @@ public:
|
||||
cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP);
|
||||
virtual ~cSatipTuner();
|
||||
bool IsTuned(void) const { return tunedM; }
|
||||
bool SetSource(const char* addressP, const char *parameterP, const int indexP);
|
||||
bool SetSource(cSatipServer *serverP, const char *parameterP, const int indexP);
|
||||
bool SetPid(int pidP, int typeP, bool onP);
|
||||
bool Open(void);
|
||||
bool Close(void);
|
||||
|
Reference in New Issue
Block a user