1
0
mirror of https://github.com/rofafor/vdr-plugin-satip.git synced 2023-10-10 11:37:42 +00:00

40 Commits

Author SHA1 Message Date
Rolf Ahrenberg
46bfc805e6 Removed SATIP_XCI. 2015-01-18 15:08:57 +02:00
Rolf Ahrenberg
30925337cb Updated Spanish and Catalan translations (Thanks to Gabriel Bonich). 2015-01-18 00:13:29 +02:00
Rolf Ahrenberg
63e47ad24a Reworded the README. 2015-01-17 20:02:18 +02:00
Rolf Ahrenberg
14123e160f Fixed the server parsing multiple times. 2015-01-17 19:42:21 +02:00
Rolf Ahrenberg
278d0478cf Added a command-line option to disable all the SAT>IP server quirks. 2015-01-17 17:29:21 +02:00
Rolf Ahrenberg
9989c36eee Delayed the server parameter parsing. 2015-01-17 16:47:19 +02:00
Rolf Ahrenberg
d2064f0c04 Added an option to disable sources via sources.conf. 2015-01-17 01:39:32 +02:00
Rolf Ahrenberg
714d3ed902 Increased the max number of disabled sources. 2015-01-17 00:45:30 +02:00
Rolf Ahrenberg
b466d6836e Added NULL checks for cSatipServer parameters. 2015-01-17 00:00:59 +02:00
Rolf Ahrenberg
184ddf2a53 Fixed a wrong parameter type. 2015-01-16 00:08:48 +02:00
Rolf Ahrenberg
65a2158051 Fixed some whitespaces. 2015-01-15 23:38:02 +02:00
Rolf Ahrenberg
e833ca6fdd Added a separate trace mode for pids. 2015-01-15 20:03:35 +02:00
Rolf Ahrenberg
c9abfddf11 Changed SATIP_USE_SINGLE_MODEL_SERVERS_ONLY into a command-line switch. 2015-01-15 19:27:02 +02:00
Rolf Ahrenberg
fb7a7fe3a2 Fixed parsing of the setup values. 2015-01-15 00:12:55 +02:00
Rolf Ahrenberg
3b9269e9de Added a separate trace mode for server discovery. 2015-01-14 22:59:56 +02:00
Rolf Ahrenberg
09e6c272cd Refactored cSatipPid for upcoming API changes. 2015-01-14 20:51:16 +02:00
Rolf Ahrenberg
266aadb999 Modified the model detection a bit more readable. 2015-01-14 20:34:12 +02:00
Rolf Ahrenberg
aed5a7820a Fixed 'length' typos. 2015-01-14 17:58:13 +02:00
Rolf Ahrenberg
bcb11b6257 Added a compile-time option to split any mixed model server into several single ones. 2015-01-13 21:45:14 +02:00
Rolf Ahrenberg
21261f8042 Clamp signal quality and level values. 2015-01-12 23:58:30 +02:00
Rolf Ahrenberg
2f11ad7a98 Added server parameter exanples. 2015-01-12 23:51:38 +02:00
Rolf Ahrenberg
83a0233780 Updated German translation (Thanks to Frank Neumann). 2015-01-12 13:09:09 +02:00
Rolf Ahrenberg
6f3715eb8b Merge pull request #5 from CvH/patch-1
Fixed a typo in firmware version.
2015-01-12 09:22:43 +02:00
CvH
92991cd144 fixed typo at fw version 2015-01-11 22:52:40 +01:00
Rolf Ahrenberg
304addbc00 Added missing CI/CAM translations. 2015-01-11 23:49:12 +02:00
Rolf Ahrenberg
26ff10ce1e Added configurable CI slots. 2015-01-11 16:34:32 +02:00
Rolf Ahrenberg
e654b3bbd2 Updated version number. 2015-01-11 16:33:42 +02:00
Rolf Ahrenberg
acea8748a4 Added SATIP_XCI variable for enabling CI support. 2015-01-10 18:30:07 +02:00
Rolf Ahrenberg
755f1049bb Reduced tuner sleep timeout to get better performance for pid updates. 2015-01-10 14:14:30 +02:00
Rolf Ahrenberg
2f6315280f Tweaked setting the pid update cache timer. 2015-01-09 19:56:43 +02:00
Rolf Ahrenberg
695dd53bfc Added initial support for x_ci parameter. 2015-01-09 16:38:02 +02:00
Rolf Ahrenberg
5fef77518e Changed the PMT debugging into a separate trace mode. 2015-01-09 02:06:20 +02:00
Rolf Ahrenberg
791767f02b Documented CI extension parameters. 2015-01-07 17:45:48 +02:00
Rolf Ahrenberg
0d52649dbd Added the missing translation item. 2015-01-06 21:41:52 +02:00
Rolf Ahrenberg
0c03c1b8d4 Added a CI extension item into the device info menu. 2015-01-06 19:46:56 +02:00
Rolf Ahrenberg
db59aa9c29 Added support for Digital Devices CI extension. 2015-01-06 15:53:31 +02:00
Rolf Ahrenberg
0fd559ce79 Added a fallback for older glibc libraries. 2015-01-05 20:24:45 +02:00
Rolf Ahrenberg
e10ce57210 Removed the unnecessary config directory definition. 2015-01-05 20:15:04 +02:00
Rolf Ahrenberg
c7f4b265d5 Fixed the server teardown. 2015-01-05 20:12:15 +02:00
Rolf Ahrenberg
35c0f25c38 Updated the command-line help and README. 2015-01-05 20:09:45 +02:00
31 changed files with 613 additions and 163 deletions

20
HISTORY
View File

@@ -88,3 +88,23 @@ VDR Plugin 'satip' Revision History
- Added plenty of performance tweaks (Thanks to
Stefan Schallenberg).
- Fixed EIT scan (Thanks to Stefan Schallenberg).
2015-01-10: Version 1.0.1
- Updated the command-line help and README.
- Fixed the server teardown.
- Removed the unnecessary config directory definition.
- Added a fallback for older glibc libraries.
- Improved pid selection performance.
- Added support for Digital Devices CI extension.
2015-01-18: Version 1.0.2
- Added configurable CI slots.
- Fixed parsing of the setup values.
- Added an option to disable sources via sources.conf.
- Added a command-line option to disable all the
SAT>IP server quirks.
- Updated Spanish and Catalan translations (Thanks to
Gabriel Bonich).
- Updated German translations (Thanks to Frank Neumann).

View File

@@ -76,8 +76,10 @@ LIBS += -lpugixml
endif
ifdef SATIP_DEBUG
ifeq ($(SATIP_DEBUG),1)
DEFINES += -DDEBUG
endif
endif
ifneq ($(strip $(GITTAG)),)
DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"'

40
README
View File

@@ -23,8 +23,13 @@ Requirements:
TinyXML - a simple, small, C++ XML parser
http://www.grinninglizard.com/tinyxml/
- Glibc >= 2.12 - the GNU C library (recvmmsg)
http://www.gnu.org/software/libc/
- VDR >= 2.1.4 for scrambled channels
- VDR >= 2.1.7 for external CI
Description:
This plugin integrates SAT>IP network devices seamlessly into VDR.
@@ -46,12 +51,19 @@ be received, if there are available SAT>IP tuners.
The plugin accepts also a "--server" (-s) command-line parameter, that
can be used to manually configure static SAT>IP servers if autodetection
via UPnP somehow can't be used.
via UPnP somehow can't be used. The parameter string is a semicolon
separated list of "<ipaddress>|<model>|<description>" entries. The model
consists of a DVB system (DVBS2,DVBT2,DVBT,DVBC) and number of available
frontends separated by a hyphen:
vdr -P 'satip -s <ipaddress>|<model>|<description>;...'
vdr -P 'satip -s 192.168.0.1|DVBS2-2,DVBT2-2|Octo1'
vdr -P 'satip -s 192.168.0.1|DVBS2-4|Octo1;192.168.0.2|DVBT2-4|Octo2'
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:
as SAT>IP signal source selection parameter. A special number zero can
be used to disable the source. Otherwise, the default parameter is one:
S19.2E Astra 1KR/1L/1M/2C
=> Signal source = 1
@@ -62,9 +74,13 @@ S19.2E 2
S19.2E 3 Astra 1KR/1L/1M/2C
=> Signal source = 3
S19.2E 0 Astra 1KR/1L/1M/2C
=> Source is disabled
A channel can be assigned into a specific SAT>IP frontend by giving the
identifier number in RID field of a channels.conf entry.
Valid range: 1 ... 8
identifier number in RID field of a channels.conf entry:
FE = RID % 100
Valid range: 1 ... 99
Setup menu:
@@ -76,6 +92,13 @@ Setup menu:
option to "low". Similarly, the "high"
value prefers the SAT>IP over the local
DVB cards when selecting available devices.
- Use CI extension = no If you want to use the CI extension found
in some SAT>IP hardware (e.g. Digital
Devices OctopusNet), set this option to
"yes".
- CICAM #<slot> = <system> If you want to assign a CA system into
a specific CI slot, set this option to
a named one. Use "---" for autoselection.
- Enable EPG scanning = yes If you want exclude all SAT>IP devices
from VDR's EIT background scanning, set
this option to "no".
@@ -119,6 +142,13 @@ Notes:
- Tracing can be set on/off dynamically via command-line switch or
SVDRP command.
- OctopusNet firmware 1.0.40 or greater recommended.
- Inverto OEM firmware 1.17.0.120 or greater recommended.
The firmware 1.16.0.120 can be downloaded and installed
from their webpage: http://www.inverto.tv/support/
An update to a newer firmware should be offered afterwards.
Acknowledgements:
- Big thanks to Digital Devices GmbH for providing the Octopus Net

View File

@@ -79,10 +79,72 @@ cString ChangeCase(const cString &strP, bool upperP)
const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE] =
{
/* description tag pid tid mask */
// 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},
};
const ca_systems_table_type ca_systems_table[CA_SYSTEMS_TABLE_SIZE] =
{
// http://www.dvb.org/index.php?id=174
// http://en.wikipedia.org/wiki/Conditional_access_system
// start end description
{0x0000, 0x0000, "---" }, // 0
{0x0100, 0x01FF, "SECA Mediaguard (100..1FF)"}, // 1
{0x0464, 0x0464, "EuroDec (464)" }, // 2
{0x0500, 0x05FF, "Viaccess (500..5FF)" }, // 3
{0x0600, 0x06FF, "Irdeto (600..6FF)" }, // 4
{0x0700, 0x07FF, "DigiCipher 2 (700..7FF)" }, // 5
{0x0900, 0x09FF, "NDS Videoguard (900..9FF)" }, // 6
{0x0B00, 0x0BFF, "Conax (B00..BFF)" }, // 7
{0x0D00, 0x0DFF, "CryptoWorks (D00..DFF)" }, // 8
{0x0E00, 0x0EFF, "PowerVu (E00..EFF)" }, // 9
{0x1000, 0x10FF, "RAS (1000..10FF)" }, // 10
{0x1200, 0x12FF, "NagraVision (1200..12FF)" }, // 11
{0x1700, 0x17FF, "VCAS (1700..17FF)" }, // 12
{0x1800, 0x18FF, "NagraVision (1800..18FF)" }, // 13
{0x22F0, 0x22F0, "Codicrypt (22F0)" }, // 14
{0x2600, 0x2600, "BISS (2600)" }, // 15
{0x2719, 0x2719, "VanyaCas (2719)" }, // 16
{0x4347, 0x4347, "CryptOn (4347)" }, // 17
{0x4800, 0x4800, "Accessgate (4800)" }, // 18
{0x4900, 0x4900, "China Crypt (4900)" }, // 19
{0x4A02, 0x4A02, "Tongfang (4A02)" }, // 20
{0x4A10, 0x4A10, "EasyCas (4A10)" }, // 21
{0x4A20, 0x4A20, "AlphaCrypt (4A20)" }, // 22
{0x4A60, 0x4A60, "SkyCrypt (4A60)" }, // 23
{0x4A61, 0x4A61, "Neotioncrypt (4A61)" }, // 24
{0x4A62, 0x4A62, "SkyCrypt (4A62)" }, // 25
{0x4A63, 0x4A63, "Neotion SHL (4A63)" }, // 26
{0x4A64, 0x4A6F, "SkyCrypt (4A64)" }, // 27
{0x4A70, 0x4A70, "DreamCrypt (4A70)" }, // 28
{0x4A80, 0x4A80, "ThalesCrypt (4A80)" }, // 29
{0x4AA1, 0x4AA1, "KeyFly (4AA1)" }, // 30
{0x4ABF, 0x4ABF, "CTI-CAS (4ABF)" }, // 31
{0x4AC1, 0x4AC1, "Latens (4AC1)" }, // 32
{0x4AD0, 0x4AD1, "X-Crypt (4AD0)" }, // 33
{0x4AD4, 0x4AD4, "OmniCrypt (4AD4)" }, // 34
{0x4AE0, 0x4AE1, "Z-Crypt (4AE0)" }, // 35
{0x4AE4, 0x4AE4, "CoreCrypt (4AE4)" }, // 36
{0x4AE5, 0x4AE5, "PRO-Crypt (4AE5)" }, // 37
{0x4AEA, 0x4AEA, "Cryptoguard (4AEA)" }, // 38
{0x4AEB, 0x4AEB, "Abel Quintic (4AEB)" }, // 39
{0x4AF0, 0x4AF0, "ABV (4AF0)" }, // 40
{0x5500, 0x5500, "Z-Crypt (5500)" }, // 41
{0x5501, 0x5501, "Griffin (5501)" }, // 42
{0x5581, 0x5581, "Bulcrypt (5581)" }, // 43
{0x7BE1, 0x7BE1, "DRE-Crypt (7BE1)" }, // 44
{0xA101, 0xA101, "RosCrypt-M (A101)" }, // 45
{0xEAD0, 0xEAD0, "VanyaCas (EAD0)" }, // 46
};
bool checkCASystem(unsigned int cicamP, int caidP)
{
// always skip the first row
if ((cicamP > 0) && (cicamP < ELEMENTS(ca_systems_table)))
return ((caidP >= ca_systems_table[cicamP].start) && (caidP <= ca_systems_table[cicamP].end));
return false;
}

View File

@@ -13,8 +13,6 @@
#include <vdr/config.h>
#include <vdr/i18n.h>
#define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
#define SATIP_MAX_DEVICES MAXDEVICES
#define SATIP_BUFFER_SIZE KILOBYTE(1024)
@@ -29,9 +27,12 @@
#define SATIP_STATS_ACTIVE_PIDS_COUNT 10
#define SATIP_STATS_ACTIVE_FILTERS_COUNT 10
#define MAX_DISABLED_SOURCES_COUNT 5
#define MAX_DISABLED_SOURCES_COUNT 25
#define SECTION_FILTER_TABLE_SIZE 5
#define MAX_CICAM_COUNT 2
#define CA_SYSTEMS_TABLE_SIZE 47
#define SATIP_CURL_EASY_GETINFO(X, Y, Z) \
if ((res = curl_easy_getinfo((X), (Y), (Z))) != CURLE_OK) { \
error("curl_easy_getinfo(%s) [%s,%d] failed: %s (%d)", #Y, __FILE__, __LINE__, curl_easy_strerror(res), res); \
@@ -81,7 +82,7 @@
} \
} while (0)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
#define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
uint16_t ts_pid(const uint8_t *bufP);
uint8_t payload(const uint8_t *bufP);
@@ -100,6 +101,15 @@ struct section_filter_table_type {
extern const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE];
struct ca_systems_table_type {
int start;
int end;
const char *description;
};
extern const ca_systems_table_type ca_systems_table[CA_SYSTEMS_TABLE_SIZE];
extern bool checkCASystem(unsigned int cicamP, int caidP);
extern const char VERSION[];
#endif // __SATIP_COMMON_H

View File

@@ -14,56 +14,65 @@ cSatipConfig SatipConfig;
cSatipConfig::cSatipConfig(void)
: operatingModeM(eOperatingModeLow),
traceModeM(eTraceModeNormal),
ciExtensionM(0),
eitScanM(1),
useBytesM(1)
useBytesM(1),
disableServerQuirksM(false),
useSingleModelServersM(false)
{
for (unsigned int i = 0; i < ARRAY_SIZE(disabledSourcesM); ++i)
for (unsigned int i = 0; i < ELEMENTS(cicamsM); ++i)
cicamsM[i] = 0;
for (unsigned int i = 0; i < ELEMENTS(disabledSourcesM); ++i)
disabledSourcesM[i] = cSource::stNone;
for (unsigned int i = 0; i < ARRAY_SIZE(disabledFiltersM); ++i)
for (unsigned int i = 0; i < ELEMENTS(disabledFiltersM); ++i)
disabledFiltersM[i] = -1;
memset(configDirectoryM, 0, sizeof(configDirectoryM));
}
int cSatipConfig::GetCICAM(unsigned int indexP) const
{
return (indexP < ELEMENTS(cicamsM)) ? cicamsM[indexP] : -1;
}
void cSatipConfig::SetCICAM(unsigned int indexP, int cicamP)
{
if (indexP < ELEMENTS(cicamsM))
cicamsM[indexP] = cicamP;
}
unsigned int cSatipConfig::GetDisabledSourcesCount(void) const
{
unsigned int n = 0;
while ((n < ARRAY_SIZE(disabledSourcesM) && (disabledSourcesM[n] != cSource::stNone)))
while ((n < ELEMENTS(disabledSourcesM) && (disabledSourcesM[n] != cSource::stNone)))
n++;
return n;
}
int cSatipConfig::GetDisabledSources(unsigned int indexP) const
{
return (indexP < ARRAY_SIZE(disabledSourcesM)) ? disabledSourcesM[indexP] : cSource::stNone;
return (indexP < ELEMENTS(disabledSourcesM)) ? disabledSourcesM[indexP] : cSource::stNone;
}
void cSatipConfig::SetDisabledSources(unsigned int indexP, int sourceP)
{
if (indexP < ARRAY_SIZE(disabledSourcesM))
if (indexP < ELEMENTS(disabledSourcesM))
disabledSourcesM[indexP] = sourceP;
}
unsigned int cSatipConfig::GetDisabledFiltersCount(void) const
{
unsigned int n = 0;
while ((n < ARRAY_SIZE(disabledFiltersM) && (disabledFiltersM[n] != -1)))
while ((n < ELEMENTS(disabledFiltersM) && (disabledFiltersM[n] != -1)))
n++;
return n;
}
int cSatipConfig::GetDisabledFilters(unsigned int indexP) const
{
return (indexP < ARRAY_SIZE(disabledFiltersM)) ? disabledFiltersM[indexP] : -1;
return (indexP < ELEMENTS(disabledFiltersM)) ? disabledFiltersM[indexP] : -1;
}
void cSatipConfig::SetDisabledFilters(unsigned int indexP, int numberP)
{
if (indexP < ARRAY_SIZE(disabledFiltersM))
if (indexP < ELEMENTS(disabledFiltersM))
disabledFiltersM[indexP] = numberP;
}
void cSatipConfig::SetConfigDirectory(const char *directoryP)
{
debug1("%s (%s)", __PRETTY_FUNCTION__, directoryP);
ERROR_IF(!realpath(directoryP, configDirectoryM), "Cannot canonicalize configuration directory");
}

View File

@@ -16,11 +16,14 @@ class cSatipConfig
private:
unsigned int operatingModeM;
unsigned int traceModeM;
unsigned int ciExtensionM;
unsigned int eitScanM;
unsigned int useBytesM;
bool disableServerQuirksM;
bool useSingleModelServersM;
int cicamsM[MAX_CICAM_COUNT];
int disabledSourcesM[MAX_DISABLED_SOURCES_COUNT];
int disabledFiltersM[SECTION_FILTER_TABLE_SIZE];
char configDirectoryM[PATH_MAX];
public:
enum eOperatingMode {
@@ -59,9 +62,12 @@ public:
void ToggleOperatingMode(void) { operatingModeM = (operatingModeM + 1) % eOperatingModeCount; }
unsigned int GetTraceMode(void) const { return traceModeM; }
bool IsTraceMode(eTraceMode modeP) const { return (traceModeM & modeP); }
unsigned int GetCIExtension(void) const { return ciExtensionM; }
int GetCICAM(unsigned int indexP) const;
unsigned int GetEITScan(void) const { return eitScanM; }
unsigned int GetUseBytes(void) const { return useBytesM; }
const char *GetConfigDirectory(void) const { return configDirectoryM; }
bool GetDisableServerQuirks(void) const { return disableServerQuirksM; }
bool GetUseSingleModelServers(void) const { return useSingleModelServersM; }
unsigned int GetDisabledSourcesCount(void) const;
int GetDisabledSources(unsigned int indexP) const;
unsigned int GetDisabledFiltersCount(void) const;
@@ -69,9 +75,12 @@ public:
void SetOperatingMode(unsigned int operatingModeP) { operatingModeM = operatingModeP; }
void SetTraceMode(unsigned int modeP) { traceModeM = (modeP & eTraceModeMask); }
void SetCIExtension(unsigned int onOffP) { ciExtensionM = onOffP; }
void SetCICAM(unsigned int indexP, int cicamP);
void SetEITScan(unsigned int onOffP) { eitScanM = onOffP; }
void SetUseBytes(unsigned int onOffP) { useBytesM = onOffP; }
void SetConfigDirectory(const char *directoryP);
void SetDisableServerQuirks(bool onOffP) { disableServerQuirksM = onOffP; }
void SetUseSingleModelServers(bool onOffP) { useSingleModelServersM = onOffP; }
void SetDisabledSources(unsigned int indexP, int sourceP);
void SetDisabledFilters(unsigned int indexP, int numberP);
};

View File

@@ -217,7 +217,11 @@ int cSatipDevice::SignalQuality(void) const
bool cSatipDevice::ProvidesSource(int sourceP) const
{
debug9("%s (%c) [device %u]", __PRETTY_FUNCTION__, cSource::ToChar(sourceP), deviceIndexM);
cSource *s = Sources.Get(sourceP);
debug9("%s (%c) desc='%s' [device %u]", __PRETTY_FUNCTION__, cSource::ToChar(sourceP), s ? s->Description() : "", deviceIndexM);
// source descriptions starting with '0' are disabled
if (s && s->Description() && (*(s->Description()) == '0'))
return false;
if (!SatipConfig.IsOperatingModeOff() && !!cSatipDiscover::GetInstance()->GetServer(sourceP)) {
int numDisabledSourcesM = SatipConfig.GetDisabledSourcesCount();
for (int i = 0; i < numDisabledSourcesM; ++i) {
@@ -326,13 +330,13 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
cString address;
cSatipServer *server = cSatipDiscover::GetInstance()->GetServer(channelP->Source(), channelP->Transponder(), dtp.System());
if (!server) {
debug1("%s No suitable server found [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
debug9("%s No suitable server found [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
return false;
}
cSatipDiscover::GetInstance()->SetTransponder(server, channelP->Transponder());
if (pTunerM && pTunerM->SetSource(server, *params, deviceIndexM)) {
deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server));
channelM = *channelP;
deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server));
return true;
}
}
@@ -345,7 +349,7 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP)
bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP)
{
debug9("%s (%d, %d, %d) [device %u]", __PRETTY_FUNCTION__, handleP->pid, typeP, onP, deviceIndexM);
debug12("%s (%d, %d, %d) [device %u]", __PRETTY_FUNCTION__, handleP->pid, typeP, onP, deviceIndexM);
if (pTunerM && handleP && handleP->pid >= 0) {
if (onP)
return pTunerM->SetPid(handleP->pid, typeP, true);
@@ -357,7 +361,7 @@ bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP)
int cSatipDevice::OpenFilter(u_short pidP, u_char tidP, u_char maskP)
{
debug9("%s (%d, %02X, %02X) [device %d]", __PRETTY_FUNCTION__, pidP, tidP, maskP, deviceIndexM);
debug12("%s (%d, %02X, %02X) [device %d]", __PRETTY_FUNCTION__, pidP, tidP, maskP, deviceIndexM);
if (pSectionFilterHandlerM) {
int handle = pSectionFilterHandlerM->Open(pidP, tidP, maskP);
if (pTunerM && (handle >= 0))
@@ -371,7 +375,7 @@ void cSatipDevice::CloseFilter(int handleP)
{
if (pSectionFilterHandlerM) {
int pid = pSectionFilterHandlerM->GetPid(handleP);
debug9("%s (%d) [device %u]", __PRETTY_FUNCTION__, pid, deviceIndexM);
debug12("%s (%d) [device %u]", __PRETTY_FUNCTION__, pid, deviceIndexM);
if (pTunerM)
pTunerM->SetPid(pid, ptOther, false);
pSectionFilterHandlerM->Close(handleP);
@@ -406,7 +410,7 @@ bool cSatipDevice::HasLock(int timeoutMsP) const
bool cSatipDevice::HasInternalCam(void)
{
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);
return false;
return SatipConfig.GetCIExtension();
}
void cSatipDevice::WriteData(uchar *bufferP, int lengthP)
@@ -428,6 +432,36 @@ int cSatipDevice::GetId(void)
return deviceIndexM;
}
int cSatipDevice::GetPmtPid(void)
{
int pid = 0;
#if defined(APIVERSNUM) && APIVERSNUM >= 20107
pid = channelM.Ca() ? ::GetPmtPid(channelM.Source(), channelM.Transponder(), channelM.Sid()) : 0;
#endif
debug11("%s pmtpid=%d source=%c transponder=%d sid=%d name=%s [device %u]", __PRETTY_FUNCTION__, pid, cSource::ToChar(channelM.Source()), channelM.Transponder(), channelM.Sid(), channelM.Name(), deviceIndexM);
return pid;
}
int cSatipDevice::GetCISlot(void)
{
int slot = 0;
int ca = 0;
for (const int *id = channelM.Caids(); *id; ++id) {
if (checkCASystem(SatipConfig.GetCICAM(0), *id)) {
ca = *id;
slot = 1;
break;
}
else if (checkCASystem(SatipConfig.GetCICAM(1), *id)) {
ca = *id;
slot = 2;
break;
}
}
debug11("%s slot=%d ca=%X name=%s [device %u]", __PRETTY_FUNCTION__, slot, ca, channelM.Name(), deviceIndexM);
return slot;
}
uchar *cSatipDevice::GetData(int *availableP)
{
debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM);

View File

@@ -108,6 +108,8 @@ public:
public:
virtual void WriteData(u_char *bufferP, int lengthP);
virtual int GetId(void);
virtual int GetPmtPid(void);
virtual int GetCISlot(void);
};
#endif // __SATIP_DEVICE_H

View File

@@ -14,6 +14,8 @@ public:
virtual ~cSatipDeviceIf() {}
virtual void WriteData(u_char *bufferP, int lengthP) = 0;
virtual int GetId(void) = 0;
virtual int GetPmtPid(void) = 0;
virtual int GetCISlot(void) = 0;
private:
cSatipDeviceIf(const cSatipDeviceIf&);

View File

@@ -233,14 +233,33 @@ void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char
{
debug1("%s (%s, %s, %s)", __PRETTY_FUNCTION__, addrP, modelP, descP);
cMutexLock MutexLock(&mutexM);
cSatipServer *tmp = new cSatipServer(addrP, modelP, descP);
// Validate against existing servers
if (!serversM.Update(tmp)) {
info("Adding server '%s|%s|%s'", tmp->Address(), tmp->Model(), tmp->Description());
serversM.Add(tmp);
if (SatipConfig.GetUseSingleModelServers()) {
int n = 0;
char *s, *p = strdup(modelP);
char *r = strtok_r(p, ",", &s);
while (r) {
r = skipspace(r);
cString desc = cString::sprintf("%s #%d", !isempty(descP) ? descP : "MyBrokenHardware", n++);
cSatipServer *tmp = new cSatipServer(addrP, r, desc);
if (!serversM.Update(tmp)) {
info("Adding server '%s|%s|%s'", tmp->Address(), tmp->Model(), tmp->Description());
serversM.Add(tmp);
}
else
DELETENULL(tmp);
r = strtok_r(NULL, ",", &s);
}
FREE_POINTER(p);
}
else {
cSatipServer *tmp = new cSatipServer(addrP, modelP, descP);
if (!serversM.Update(tmp)) {
info("Adding server '%s|%s|%s'", tmp->Address(), tmp->Model(), tmp->Description());
serversM.Add(tmp);
}
else
DELETENULL(tmp);
}
else
DELETENULL(tmp);
}
int cSatipDiscover::GetServerCount(void)

6
log.h
View File

@@ -32,11 +32,11 @@
#define debug9(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug9) ? dsyslog("SATIP9: " x) : void() )
// 0x0200: RTCP packets
#define debug10(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug10) ? dsyslog("SATIP10: " x) : void() )
// 0x0400: TBD
// 0x0400: CI
#define debug11(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug11) ? dsyslog("SATIP11: " x) : void() )
// 0x0800: TBD
// 0x0800: Discovery
#define debug12(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug12) ? dsyslog("SATIP12: " x) : void() )
// 0x1000: TBD
// 0x1000: Pids
#define debug13(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug13) ? dsyslog("SATIP13: " x) : void() )
// 0x2000: TBD
#define debug14(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug14) ? dsyslog("SATIP14: " x) : void() )

View File

@@ -59,12 +59,12 @@ void cSatipMsearch::Process(void)
int length;
while ((length = Read(bufferM, bufferLenM)) > 0) {
bufferM[min(length, int(bufferLenM - 1))] = 0;
debug3("%s len=%d buf=%s", __PRETTY_FUNCTION__, length, bufferM);
debug12("%s len=%d buf=%s", __PRETTY_FUNCTION__, length, bufferM);
bool status = false, valid = false;
char *s, *p = reinterpret_cast<char *>(bufferM), *location = NULL;
char *r = strtok_r(p, "\r\n", &s);
while (r) {
debug3("%s r=%s", __PRETTY_FUNCTION__, r);
debug12("%s r=%s", __PRETTY_FUNCTION__, r);
// Check the status code
// HTTP/1.1 200 OK
if (!status && startswith(r, "HTTP/1.1 200 OK"))

View File

@@ -191,8 +191,8 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
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);
if (channelP->Rid() > 0)
q += snprintf(q, STBUFLEFT, "&fe=%d", channelP->Rid());
if ((channelP->Rid() % 100) > 0)
q += snprintf(q, STBUFLEFT, "&fe=%d", channelP->Rid() % 100);
#undef ST
return buffer;
}

View File

@@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2014 Rolf Ahrenberg
# Copyright (C) 2007-2015 Rolf Ahrenberg
# This file is distributed under the same license as the satip package.
# Gabriel Bonich, 2014
# Gabriel Bonich, 2014-2015
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-satip 1.0.0\n"
"Project-Id-Version: vdr-satip 1.0.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2014-12-24 12:24+0200\n"
"PO-Revision-Date: 2014-12-24 12:24+0200\n"
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
"Language-Team: Catalan <vdr@linuxtv.org>\n"
"Language: ca\n"
@@ -38,7 +38,7 @@ msgid "SAT>IP Devices"
msgstr "SAT>IP Dispositius"
msgid "SAT>IP Server"
msgstr ""
msgstr "SAT>IP Server"
msgid "Address"
msgstr "Adressa"
@@ -49,11 +49,14 @@ msgstr "Model"
msgid "Description"
msgstr "Descripció"
msgid "CI extension"
msgstr "Extensió CI"
msgid "Creation date"
msgstr "Creació de data"
msgid "SAT>IP Device Status"
msgstr ""
msgstr "SAT>IP Estat Dispositiu"
msgid "SAT>IP Information"
msgstr "SAT>IP Informació"
@@ -83,7 +86,7 @@ msgid "high"
msgstr "Alt"
msgid "Button$Devices"
msgstr ""
msgstr "Dispositius"
msgid "Operating mode"
msgstr "Mode de operació"
@@ -96,13 +99,37 @@ msgid ""
"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"
"Defineig la manera de operar els Dispositius 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 CI extension"
msgstr "Habilita la extenció CI"
msgid ""
"Define whether a CI extension shall be used.\n"
"\n"
"This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)."
msgstr ""
"Definir si s'utilitzarà una extensió de CI.\n"
"\n"
"Aquesta configuració permet utilitzar CI/CAM integrat que es troba en alguns equips SAT>IP (ex. Digital Devices OctopusNet)."
msgid "CI/CAM"
msgstr "CI/CAM"
msgid ""
"Define a desired CAM type for the CI slot.\n"
"\n"
"The '---' option lets SAT>IP hardware do the auto-selection."
msgstr ""
"Definir quin tipus de CAM vols per a la ranura CI.\n"
"\n"
"L'opció '---' permet l'equip SAT>IP fer la selecció automàtica."
msgid "Enable EPG scanning"
msgstr "Activa Escanneig EPG"
@@ -116,7 +143,7 @@ msgstr ""
"Aquesta configuració desactiva la funcionalitat d'escaneig EIT automàtica per a tots els dispositius SAT>IP."
msgid "Disabled sources"
msgstr ""
msgstr "Desactiva entrades"
msgid "none"
msgstr "no"
@@ -126,9 +153,12 @@ msgid ""
"\n"
"SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here."
msgstr ""
"Definir nombre de entrades que es desactiven.\n"
"\n"
"SAT>IP els servidors podrien no tenir totes les posicions dels satèl·lits disponibles i aquestes entrades poden ser la llista negra."
msgid "Define a source to be blacklisted."
msgstr ""
msgstr "Definir una entrada a la llista negra"
msgid "Disabled filters"
msgstr "Desactiva filtres"
@@ -149,7 +179,7 @@ msgid "Define an ill-behaving filter to be blacklisted."
msgstr "Definir un filtre mal comportar a la llista negra."
msgid "Active SAT>IP servers:"
msgstr ""
msgstr "Activa SAT>IP servers:"
msgid "Help"
msgstr "Ajuda"

View File

@@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2014 Rolf Ahrenberg
# Copyright (C) 2007-2015 Rolf Ahrenberg
# This file is distributed under the same license as the satip package.
# Frank Neumann, 2014
# Frank Neumann, 2014-2015
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-satip 1.0.0\n"
"Project-Id-Version: vdr-satip 1.0.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2014-12-24 12:24+0200\n"
"PO-Revision-Date: 2014-12-24 12:24+0200\n"
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
"Language-Team: German <vdr@linuxtv.org>\n"
"Language: de\n"
@@ -49,6 +49,9 @@ msgstr "Modell"
msgid "Description"
msgstr "Beschreibung"
msgid "CI extension"
msgstr "CI Erweiterung"
msgid "Creation date"
msgstr "Zeitpunkt der Erstellung"
@@ -83,7 +86,7 @@ msgid "high"
msgstr "hoch"
msgid "Button$Devices"
msgstr ""
msgstr "Geräte"
msgid "Operating mode"
msgstr "Betriebsmodus"
@@ -103,6 +106,30 @@ msgstr ""
"normal - Geräte arbeiten innerhalb der gewöhnlichen Parameter\n"
"hoch - Geräte arbeiten mit höchste Priorität"
msgid "Enable CI extension"
msgstr "Aktiviere CI Erweiterung"
msgid ""
"Define whether a CI extension shall be used.\n"
"\n"
"This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)."
msgstr ""
"Legt fest ob eine CI Erweiterung genutzt werden soll.\n"
"\n"
"Diese Einstellung aktiviert die Nutzung des integrierten CI/CAM einiger SAT>IP Geräte (z.B. Digital Devices OctopusNet)."
msgid "CI/CAM"
msgstr "CI/CAM"
msgid ""
"Define a desired CAM type for the CI slot.\n"
"\n"
"The '---' option lets SAT>IP hardware do the auto-selection."
msgstr ""
"Bestimmt welcher CI Einschub für ein CAM genutzt werden soll.\n"
"\n"
"Die Option '---' überlässt der SAT>IP Hardware die automatische Auswahl."
msgid "Enable EPG scanning"
msgstr "Aktiviere EPG Aktualisierung"
@@ -111,7 +138,7 @@ msgid ""
"\n"
"This setting disables the automatic EIT scanning functionality for all SAT>IP devices."
msgstr ""
"Definiert ob EPG im Hintergrund aktualisiert werden soll oder nicht.\n"
"Legt fest ob EPG im Hintergrund aktualisiert werden soll oder nicht.\n"
"\n"
"Diese Einstellung schaltet die automatische EIT Aktualisierung für alle SAT>IP Geräte."
@@ -126,7 +153,7 @@ msgid ""
"\n"
"SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here."
msgstr ""
"Definiert die Anzahl der deaktivierten Quellen.\n"
"Legt die Anzahl der deaktivierten Quellen fest.\n"
"\n"
"Für einige SAT>IP server sind nicht alle Satellitenpositionen verfügbar, nicht verfügbare Quellen können hier ausgeblendet werden"
@@ -152,7 +179,7 @@ msgid "Define an ill-behaving filter to be blacklisted."
msgstr "Bestimme einen fehlerhaften Filter der ausgeblendet werden soll."
msgid "Active SAT>IP servers:"
msgstr "Aktive SAT>IP Server"
msgstr "Aktive SAT>IP Server:"
msgid "Help"
msgstr "Hilfe"

View File

@@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2014 Rolf Ahrenberg
# Copyright (C) 2007-2015 Rolf Ahrenberg
# This file is distributed under the same license as the satip package.
# Gabriel Bonich, 2014
# Gabriel Bonich, 2014-2015
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-satip 1.0.0\n"
"Project-Id-Version: vdr-satip 1.0.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2014-12-24 12:24+0200\n"
"PO-Revision-Date: 2014-12-24 12:24+0200\n"
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
"Language-Team: Spanish <vdr@linuxtv.org>\n"
"Language: es\n"
@@ -38,7 +38,7 @@ msgid "SAT>IP Devices"
msgstr "SAT>IP Dispositivos"
msgid "SAT>IP Server"
msgstr ""
msgstr "SAT>IP Server"
msgid "Address"
msgstr "Dirección"
@@ -49,11 +49,14 @@ msgstr "Modelo"
msgid "Description"
msgstr "Descripción"
msgid "CI extension"
msgstr "Extensión CI"
msgid "Creation date"
msgstr "Fecha creación"
msgid "SAT>IP Device Status"
msgstr ""
msgstr "SAT>IP Estado del Dispositivo"
msgid "SAT>IP Information"
msgstr "SAT>IP Información"
@@ -83,7 +86,7 @@ msgid "high"
msgstr "Alto"
msgid "Button$Devices"
msgstr ""
msgstr "Dispositivos"
msgid "Operating mode"
msgstr "Modo de operación"
@@ -103,6 +106,30 @@ msgstr ""
"Normal - Dispositivos trabajando con prioridad Normal\n"
"Alta - Dispositivos trabajando con prioridad Alta"
msgid "Enable CI extension"
msgstr "Habilitar extensión CI"
msgid ""
"Define whether a CI extension shall be used.\n"
"\n"
"This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)."
msgstr ""
"Definir si se utilizará una extensión de CI.\n"
"\n"
"Esto permite la configuración CI/CAM integrado que se encuentra en algunos equipos SAT>IP (ej. Digital Devices OctopusNet)."
msgid "CI/CAM"
msgstr "CI/CAM"
msgid ""
"Define a desired CAM type for the CI slot.\n"
"\n"
"The '---' option lets SAT>IP hardware do the auto-selection."
msgstr ""
"Definir el tipo de CAM para la ranura CI.\n"
"\n"
"La opción '---' permite al equipo SAT>IP hacer la selección automática."
msgid "Enable EPG scanning"
msgstr "Activa Escaneo EPG"
@@ -116,7 +143,7 @@ msgstr ""
"Esta configuración desactiva la funcionalidad del escaneo EIT automática para todos los Dispositivos SAT>IP."
msgid "Disabled sources"
msgstr ""
msgstr "Desactiva fuentes"
msgid "none"
msgstr "no"
@@ -126,9 +153,12 @@ msgid ""
"\n"
"SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here."
msgstr ""
"Definir número de fuentes desactivadas.\n"
"\n"
"SAT>IP servidores que no tenga todas las posiciones de los satélites disponibles y estas se ponen en la lista negra."
msgid "Define a source to be blacklisted."
msgstr ""
msgstr "Define fuentes de la lista negra"
msgid "Disabled filters"
msgstr "Desactiva filtros"
@@ -149,7 +179,7 @@ msgid "Define an ill-behaving filter to be blacklisted."
msgstr "Define un filtro para poner en la lista negra."
msgid "Active SAT>IP servers:"
msgstr ""
msgstr "Activa SAT>IP servers:"
msgid "Help"
msgstr "Ayuda"

View File

@@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2014 Rolf Ahrenberg
# Copyright (C) 2007-2015 Rolf Ahrenberg
# This file is distributed under the same license as the satip package.
# Rolf Ahrenberg, 2014
# Rolf Ahrenberg, 2015
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-satip 1.0.0\n"
"Project-Id-Version: vdr-satip 1.0.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2014-12-24 12:24+0200\n"
"PO-Revision-Date: 2014-12-24 12:24+0200\n"
"POT-Creation-Date: 2015-01-18 01:18+0200\n"
"PO-Revision-Date: 2015-01-18 01:18+0200\n"
"Last-Translator: Rolf Ahrenberg\n"
"Language-Team: Finnish <vdr@linuxtv.org>\n"
"Language: fi\n"
@@ -49,6 +49,9 @@ msgstr "Malli"
msgid "Description"
msgstr "Kuvaus"
msgid "CI extension"
msgstr "CI-laajennos"
msgid "Creation date"
msgstr "Luontiajankohta"
@@ -102,6 +105,30 @@ msgstr ""
"normaali - laitteet toimivat normaalilla prioriteetilla\n"
"korkea - laitteet toimivat korkealla prioriteetilla"
msgid "Enable CI extension"
msgstr "Käytä CI-laajennosta"
msgid ""
"Define whether a CI extension shall be used.\n"
"\n"
"This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)."
msgstr ""
"Määrittele CI-laajennoksen käyttöönotto\n"
"\n"
"Tällä asetuksella saadaan otettua käyttöön SAT>IP-laitteiden sisäinen CI-paikka (esim. Digital Devices OctopusNet)."
msgid "CI/CAM"
msgstr "CI/CAM"
msgid ""
"Define a desired CAM type for the CI slot.\n"
"\n"
"The '---' option lets SAT>IP hardware do the auto-selection."
msgstr ""
"Määrittele haluttu CAM-tyyppi CI-paikalle.\n"
"\n"
"Vaihtoehto '---' antaa SAT>IP-laitteen valita automaattisesti käytetyn CI-paikan."
msgid "Enable EPG scanning"
msgstr "Käytä ohjelmaoppaan taustapäivitystä"

2
rtcp.c
View File

@@ -50,7 +50,7 @@ int cSatipRtcp::GetApplicationOffset(int *lengthP)
//unsigned int st = bufferM[offset] & 0x1F;
// Payload type
unsigned int pt = bufferM[offset + 1] & 0xFF;
// Lenght
// Length
unsigned int length = ((bufferM[offset + 2] & 0xFF) << 8) | (bufferM[offset + 3] & 0xFF);
// Convert it to bytes
length = (length + 1) * 4;

2
rtcp.h
View File

@@ -20,7 +20,7 @@ private:
cSatipTunerIf &tunerM;
unsigned int bufferLenM;
unsigned char *bufferM;
int GetApplicationOffset(int *lenghtP);
int GetApplicationOffset(int *lengthP);
public:
cSatipRtcp(cSatipTunerIf &tunerP);

6
rtp.c
View File

@@ -51,7 +51,7 @@ void cSatipRtp::Close(void)
}
}
int cSatipRtp::GetHeaderLenght(unsigned char *bufferP, unsigned int lengthP)
int cSatipRtp::GetHeaderLength(unsigned char *bufferP, unsigned int lengthP)
{
debug16("%s (, %d) [device %d]", __PRETTY_FUNCTION__, lengthP, tunerM.GetId());
unsigned int headerlen = 0;
@@ -88,7 +88,7 @@ int cSatipRtp::GetHeaderLenght(unsigned char *bufferP, unsigned int lengthP)
}
else
sequenceNumberM = seq;
// Header lenght
// Header length
headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t);
// Check if extension
if (x) {
@@ -130,7 +130,7 @@ void cSatipRtp::Process(void)
count = ReadMulti(bufferM, lenMsg, eRtpPacketReadCount, eMaxUdpPacketSizeB);
for (int i = 0; i < count; ++i) {
unsigned char *p = &bufferM[i * eMaxUdpPacketSizeB];
int headerlen = GetHeaderLenght(p, lenMsg[i]);
int headerlen = GetHeaderLength(p, lenMsg[i]);
if ((headerlen >= 0) && (headerlen < (int)lenMsg[i]))
tunerM.ProcessVideoData(p + headerlen, lenMsg[i] - headerlen);
}

2
rtp.h
View File

@@ -25,7 +25,7 @@ private:
time_t lastErrorReportM;
int packetErrorsM;
int sequenceNumberM;
int GetHeaderLenght(unsigned char *bufferP, unsigned int lengthP);
int GetHeaderLength(unsigned char *bufferP, unsigned int lengthP);
public:
cSatipRtp(cSatipTunerIf &tunerP);

75
satip.c
View File

@@ -27,7 +27,7 @@
#define GITVERSION ""
#endif
const char VERSION[] = "1.0.0" GITVERSION;
const char VERSION[] = "1.0.2" GITVERSION;
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
class cPluginSatip : public cPlugin {
@@ -35,6 +35,7 @@ private:
unsigned int deviceCountM;
cSatipDiscoverServers *serversM;
void ParseServer(const char *paramP);
int ParseCicams(const char *valueP, int *cicamsP);
int ParseSources(const char *valueP, int *sourcesP);
int ParseFilters(const char *valueP, int *filtersP);
public:
@@ -81,8 +82,11 @@ const char *cPluginSatip::CommandLineHelp(void)
debug1("%s", __PRETTY_FUNCTION__);
// Return a string that describes all known command line options.
return " -d <num>, --devices=<number> set number of devices to be created\n"
" -t <mode>, --trace=<mode> set the tracing mode\n"
" -s <ipaddr>|<model>|<desc>, --server=<ipaddr1>|<model1>|<desc1>;<ipaddr2>|<model2>|<desc2>\n"
" define hard-coded SAT>IP server(s)\n";
" define hard-coded SAT>IP server(s)"
" -S, --single set the single model server mode on\n"
" -n, --noquirks disable all the server quirks\n";
}
bool cPluginSatip::ProcessArgs(int argc, char *argv[])
@@ -90,14 +94,17 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
debug1("%s", __PRETTY_FUNCTION__);
// Implement command line argument processing here if applicable.
static const struct option long_options[] = {
{ "devices", required_argument, NULL, 'd' },
{ "trace", required_argument, NULL, 't' },
{ "server", required_argument, NULL, 's' },
{ NULL, no_argument, NULL, 0 }
{ "devices", required_argument, NULL, 'd' },
{ "trace", required_argument, NULL, 't' },
{ "server", required_argument, NULL, 's' },
{ "single", no_argument, NULL, 'S' },
{ "noquirks", no_argument, NULL, 'n' },
{ NULL, no_argument, NULL, 0 }
};
cString server;
int c;
while ((c = getopt_long(argc, argv, "d:t:s:", long_options, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "d:t:s:Sn", long_options, NULL)) != -1) {
switch (c) {
case 'd':
deviceCountM = strtol(optarg, NULL, 0);
@@ -106,12 +113,21 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
SatipConfig.SetTraceMode(strtol(optarg, NULL, 0));
break;
case 's':
ParseServer(optarg);
server = optarg;
break;
case 'S':
SatipConfig.SetUseSingleModelServers(true);
break;
case 'n':
SatipConfig.SetDisableServerQuirks(true);
break;
default:
return false;
}
}
// this must be done after all parameters are parsed
if (!isempty(*server))
ParseServer(*server);
return true;
}
@@ -121,7 +137,6 @@ bool cPluginSatip::Initialize(void)
// Initialize any background activities the plugin shall perform.
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
error("Unable to initialize CURL");
SatipConfig.SetConfigDirectory(cPlugin::ResourceDirectory(PLUGIN_NAME_I18N));
cSatipPoller::GetInstance()->Initialize();
cSatipDiscover::GetInstance()->Initialize(serversM);
return cSatipDevice::Initialize(deviceCountM);
@@ -197,7 +212,7 @@ void cPluginSatip::ParseServer(const char *paramP)
{
debug1("%s (%s)", __PRETTY_FUNCTION__, paramP);
int n = 0;
char *s, *p = (char *)paramP;
char *s, *p = strdup(paramP);
char *r = strtok_r(p, ";", &s);
while (r) {
r = skipspace(r);
@@ -232,13 +247,32 @@ void cPluginSatip::ParseServer(const char *paramP)
++n;
r = strtok_r(NULL, ";", &s);
}
FREE_POINTER(p);
}
int cPluginSatip::ParseCicams(const char *valueP, int *cicamsP)
{
debug1("%s (%s,)", __PRETTY_FUNCTION__, valueP);
int n = 0;
char *s, *p = strdup(valueP);
char *r = strtok_r(p, " ", &s);
while (r) {
r = skipspace(r);
debug3("%s cicams[%d]=%s", __PRETTY_FUNCTION__, n, r);
if (n < MAX_CICAM_COUNT) {
cicamsP[n++] = atoi(r);
}
r = strtok_r(NULL, " ", &s);
}
FREE_POINTER(p);
return n;
}
int cPluginSatip::ParseSources(const char *valueP, int *sourcesP)
{
debug1("%s (%s,)", __PRETTY_FUNCTION__, valueP);
int n = 0;
char *s, *p = (char *)valueP;
char *s, *p = strdup(valueP);
char *r = strtok_r(p, " ", &s);
while (r) {
r = skipspace(r);
@@ -246,8 +280,9 @@ int cPluginSatip::ParseSources(const char *valueP, int *sourcesP)
if (n < MAX_DISABLED_SOURCES_COUNT) {
sourcesP[n++] = cSource::FromString(r);
}
r = strtok_r(NULL, " \n", &s);
r = strtok_r(NULL, " ", &s);
}
FREE_POINTER(p);
return n;
}
@@ -259,7 +294,7 @@ int cPluginSatip::ParseFilters(const char *valueP, int *filtersP)
while (valueP && *valueP && (n < SECTION_FILTER_TABLE_SIZE)) {
strn0cpy(buffer, valueP, sizeof(buffer));
int i = atoi(buffer);
debug3(":%s filters[%d]=%d", __PRETTY_FUNCTION__, n, i);
debug3("%s filters[%d]=%d", __PRETTY_FUNCTION__, n, i);
if (i >= 0)
filtersP[n++] = i;
if ((valueP = strchr(valueP, ' ')) != NULL)
@@ -274,11 +309,21 @@ bool cPluginSatip::SetupParse(const char *nameP, const char *valueP)
// Parse your own setup parameters and store their values.
if (!strcasecmp(nameP, "OperatingMode"))
SatipConfig.SetOperatingMode(atoi(valueP));
else if (!strcasecmp(nameP, "EnableCIExtension"))
SatipConfig.SetCIExtension(atoi(valueP));
else if (!strcasecmp(nameP, "CICAM")) {
int Cicams[MAX_CICAM_COUNT];
for (unsigned int i = 0; i < ELEMENTS(Cicams); ++i)
Cicams[i] = 0;
unsigned int CicamsCount = ParseCicams(valueP, Cicams);
for (unsigned int i = 0; i < CicamsCount; ++i)
SatipConfig.SetCICAM(i, Cicams[i]);
}
else if (!strcasecmp(nameP, "EnableEITScan"))
SatipConfig.SetEITScan(atoi(valueP));
else if (!strcasecmp(nameP, "DisabledSources")) {
int DisabledSources[MAX_DISABLED_SOURCES_COUNT];
for (unsigned int i = 0; i < ARRAY_SIZE(DisabledSources); ++i)
for (unsigned int i = 0; i < ELEMENTS(DisabledSources); ++i)
DisabledSources[i] = cSource::stNone;
unsigned int DisabledSourcesCount = ParseSources(valueP, DisabledSources);
for (unsigned int i = 0; i < DisabledSourcesCount; ++i)
@@ -286,7 +331,7 @@ bool cPluginSatip::SetupParse(const char *nameP, const char *valueP)
}
else if (!strcasecmp(nameP, "DisabledFilters")) {
int DisabledFilters[SECTION_FILTER_TABLE_SIZE];
for (unsigned int i = 0; i < ARRAY_SIZE(DisabledFilters); ++i)
for (unsigned int i = 0; i < ELEMENTS(DisabledFilters); ++i)
DisabledFilters[i] = -1;
unsigned int DisabledFiltersCount = ParseFilters(valueP, DisabledFilters);
for (unsigned int i = 0; i < DisabledFiltersCount; ++i)

View File

@@ -15,9 +15,9 @@
// --- cSatipServer -----------------------------------------------------------
cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char *descriptionP)
: addressM(addressP),
modelM(modelP),
descriptionM(descriptionP),
: addressM((addressP && *addressP) ? addressP : "0.0.0.0"),
modelM((modelP && *modelP) ? modelP : "DVBS-1"),
descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"),
modelTypeM(eSatipModelTypeNone),
quirkM(eSatipQuirkNone),
useCountM(0),
@@ -26,9 +26,8 @@ cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char
lastSeenM(0)
{
memset(modelCountM, 0, sizeof(modelCountM));
if (isempty(*modelM))
modelM = "DVBS-1";
if (!isempty(*descriptionM)) {
if (!SatipConfig.GetDisableServerQuirks()) {
debug3("%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM);
// These devices contain a session id bug:
// Inverto Airscreen Server IDL 400 ?
// Elgato EyeTV Netstream 4Sat ?
@@ -45,44 +44,41 @@ cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char
quirkM |= eSatipQuirkForceLock;
if (quirkM != eSatipQuirkNone)
info("Malfunctioning '%s' server detected! Please, fix the firmware.", *descriptionM);
}
}
// These devices support the X_PMT protocol extension
if (strstr(*descriptionM, "OctopusNet")) // Digital Devices OctopusNet
quirkM |= eSatipQuirkUseXCI;
char *s, *p = strdup(*modelM);
char *r = strtok_r(p, ",", &s);
while (r) {
if (strstr(r, "DVBS2")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBS2;
if (strstr(r, "DVBS2-")) {
modelTypeM |= eSatipModelTypeDVBS2;
if (char *c = strstr(r, "-"))
modelCountM[eSatipModuleDVBS2] = atoi(++c);
else
modelCountM[eSatipModuleDVBS2] = 1;
}
if (strstr(r, "DVBT2")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBT2;
else if (strstr(r, "DVBT2-")) {
modelTypeM |= eSatipModelTypeDVBT2;
if (char *c = strstr(r, "-"))
modelCountM[eSatipModuleDVBT2] = atoi(++c);
else
modelCountM[eSatipModuleDVBT2] = 1;
modelTypeM |= eSatipModelTypeDVBT;
modelCountM[eSatipModuleDVBT] = modelCountM[eSatipModuleDVBT2];
}
if (strstr(r, "DVBT")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBT;
else if (strstr(r, "DVBT-")) {
modelTypeM |= eSatipModelTypeDVBT;
if (char *c = strstr(r, "-"))
modelCountM[eSatipModuleDVBT] = atoi(++c);
else
modelCountM[eSatipModuleDVBT] = 1;
}
if (strstr(r, "DVBC2")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBC2;
else if (strstr(r, "DVBC2-")) {
modelTypeM |= eSatipModelTypeDVBC2;
if (char *c = strstr(r, "-"))
modelCountM[eSatipModuleDVBC2] = atoi(++c);
else
modelCountM[eSatipModuleDVBC2] = 1;
modelTypeM |= eSatipModelTypeDVBC;
modelCountM[eSatipModuleDVBC] = modelCountM[eSatipModuleDVBC2];
}
if (strstr(r, "DVBC")) {
modelTypeM |= cSatipServer::eSatipModelTypeDVBC;
else if (strstr(r, "DVBC-")) {
modelTypeM |= eSatipModelTypeDVBC;
if (char *c = strstr(r, "-"))
modelCountM[eSatipModuleDVBC] = atoi(++c);
else
modelCountM[eSatipModuleDVBC] = 1;
}
r = strtok_r(NULL, ",", &s);
}
@@ -96,7 +92,13 @@ cSatipServer::~cSatipServer()
int cSatipServer::Compare(const cListObject &listObjectP) const
{
const cSatipServer *s = (const cSatipServer *)&listObjectP;
return strcasecmp(*addressM, *s->addressM);
int result = strcasecmp(*addressM, *s->addressM);
if (!result) {
result = strcasecmp(*modelM, *s->modelM);
if (!result)
result = strcasecmp(*descriptionM, *s->descriptionM);
}
return result;
}
void cSatipServer::Use(bool onOffP)
@@ -147,7 +149,7 @@ cSatipServer *cSatipServers::Find(int sourceP, int transponderP, int systemP)
return result;
}
void cSatipServers::SetTransponder(cSatipServer *serverP, bool transponderP)
void cSatipServers::SetTransponder(cSatipServer *serverP, int transponderP)
{
for (cSatipServer *s = First(); s; s = Next(s)) {
if (s == serverP) {

View File

@@ -37,6 +37,7 @@ public:
eSatipQuirkSessionId = 0x01,
eSatipQuirkPlayPids = 0x02,
eSatipQuirkForceLock = 0x04,
eSatipQuirkUseXCI = 0x08,
eSatipQuirkMask = 0x0F
};
enum eSatipModelType {
@@ -77,7 +78,7 @@ class cSatipServers : public cList<cSatipServer> {
public:
cSatipServer *Find(cSatipServer *serverP);
cSatipServer *Find(int sourceP, int transponderP, int systemP);
void SetTransponder(cSatipServer *serverP, bool transponderP);
void SetTransponder(cSatipServer *serverP, int transponderP);
cSatipServer *Update(cSatipServer *serverP);
void Use(cSatipServer *serverP, bool onOffP);
void Cleanup(uint64_t intervalMsP = 0);

44
setup.c
View File

@@ -89,6 +89,7 @@ private:
cString addressM;
cString modelM;
cString descriptionM;
cString ciExtensionM;
uint64_t createdM;
void Setup(void);
@@ -103,6 +104,7 @@ cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP)
addressM(serverP ? serverP->Address() : "---"),
modelM(serverP ? serverP->Model() : "---"),
descriptionM(serverP ? serverP->Description() : "---"),
ciExtensionM(serverP && serverP->Quirk(cSatipServer::eSatipQuirkUseXCI) ? trVDR("yes") : trVDR("no")),
createdM(serverP ? serverP->Created() : 0)
{
SetMenuCategory(mcSetupPlugins);
@@ -119,6 +121,7 @@ void cSatipServerInfo::Setup(void)
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("CI extension"), *ciExtensionM), osUnknown, false));
Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Creation date"), *DayDateTime(createdM)), osUnknown, false));
}
@@ -329,6 +332,7 @@ eOSState cSatipMenuInfo::ProcessKey(eKeys keyP)
cSatipPluginSetup::cSatipPluginSetup()
: deviceCountM(0),
operatingModeM(SatipConfig.GetOperatingMode()),
ciExtensionM(SatipConfig.GetCIExtension()),
eitScanM(SatipConfig.GetEITScan()),
numDisabledSourcesM(SatipConfig.GetDisabledSourcesCount()),
numDisabledFiltersM(SatipConfig.GetDisabledFiltersCount())
@@ -338,6 +342,10 @@ cSatipPluginSetup::cSatipPluginSetup()
operatingModeTextsM[cSatipConfig::eOperatingModeLow] = tr("low");
operatingModeTextsM[cSatipConfig::eOperatingModeNormal] = tr("normal");
operatingModeTextsM[cSatipConfig::eOperatingModeHigh] = tr("high");
for (unsigned int i = 0; i < ELEMENTS(cicamsM); ++i)
cicamsM[i] = SatipConfig.GetCICAM(i);
for (unsigned int i = 0; i < ELEMENTS(ca_systems_table); ++i)
cicamTextsM[i] = ca_systems_table[i].description;
if (numDisabledSourcesM > MAX_DISABLED_SOURCES_COUNT)
numDisabledSourcesM = MAX_DISABLED_SOURCES_COUNT;
for (int i = 0; i < MAX_DISABLED_SOURCES_COUNT; ++i)
@@ -364,6 +372,14 @@ void cSatipPluginSetup::Setup(void)
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"));
if (operatingModeM) {
Add(new cMenuEditBoolItem(tr("Enable CI extension"), &ciExtensionM));
helpM.Append(tr("Define whether a CI extension shall be used.\n\nThis setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)."));
for (unsigned int i = 0; ciExtensionM && i < ELEMENTS(cicamsM); ++i) {
Add(new cMenuEditStraItem(*cString::sprintf(" %s #%d", tr("CI/CAM"), i + 1), &cicamsM[i], ELEMENTS(cicamTextsM), cicamTextsM));
helpM.Append(tr("Define a desired CAM type for the CI slot.\n\nThe '---' option lets SAT>IP hardware do the auto-selection."));
}
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."));
@@ -440,6 +456,7 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
{
bool hadSubMenu = HasSubMenu();
int oldOperatingMode = operatingModeM;
int oldCiExtension = ciExtensionM;
int oldNumDisabledSources = numDisabledSourcesM;
int oldNumDisabledFilters = numDisabledFiltersM;
eOSState state = cMenuSetupPage::ProcessKey(keyP);
@@ -463,7 +480,7 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
if ((keyP == kNone) && (cSatipDiscover::GetInstance()->GetServers()->Count() != deviceCountM))
Setup();
if ((keyP != kNone) && ((numDisabledSourcesM != oldNumDisabledSources) || (numDisabledFiltersM != oldNumDisabledFilters) || (operatingModeM != oldOperatingMode))) {
if ((keyP != kNone) && ((numDisabledSourcesM != oldNumDisabledSources) || (numDisabledFiltersM != oldNumDisabledFilters) || (operatingModeM != oldOperatingMode) || (ciExtensionM != oldCiExtension))) {
while ((numDisabledSourcesM < oldNumDisabledSources) && (oldNumDisabledSources > 0))
disabledSourcesM[--oldNumDisabledSources] = cSource::stNone;
while ((numDisabledFiltersM < oldNumDisabledFilters) && (oldNumDisabledFilters > 0))
@@ -474,6 +491,22 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP)
return state;
}
void cSatipPluginSetup::StoreCicams(const char *nameP, int *cicamsP)
{
cString buffer = "";
int n = 0;
for (int i = 0; i < MAX_CICAM_COUNT; ++i) {
if (cicamsP[i] < 0)
break;
if (n++ > 0)
buffer = cString::sprintf("%s %d", *buffer, cicamsP[i]);
else
buffer = cString::sprintf("%d", cicamsP[i]);
}
debug3("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer);
SetupStore(nameP, *buffer);
}
void cSatipPluginSetup::StoreSources(const char *nameP, int *sourcesP)
{
cString buffer = "";
@@ -486,7 +519,7 @@ void cSatipPluginSetup::StoreSources(const char *nameP, int *sourcesP)
else
buffer = cString::sprintf("%s", *cSource::ToString(sourcesP[i]));
}
debug1("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer);
debug3("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer);
SetupStore(nameP, *buffer);
}
@@ -502,7 +535,7 @@ void cSatipPluginSetup::StoreFilters(const char *nameP, int *valuesP)
else
buffer = cString::sprintf("%d", valuesP[i]);
}
debug1("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer);
debug3("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer);
SetupStore(nameP, *buffer);
}
@@ -510,12 +543,17 @@ void cSatipPluginSetup::Store(void)
{
// Store values into setup.conf
SetupStore("OperatingMode", operatingModeM);
SetupStore("EnableCIExtension", ciExtensionM);
SetupStore("EnableEITScan", eitScanM);
StoreCicams("CICAM", cicamsM);
StoreSources("DisabledSources", disabledSourcesM);
StoreFilters("DisabledFilters", disabledFilterIndexesM);
// Update global config
SatipConfig.SetOperatingMode(operatingModeM);
SatipConfig.SetCIExtension(ciExtensionM);
SatipConfig.SetEITScan(eitScanM);
for (int i = 0; i < MAX_CICAM_COUNT; ++i)
SatipConfig.SetCICAM(i, cicamsM[i]);
for (int i = 0; i < MAX_DISABLED_SOURCES_COUNT; ++i)
SatipConfig.SetDisabledSources(i, disabledSourcesM[i]);
for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i)

View File

@@ -18,6 +18,9 @@ private:
int deviceCountM;
int operatingModeM;
const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
int ciExtensionM;
int cicamsM[MAX_CICAM_COUNT];
const char *cicamTextsM[CA_SYSTEMS_TABLE_SIZE];
int eitScanM;
int numDisabledSourcesM;
int disabledSourcesM[MAX_DISABLED_SOURCES_COUNT];
@@ -31,6 +34,7 @@ private:
eOSState ShowDeviceStatus(void);
eOSState ShowInfo(void);
void Setup(void);
void StoreCicams(const char *nameP, int *cicamsP);
void StoreSources(const char *nameP, int *sourcesP);
void StoreFilters(const char *nameP, int *valuesP);

View File

@@ -136,6 +136,7 @@ int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP)
int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRecvSizeP, unsigned int elementCountP, unsigned int elementBufferSizeP)
{
debug16("%s (, , %d, %d)", __PRETTY_FUNCTION__, elementCountP, elementBufferSizeP);
#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,12)
// Error out if socket not initialized
if (socketDescM <= 0) {
error("%s Invalid socket", __PRETTY_FUNCTION__);
@@ -159,6 +160,17 @@ int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRec
ERROR_IF_RET(count < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmmsg()", return -1);
for (int i = 0; i < count; ++i)
elementRecvSizeP[i] = mmsgh[i].msg_len;
#else
int count = 0;
while (count < (int)elementCountP) {
int len = Read(bufferAddrP + count * elementBufferSizeP, elementBufferSizeP);
if (len < 0)
return -1;
else if (len == 0)
break;
elementRecvSizeP[count++] = len;
}
#endif
debug16("%s Received %d packets size[0]=%d", __PRETTY_FUNCTION__, count, elementRecvSizeP[0]);
return count;

31
tuner.c
View File

@@ -41,6 +41,7 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
signalStrengthM(-1),
signalQualityM(-1),
streamIdM(-1),
pmtPidM(-1),
addPidsM(),
delPidsM(),
pidsM()
@@ -186,8 +187,6 @@ bool cSatipTuner::Connect(void)
// Just retune
if (streamIdM >= 0) {
cString uri = cString::sprintf("%sstream=%d?%s", *connectionUri, streamIdM, *streamParamM);
//if (pidsM.Size())
// uri = cString::sprintf("%s&pids=%s", *uri, *pidsM.ListPids());
debug1("%s Retuning [device %d]", __PRETTY_FUNCTION__, deviceIdM);
if (rtspM.Play(*uri)) {
keepAliveM.Set(timeoutM);
@@ -226,6 +225,8 @@ bool cSatipTuner::Disconnect(void)
if (!isempty(*streamAddrM) && (streamIdM >= 0)) {
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
rtspM.Teardown(*uri);
// some devices requires a teardown for TCP connection also
rtspM.Reset();
streamIdM = -1;
}
@@ -238,6 +239,7 @@ bool cSatipTuner::Disconnect(void)
cSatipDiscover::GetInstance()->UseServer(currentServerM, false);
statusUpdateM.Set(0);
timeoutM = eMinKeepAliveIntervalMs;
pmtPidM = -1;
addPidsM.Clear();
delPidsM.Clear();
@@ -290,7 +292,7 @@ void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP)
// -65dBm corresponds to 32
// No signal corresponds to 0
c = strstr(c, ",");
value = atoi(++c);
value = min(atoi(++c), 255);
// Scale value to 0-100
signalStrengthM = (value >= 0) ? (value * 100 / 255) : -1;
@@ -308,7 +310,7 @@ void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP)
// -a BER lower than 2x10-4 after Viterbi for DVB-S
// -a PER lower than 10-7 for DVB-S2
c = strstr(c, ",");
value = atoi(++c);
value = min(atoi(++c), 15);
// Scale value to 0-100
signalQualityM = (hasLockM && (value >= 0)) ? (value * 100 / 15) : 0;
}
@@ -375,8 +377,7 @@ bool cSatipTuner::SetPid(int pidP, int typeP, bool onP)
delPidsM.AddPid(pidP);
addPidsM.RemovePid(pidP);
}
debug9("%s (%d, %d, %d) pids=%s [device %d]", __PRETTY_FUNCTION__, pidP, typeP, onP, *pidsM.ListPids(), deviceIdM);
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
debug12("%s (%d, %d, %d) pids=%s [device %d]", __PRETTY_FUNCTION__, pidP, typeP, onP, *pidsM.ListPids(), deviceIdM);
sleepM.Signal();
return true;
@@ -389,6 +390,7 @@ bool cSatipTuner::UpdatePids(bool forceP)
if (((forceP && pidsM.Size()) || (pidUpdateCacheM.TimedOut() && (addPidsM.Size() || delPidsM.Size()))) &&
!isempty(*streamAddrM) && (streamIdM > 0)) {
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
bool useci = (SatipConfig.GetCIExtension() && !!(currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkUseXCI)));
bool usedummy = !!(currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkPlayPids));
if (forceP || usedummy) {
if (pidsM.Size())
@@ -402,6 +404,23 @@ bool cSatipTuner::UpdatePids(bool forceP)
if (delPidsM.Size())
uri = cString::sprintf("%s%sdelpids=%s", *uri, addPidsM.Size() ? "&" : "?", *delPidsM.ListPids());
}
if (useci) {
// CI extension parameters:
// - x_pmt : specifies the PMT of the service you want the CI to decode
// - x_ci : specfies which CI slot (1..n) to use
// value 0 releases the CI slot
// CI slot released automatically if the stream is released,
// but not when used retuning to another channel
int pid = deviceM->GetPmtPid();
if ((pid > 0) && (pid != pmtPidM)) {
int slot = deviceM->GetCISlot();
uri = cString::sprintf("%s&x_pmt=%d", *uri, pid);
if (slot > 0)
uri = cString::sprintf("%s&x_ci=%d", *uri, slot);
}
pmtPidM = pid;
}
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
if (!rtspM.Play(*uri))
return false;
addPidsM.Clear();

44
tuner.h
View File

@@ -8,6 +8,7 @@
#ifndef __SATIP_TUNER_H
#define __SATIP_TUNER_H
#include <vdr/config.h> // APIVERSNUM
#include <vdr/thread.h>
#include <vdr/tools.h>
@@ -20,7 +21,14 @@
class cSatipPid : public cVector<int> {
private:
int PidIndex(const int &pidP)
static int PidCompare(const void *aPidP, const void *bPidP)
{
return (*(int*)aPidP - *(int*)bPidP);
}
public:
#if defined(APIVERSNUM) && APIVERSNUM < 20107
int IndexOf(const int &pidP)
{
for (int i = 0; i < Size(); ++i) {
if (pidP == At(i))
@@ -28,26 +36,33 @@ private:
}
return -1;
}
static int PidCompare(const void *aPidP, const void *bPidP)
bool RemoveElement(const int &pidP)
{
return (*(int*)aPidP - *(int*)bPidP);
}
public:
void RemovePid(const int &pidP)
{
int i = PidIndex(pidP);
int i = IndexOf(pidP);
if (i >= 0) {
Remove(i);
Sort(PidCompare);
return true;
}
return false;
}
bool AppendUnique(int pidP)
{
if (IndexOf(pidP) < 0) {
Append(pidP);
return true;
}
return false;
}
#endif
void RemovePid(const int &pidP)
{
if (RemoveElement(pidP))
Sort(PidCompare);
}
void AddPid(int pidP)
{
if (PidIndex(pidP) < 0) {
Append(pidP);
if (AppendUnique(pidP))
Sort(PidCompare);
}
}
cString ListPids(void)
{
@@ -68,7 +83,7 @@ private:
eDummyPid = 100,
eDefaultSignalStrength = 15,
eDefaultSignalQuality = 224,
eSleepTimeoutMs = 1000, // in milliseconds
eSleepTimeoutMs = 250, // in milliseconds
eStatusUpdateTimeoutMs = 1000, // in milliseconds
ePidUpdateIntervalMs = 250, // in milliseconds
eConnectTimeoutMs = 5000, // in milliseconds
@@ -101,6 +116,7 @@ private:
int signalStrengthM;
int signalQualityM;
int streamIdM;
int pmtPidM;
cSatipPid addPidsM;
cSatipPid delPidsM;
cSatipPid pidsM;

View File

@@ -12,8 +12,8 @@ class cSatipTunerIf {
public:
cSatipTunerIf() {}
virtual ~cSatipTunerIf() {}
virtual void ProcessVideoData(u_char *bufferP, int lenghtP) = 0;
virtual void ProcessApplicationData(u_char *bufferP, int lenghtP) = 0;
virtual void ProcessVideoData(u_char *bufferP, int lengthP) = 0;
virtual void ProcessApplicationData(u_char *bufferP, int lengthP) = 0;
virtual void SetStreamId(int streamIdP) = 0;
virtual void SetSessionTimeout(const char *sessionP, int timeoutP) = 0;
virtual int GetId(void) = 0;