mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 13:37:42 +02:00
Merge branch 'vdr-2.2.x' of https://github.com/rofafor/vdr-plugin-satip into vdr-2.2.x
This commit is contained in:
commit
462d83d0fd
8
README
8
README
@ -116,6 +116,11 @@ Setup menu:
|
|||||||
"Disable filter" options which allow you
|
"Disable filter" options which allow you
|
||||||
to disable the individual section filters.
|
to disable the individual section filters.
|
||||||
Valid range: "none" = 0 ... 7
|
Valid range: "none" = 0 ... 7
|
||||||
|
- Transport mode = unicast If you want to use the non-standard
|
||||||
|
multicast RTP-over-TCP transport mode, set this option
|
||||||
|
rtp-o-tcp accordingly. Otherwise, the transport
|
||||||
|
mode will be RTP-over-UDP via unicast or
|
||||||
|
multicast.
|
||||||
- [Red:Scan] Forces network scanning of SAT>IP hardware.
|
- [Red:Scan] Forces network scanning of SAT>IP hardware.
|
||||||
- [Yellow:Devices] Opens SAT>IP device status menu.
|
- [Yellow:Devices] Opens SAT>IP device status menu.
|
||||||
- [Blue:Info] Opens SAT>IP information/statistics menu.
|
- [Blue:Info] Opens SAT>IP information/statistics menu.
|
||||||
@ -131,6 +136,9 @@ Information menu:
|
|||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
|
- If you are having problems receiving DVB-S2 channels, make sure your
|
||||||
|
channels.conf entry contains correct pilot tone setting.
|
||||||
|
|
||||||
- The stream id "-1" states about unsuccessful tuning. This might be a
|
- The stream id "-1" states about unsuccessful tuning. This might be a
|
||||||
result of invalid channel parameters or lack of free SAT>IP tuners.
|
result of invalid channel parameters or lack of free SAT>IP tuners.
|
||||||
|
|
||||||
|
2
config.c
2
config.c
@ -19,7 +19,7 @@ cSatipConfig::cSatipConfig(void)
|
|||||||
useBytesM(1),
|
useBytesM(1),
|
||||||
portRangeStartM(0),
|
portRangeStartM(0),
|
||||||
portRangeStopM(0),
|
portRangeStopM(0),
|
||||||
useRtpOverTcpM(false),
|
transportModeM(eTransportModeUnicast),
|
||||||
detachedModeM(false),
|
detachedModeM(false),
|
||||||
disableServerQuirksM(false),
|
disableServerQuirksM(false),
|
||||||
useSingleModelServersM(false)
|
useSingleModelServersM(false)
|
||||||
|
15
config.h
15
config.h
@ -21,7 +21,7 @@ private:
|
|||||||
unsigned int useBytesM;
|
unsigned int useBytesM;
|
||||||
unsigned int portRangeStartM;
|
unsigned int portRangeStartM;
|
||||||
unsigned int portRangeStopM;
|
unsigned int portRangeStopM;
|
||||||
bool useRtpOverTcpM;
|
unsigned int transportModeM;
|
||||||
bool detachedModeM;
|
bool detachedModeM;
|
||||||
bool disableServerQuirksM;
|
bool disableServerQuirksM;
|
||||||
bool useSingleModelServersM;
|
bool useSingleModelServersM;
|
||||||
@ -37,6 +37,12 @@ public:
|
|||||||
eOperatingModeHigh,
|
eOperatingModeHigh,
|
||||||
eOperatingModeCount
|
eOperatingModeCount
|
||||||
};
|
};
|
||||||
|
enum eTransportMode {
|
||||||
|
eTransportModeUnicast = 0,
|
||||||
|
eTransportModeMulticast,
|
||||||
|
eTransportModeRtpOverTcp,
|
||||||
|
eTransportModeCount
|
||||||
|
};
|
||||||
enum eTraceMode {
|
enum eTraceMode {
|
||||||
eTraceModeNormal = 0x0000,
|
eTraceModeNormal = 0x0000,
|
||||||
eTraceModeDebug1 = 0x0001,
|
eTraceModeDebug1 = 0x0001,
|
||||||
@ -70,7 +76,10 @@ public:
|
|||||||
int GetCICAM(unsigned int indexP) const;
|
int GetCICAM(unsigned int indexP) const;
|
||||||
unsigned int GetEITScan(void) const { return eitScanM; }
|
unsigned int GetEITScan(void) const { return eitScanM; }
|
||||||
unsigned int GetUseBytes(void) const { return useBytesM; }
|
unsigned int GetUseBytes(void) const { return useBytesM; }
|
||||||
bool GetUseRtpOverTcp(void) const { return useRtpOverTcpM; }
|
unsigned int GetTransportMode(void) const { return transportModeM; }
|
||||||
|
bool IsTransportModeUnicast(void) const { return (transportModeM == eTransportModeUnicast); }
|
||||||
|
bool IsTransportModeRtpOverTcp(void) const { return (transportModeM == eTransportModeRtpOverTcp); }
|
||||||
|
bool IsTransportModeMulticast(void) const { return (transportModeM == eTransportModeMulticast); }
|
||||||
bool GetDetachedMode(void) const { return detachedModeM; }
|
bool GetDetachedMode(void) const { return detachedModeM; }
|
||||||
bool GetDisableServerQuirks(void) const { return disableServerQuirksM; }
|
bool GetDisableServerQuirks(void) const { return disableServerQuirksM; }
|
||||||
bool GetUseSingleModelServers(void) const { return useSingleModelServersM; }
|
bool GetUseSingleModelServers(void) const { return useSingleModelServersM; }
|
||||||
@ -87,7 +96,7 @@ public:
|
|||||||
void SetCICAM(unsigned int indexP, int cicamP);
|
void SetCICAM(unsigned int indexP, int cicamP);
|
||||||
void SetEITScan(unsigned int onOffP) { eitScanM = onOffP; }
|
void SetEITScan(unsigned int onOffP) { eitScanM = onOffP; }
|
||||||
void SetUseBytes(unsigned int onOffP) { useBytesM = onOffP; }
|
void SetUseBytes(unsigned int onOffP) { useBytesM = onOffP; }
|
||||||
void SetUseRtpOverTcp(bool onOffP) { useRtpOverTcpM = onOffP; }
|
void SetTransportMode(unsigned int transportModeP) { transportModeM = transportModeP; }
|
||||||
void SetDetachedMode(bool onOffP) { detachedModeM = onOffP; }
|
void SetDetachedMode(bool onOffP) { detachedModeM = onOffP; }
|
||||||
void SetDisableServerQuirks(bool onOffP) { disableServerQuirksM = onOffP; }
|
void SetDisableServerQuirks(bool onOffP) { disableServerQuirksM = onOffP; }
|
||||||
void SetUseSingleModelServers(bool onOffP) { useSingleModelServersM = onOffP; }
|
void SetUseSingleModelServers(bool onOffP) { useSingleModelServersM = onOffP; }
|
||||||
|
22
device.c
22
device.c
@ -22,8 +22,7 @@ cSatipDevice::cSatipDevice(unsigned int indexP)
|
|||||||
deviceNameM(*cString::sprintf("%s %d", *DeviceType(), deviceIndexM)),
|
deviceNameM(*cString::sprintf("%s %d", *DeviceType(), deviceIndexM)),
|
||||||
channelM(),
|
channelM(),
|
||||||
createdM(0),
|
createdM(0),
|
||||||
mutexM(),
|
mutexM()
|
||||||
fixedPidsM()
|
|
||||||
{
|
{
|
||||||
unsigned int bufsize = (unsigned int)SATIP_BUFFER_SIZE;
|
unsigned int bufsize = (unsigned int)SATIP_BUFFER_SIZE;
|
||||||
bufsize -= (bufsize % TS_SIZE);
|
bufsize -= (bufsize % TS_SIZE);
|
||||||
@ -141,7 +140,7 @@ cString cSatipDevice::GetGeneralInformation(void)
|
|||||||
#if defined(APIVERSNUM) && APIVERSNUM >= 20301
|
#if defined(APIVERSNUM) && APIVERSNUM >= 20301
|
||||||
LOCK_CHANNELS_READ;
|
LOCK_CHANNELS_READ;
|
||||||
#endif
|
#endif
|
||||||
return cString::sprintf("SAT>IP device: %d\nCardIndex: %d\nStream: %s\nSignal: %s\nStream bitrate: %s\n%sChannel: %s",
|
return cString::sprintf("SAT>IP device: %d\nCardIndex: %d\nStream: %s\nSignal: %s\nStream bitrate: %s\n%sChannel: %s\n",
|
||||||
deviceIndexM, CardIndex(),
|
deviceIndexM, CardIndex(),
|
||||||
pTunerM ? *pTunerM->GetInformation() : "",
|
pTunerM ? *pTunerM->GetInformation() : "",
|
||||||
pTunerM ? *pTunerM->GetSignalStatus() : "",
|
pTunerM ? *pTunerM->GetSignalStatus() : "",
|
||||||
@ -372,16 +371,10 @@ bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP)
|
|||||||
{
|
{
|
||||||
debug12("%s (%d, %d, %d) [device %u]", __PRETTY_FUNCTION__, handleP ? handleP->pid : -1, typeP, onP, deviceIndexM);
|
debug12("%s (%d, %d, %d) [device %u]", __PRETTY_FUNCTION__, handleP ? handleP->pid : -1, typeP, onP, deviceIndexM);
|
||||||
if (pTunerM && handleP && handleP->pid >= 0) {
|
if (pTunerM && handleP && handleP->pid >= 0) {
|
||||||
if (onP) {
|
if (onP)
|
||||||
fixedPidsM.AddPid(handleP->pid);
|
|
||||||
debug12("%s A%d fixedPidsM=%s [device %d]", __PRETTY_FUNCTION__, handleP->pid, *fixedPidsM.ListPids(), deviceIndexM);
|
|
||||||
return pTunerM->SetPid(handleP->pid, typeP, true);
|
return pTunerM->SetPid(handleP->pid, typeP, true);
|
||||||
}
|
else if (!handleP->used && pSectionFilterHandlerM && !pSectionFilterHandlerM->Exists(handleP->pid))
|
||||||
else if (!handleP->used) {
|
|
||||||
fixedPidsM.RemovePid(handleP->pid);
|
|
||||||
debug12("%s R%d fixedPidsM=%s [device %d]", __PRETTY_FUNCTION__, handleP->pid, *fixedPidsM.ListPids(), deviceIndexM);
|
|
||||||
return pTunerM->SetPid(handleP->pid, typeP, false);
|
return pTunerM->SetPid(handleP->pid, typeP, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -403,7 +396,7 @@ void cSatipDevice::CloseFilter(int handleP)
|
|||||||
if (pSectionFilterHandlerM) {
|
if (pSectionFilterHandlerM) {
|
||||||
int pid = pSectionFilterHandlerM->GetPid(handleP);
|
int pid = pSectionFilterHandlerM->GetPid(handleP);
|
||||||
debug12("%s (%d) [device %u]", __PRETTY_FUNCTION__, pid, deviceIndexM);
|
debug12("%s (%d) [device %u]", __PRETTY_FUNCTION__, pid, deviceIndexM);
|
||||||
if (pTunerM && fixedPidsM.IndexOf(pid) == -1)
|
if (pTunerM)
|
||||||
pTunerM->SetPid(pid, ptOther, false);
|
pTunerM->SetPid(pid, ptOther, false);
|
||||||
pSectionFilterHandlerM->Close(handleP);
|
pSectionFilterHandlerM->Close(handleP);
|
||||||
}
|
}
|
||||||
@ -417,7 +410,6 @@ bool cSatipDevice::OpenDvr(void)
|
|||||||
if (pTunerM)
|
if (pTunerM)
|
||||||
pTunerM->Open();
|
pTunerM->Open();
|
||||||
isOpenDvrM = true;
|
isOpenDvrM = true;
|
||||||
fixedPidsM.Clear();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,8 +554,8 @@ bool cSatipDevice::GetTSPacket(uchar *&dataP)
|
|||||||
if (dataP && (dataP[4] == 0x00) && (dataP[5] == 0x02) && ((dataP[6] & 0xfc) == 0xb0)) {
|
if (dataP && (dataP[4] == 0x00) && (dataP[5] == 0x02) && ((dataP[6] & 0xfc) == 0xb0)) {
|
||||||
int pidA = ((dataP[1] & 0x1f) << 8) | dataP[2];
|
int pidA = ((dataP[1] & 0x1f) << 8) | dataP[2];
|
||||||
int pidB = GetPmtPid();
|
int pidB = GetPmtPid();
|
||||||
debug12("%s PID %d/%d 0x%02x%02x%02x%02x%02x%02x%02x %d", __PRETTY_FUNCTION__,
|
debug12("%s PID %d/%d 0x%02x%02x%02x%02x%02x%02x%02x", __PRETTY_FUNCTION__,
|
||||||
pidA, pidB, dataP[0], dataP[1], dataP[2], dataP[3], dataP[4], dataP[5], dataP[6], fixedPidsM.IndexOf(pidA));
|
pidA, pidB, dataP[0], dataP[1], dataP[2], dataP[3], dataP[4], dataP[5], dataP[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
1
device.h
1
device.h
@ -40,7 +40,6 @@ private:
|
|||||||
cSatipSectionFilterHandler *pSectionFilterHandlerM;
|
cSatipSectionFilterHandler *pSectionFilterHandlerM;
|
||||||
cTimeMs createdM;
|
cTimeMs createdM;
|
||||||
cMutex mutexM;
|
cMutex mutexM;
|
||||||
cSatipPid fixedPidsM;
|
|
||||||
|
|
||||||
// constructor & destructor
|
// constructor & destructor
|
||||||
public:
|
public:
|
||||||
|
@ -100,6 +100,11 @@ void cSatipMsearch::Process(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cSatipMsearch::Process(unsigned char *dataP, int lengthP)
|
||||||
|
{
|
||||||
|
debug16("%s", __PRETTY_FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
cString cSatipMsearch::ToString(void) const
|
cString cSatipMsearch::ToString(void) const
|
||||||
{
|
{
|
||||||
return "MSearch";
|
return "MSearch";
|
||||||
|
@ -34,6 +34,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
virtual int GetFd(void);
|
virtual int GetFd(void);
|
||||||
virtual void Process(void);
|
virtual void Process(void);
|
||||||
|
virtual void Process(unsigned char *dataP, int lengthP);
|
||||||
virtual cString ToString(void) const;
|
virtual cString ToString(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
17
po/ca_ES.po
17
po/ca_ES.po
@ -1,5 +1,5 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2015 Rolf Ahrenberg
|
# Copyright (C) 2007-2016 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the satip package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Gabriel Bonich, 2014-2015
|
# Gabriel Bonich, 2014-2015
|
||||||
#
|
#
|
||||||
@ -85,6 +85,15 @@ msgstr "Normal"
|
|||||||
msgid "high"
|
msgid "high"
|
||||||
msgstr "Alt"
|
msgstr "Alt"
|
||||||
|
|
||||||
|
msgid "Unicast"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Multicast"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "RTP-over-TCP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Button$Devices"
|
msgid "Button$Devices"
|
||||||
msgstr "Dispositius"
|
msgstr "Dispositius"
|
||||||
|
|
||||||
@ -178,13 +187,13 @@ msgstr "Filtra"
|
|||||||
msgid "Define an ill-behaving filter to be blacklisted."
|
msgid "Define an ill-behaving filter to be blacklisted."
|
||||||
msgstr "Definir un filtre mal comportar a la llista negra."
|
msgstr "Definir un filtre mal comportar a la llista negra."
|
||||||
|
|
||||||
msgid "Use RTP-over-TCP mode"
|
msgid "Transport mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Define whether the RTP-over-TCP mode shall be used.\n"
|
"Define which transport mode shall be used.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This setting affects only SAT>IP devices supporting the feature."
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Active SAT>IP servers:"
|
msgid "Active SAT>IP servers:"
|
||||||
|
32
po/de_DE.po
32
po/de_DE.po
@ -1,7 +1,7 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2015 Rolf Ahrenberg
|
# Copyright (C) 2007-2016 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the satip package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Frank Neumann, 2014-2015
|
# Frank Neumann, 2014-2016
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -85,11 +85,20 @@ msgstr "normal"
|
|||||||
msgid "high"
|
msgid "high"
|
||||||
msgstr "hoch"
|
msgstr "hoch"
|
||||||
|
|
||||||
|
msgid "Unicast"
|
||||||
|
msgstr "Unicast"
|
||||||
|
|
||||||
|
msgid "Multicast"
|
||||||
|
msgstr "Multicast"
|
||||||
|
|
||||||
|
msgid "RTP-over-TCP"
|
||||||
|
msgstr "RTP-over-TCP"
|
||||||
|
|
||||||
msgid "Button$Devices"
|
msgid "Button$Devices"
|
||||||
msgstr "Geräte"
|
msgstr "Geräte"
|
||||||
|
|
||||||
msgid "Operating mode"
|
msgid "Operating mode"
|
||||||
msgstr "Betriebsmodus"
|
msgstr "Betriebsart"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Define the used operating mode for all SAT>IP devices:\n"
|
"Define the used operating mode for all SAT>IP devices:\n"
|
||||||
@ -99,7 +108,7 @@ msgid ""
|
|||||||
"normal - devices are working within normal parameters\n"
|
"normal - devices are working within normal parameters\n"
|
||||||
"high - devices are working at the highest priority"
|
"high - devices are working at the highest priority"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Bestimme den Betriebsmodus für alle SAT>IP Geräte:\n"
|
"Bestimme die Betriebsart für alle SAT>IP Geräte:\n"
|
||||||
"\n"
|
"\n"
|
||||||
"aus - Geräte sind abgeschaltet\n"
|
"aus - Geräte sind abgeschaltet\n"
|
||||||
"niedrig - Geräte arbeiten mit geringster Priorität\n"
|
"niedrig - Geräte arbeiten mit geringster Priorität\n"
|
||||||
@ -170,22 +179,25 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Bestimme die Anzahl der Abschnittsfilter die deaktiviert werden sollen.\n"
|
"Bestimme die Anzahl der Abschnittsfilter die deaktiviert werden sollen.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Bestimmte Abschnittsfilter können unerwünschtes Verhalten mit VDR, z.B. falsche Zeit-Synchronisation, verursachen. Durch das Ausblenden einzelner Filter können nützliche Daten dieser Abschnitte für den VDR erhalten werden."
|
"Bestimmte Abschnittsfilter können unerwünschtes Verhalten mit VDR, z.B. falsche Zeit-Synchronisation, verursachen. Durch das Ausblenden einzelner Filter können nützliche Daten dieser Abschnitte für den VDR erhalten bleiben."
|
||||||
|
|
||||||
msgid "Filter"
|
msgid "Filter"
|
||||||
msgstr "Filter"
|
msgstr "Filter"
|
||||||
|
|
||||||
msgid "Define an ill-behaving filter to be blacklisted."
|
msgid "Define an ill-behaving filter to be blacklisted."
|
||||||
msgstr "Bestimme einen fehlerhaften Filter der ausgeblendet werden soll."
|
msgstr "Bestimme fehlerhafte Filter die ausgeblendet werden sollen."
|
||||||
|
|
||||||
msgid "Use RTP-over-TCP mode"
|
msgid "Transport mode"
|
||||||
msgstr ""
|
msgstr "Übertragungsart"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Define whether the RTP-over-TCP mode shall be used.\n"
|
"Define which transport mode shall be used.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This setting affects only SAT>IP devices supporting the feature."
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Lege die gewünschte Übertragungsart fest.\n"
|
||||||
|
"\n"
|
||||||
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
|
|
||||||
msgid "Active SAT>IP servers:"
|
msgid "Active SAT>IP servers:"
|
||||||
msgstr "Aktive SAT>IP Server:"
|
msgstr "Aktive SAT>IP Server:"
|
||||||
|
17
po/es_ES.po
17
po/es_ES.po
@ -1,5 +1,5 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2015 Rolf Ahrenberg
|
# Copyright (C) 2007-2016 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the satip package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Gabriel Bonich, 2014-2015
|
# Gabriel Bonich, 2014-2015
|
||||||
#
|
#
|
||||||
@ -85,6 +85,15 @@ msgstr "Normal"
|
|||||||
msgid "high"
|
msgid "high"
|
||||||
msgstr "Alto"
|
msgstr "Alto"
|
||||||
|
|
||||||
|
msgid "Unicast"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Multicast"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "RTP-over-TCP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Button$Devices"
|
msgid "Button$Devices"
|
||||||
msgstr "Dispositivos"
|
msgstr "Dispositivos"
|
||||||
|
|
||||||
@ -178,13 +187,13 @@ msgstr "Filtra"
|
|||||||
msgid "Define an ill-behaving filter to be blacklisted."
|
msgid "Define an ill-behaving filter to be blacklisted."
|
||||||
msgstr "Define un filtro para poner en la lista negra."
|
msgstr "Define un filtro para poner en la lista negra."
|
||||||
|
|
||||||
msgid "Use RTP-over-TCP mode"
|
msgid "Transport mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Define whether the RTP-over-TCP mode shall be used.\n"
|
"Define which transport mode shall be used.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This setting affects only SAT>IP devices supporting the feature."
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Active SAT>IP servers:"
|
msgid "Active SAT>IP servers:"
|
||||||
|
25
po/fi_FI.po
25
po/fi_FI.po
@ -1,7 +1,7 @@
|
|||||||
# VDR plugin language source file.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2015 Rolf Ahrenberg
|
# Copyright (C) 2007-2016 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the satip package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Rolf Ahrenberg, 2015
|
# Rolf Ahrenberg, 2015-2016
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -85,6 +85,15 @@ msgstr "normaali"
|
|||||||
msgid "high"
|
msgid "high"
|
||||||
msgstr "korkea"
|
msgstr "korkea"
|
||||||
|
|
||||||
|
msgid "Unicast"
|
||||||
|
msgstr "Unicast"
|
||||||
|
|
||||||
|
msgid "Multicast"
|
||||||
|
msgstr "Multicast"
|
||||||
|
|
||||||
|
msgid "RTP-over-TCP"
|
||||||
|
msgstr "RTP-over-TCP"
|
||||||
|
|
||||||
msgid "Button$Devices"
|
msgid "Button$Devices"
|
||||||
msgstr "Laitteet"
|
msgstr "Laitteet"
|
||||||
|
|
||||||
@ -177,17 +186,17 @@ msgstr "Suodatin"
|
|||||||
msgid "Define an ill-behaving filter to be blacklisted."
|
msgid "Define an ill-behaving filter to be blacklisted."
|
||||||
msgstr "Määrittele käytöstä poistettava suodatin, joka lisätään mustalle listalle."
|
msgstr "Määrittele käytöstä poistettava suodatin, joka lisätään mustalle listalle."
|
||||||
|
|
||||||
msgid "Use RTP-over-TCP mode"
|
msgid "Transport mode"
|
||||||
msgstr "Käytä RTP-over-TCP -moodia"
|
msgstr "Siirtoyhteystapa"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Define whether the RTP-over-TCP mode shall be used.\n"
|
"Define which transport mode shall be used.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This setting affects only SAT>IP devices supporting the feature."
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Määrittele RTP-over-TCP -moodin käyttöönotto.\n"
|
"Määrittele käytettävä siirtoyhteystapa.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Tämä asetus vaikuttaa vain SAT>IP-laitteisiin, jotka tukevat kyseistä ominaisuutta."
|
"Unicast, Multicast, RTP-over-TCP"
|
||||||
|
|
||||||
msgid "Active SAT>IP servers:"
|
msgid "Active SAT>IP servers:"
|
||||||
msgstr "Aktiiviset SAT>IP-palvelimet:"
|
msgstr "Aktiiviset SAT>IP-palvelimet:"
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
virtual ~cSatipPollerIf() {}
|
virtual ~cSatipPollerIf() {}
|
||||||
virtual int GetFd(void) = 0;
|
virtual int GetFd(void) = 0;
|
||||||
virtual void Process(void) = 0;
|
virtual void Process(void) = 0;
|
||||||
|
virtual void Process(unsigned char *dataP, int lengthP) = 0;
|
||||||
virtual cString ToString(void) const = 0;
|
virtual cString ToString(void) const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
10
rtcp.c
10
rtcp.c
@ -92,6 +92,16 @@ void cSatipRtcp::Process(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cSatipRtcp::Process(unsigned char *dataP, int lengthP)
|
||||||
|
{
|
||||||
|
debug16("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
||||||
|
if (dataP && lengthP > 0) {
|
||||||
|
int offset = GetApplicationOffset(&lengthP);
|
||||||
|
if (offset >= 0)
|
||||||
|
tunerM.ProcessApplicationData(dataP + offset, lengthP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cString cSatipRtcp::ToString(void) const
|
cString cSatipRtcp::ToString(void) const
|
||||||
{
|
{
|
||||||
return cString::sprintf("RTCP [device %d]", tunerM.GetId());
|
return cString::sprintf("RTCP [device %d]", tunerM.GetId());
|
||||||
|
1
rtcp.h
1
rtcp.h
@ -30,6 +30,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
virtual int GetFd(void);
|
virtual int GetFd(void);
|
||||||
virtual void Process(void);
|
virtual void Process(void);
|
||||||
|
virtual void Process(unsigned char *dataP, int lengthP);
|
||||||
virtual cString ToString(void) const;
|
virtual cString ToString(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
16
rtp.c
16
rtp.c
@ -142,6 +142,22 @@ void cSatipRtp::Process(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cSatipRtp::Process(unsigned char *dataP, int lengthP)
|
||||||
|
{
|
||||||
|
debug16("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
||||||
|
if (dataP && lengthP > 0) {
|
||||||
|
uint64_t elapsed;
|
||||||
|
cTimeMs processing(0);
|
||||||
|
int headerlen = GetHeaderLength(dataP, lengthP);
|
||||||
|
if ((headerlen >= 0) && (headerlen < lengthP))
|
||||||
|
tunerM.ProcessVideoData(dataP + headerlen, lengthP - headerlen);
|
||||||
|
|
||||||
|
elapsed = processing.Elapsed();
|
||||||
|
if (elapsed > 1)
|
||||||
|
debug6("%s %d read(s) took %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, lengthP, elapsed, tunerM.GetId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cString cSatipRtp::ToString(void) const
|
cString cSatipRtp::ToString(void) const
|
||||||
{
|
{
|
||||||
return cString::sprintf("RTP [device %d]", tunerM.GetId());
|
return cString::sprintf("RTP [device %d]", tunerM.GetId());
|
||||||
|
1
rtp.h
1
rtp.h
@ -36,6 +36,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
virtual int GetFd(void);
|
virtual int GetFd(void);
|
||||||
virtual void Process(void);
|
virtual void Process(void);
|
||||||
|
virtual void Process(unsigned char *dataP, int lengthP);
|
||||||
virtual cString ToString(void) const;
|
virtual cString ToString(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
96
rtsp.c
96
rtsp.c
@ -17,12 +17,14 @@ cSatipRtsp::cSatipRtsp(cSatipTunerIf &tunerP)
|
|||||||
: tunerM(tunerP),
|
: tunerM(tunerP),
|
||||||
headerBufferM(),
|
headerBufferM(),
|
||||||
dataBufferM(),
|
dataBufferM(),
|
||||||
modeM(cmUnicast),
|
|
||||||
handleM(NULL),
|
handleM(NULL),
|
||||||
headerListM(NULL),
|
headerListM(NULL),
|
||||||
errorNoMoreM(""),
|
errorNoMoreM(""),
|
||||||
errorOutOfRangeM(""),
|
errorOutOfRangeM(""),
|
||||||
errorCheckSyntaxM("")
|
errorCheckSyntaxM(""),
|
||||||
|
modeM(cSatipConfig::eTransportModeUnicast),
|
||||||
|
interleavedRtpIdM(0),
|
||||||
|
interleavedRtcpIdM(1)
|
||||||
{
|
{
|
||||||
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId());
|
||||||
Create();
|
Create();
|
||||||
@ -58,6 +60,30 @@ size_t cSatipRtsp::DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void *d
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t cSatipRtsp::InterleaveCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP)
|
||||||
|
{
|
||||||
|
cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(dataP);
|
||||||
|
size_t len = sizeP * nmembP;
|
||||||
|
debug16("%s len=%zu", __PRETTY_FUNCTION__, len);
|
||||||
|
|
||||||
|
if (obj && ptrP && len > 0) {
|
||||||
|
char tag = ptrP[0] & 0xFF;
|
||||||
|
if (tag == '$') {
|
||||||
|
int count = ((ptrP[2] & 0xFF) << 8) | (ptrP[3] & 0xFF);
|
||||||
|
if (count > 0) {
|
||||||
|
unsigned int channel = ptrP[1] & 0xFF;
|
||||||
|
u_char *data = (u_char *)&ptrP[4];
|
||||||
|
if (channel == obj->interleavedRtpIdM)
|
||||||
|
obj->tunerM.ProcessRtpData(data, count);
|
||||||
|
else if (channel == obj->interleavedRtcpIdM)
|
||||||
|
obj->tunerM.ProcessRtcpData(data, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
int cSatipRtsp::DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP)
|
int cSatipRtsp::DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP)
|
||||||
{
|
{
|
||||||
cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(userPtrP);
|
cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(userPtrP);
|
||||||
@ -87,6 +113,21 @@ int cSatipRtsp::DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, s
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cString cSatipRtsp::GetActiveMode(void)
|
||||||
|
{
|
||||||
|
switch (modeM) {
|
||||||
|
case cSatipConfig::eTransportModeUnicast:
|
||||||
|
return "Unicast";
|
||||||
|
case cSatipConfig::eTransportModeMulticast:
|
||||||
|
return "Multicast";
|
||||||
|
case cSatipConfig::eTransportModeRtpOverTcp:
|
||||||
|
return "RTP-over-TCP";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
cString cSatipRtsp::RtspUnescapeString(const char *strP)
|
cString cSatipRtsp::RtspUnescapeString(const char *strP)
|
||||||
{
|
{
|
||||||
debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, strP, tunerM.GetId());
|
debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, strP, tunerM.GetId());
|
||||||
@ -123,6 +164,9 @@ void cSatipRtsp::Create(void)
|
|||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_TIMEOUT_MS, (long)eConnectTimeoutMs);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_TIMEOUT_MS, (long)eConnectTimeoutMs);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_CONNECTTIMEOUT_MS, (long)eConnectTimeoutMs);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_CONNECTTIMEOUT_MS, (long)eConnectTimeoutMs);
|
||||||
|
|
||||||
|
// Limit download speed (bytes/s)
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_MAX_RECV_SPEED_LARGE, eMaxDownloadSpeedMBits * 131072L);
|
||||||
|
|
||||||
// Set user-agent
|
// Set user-agent
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s (device %d)", PLUGIN_NAME_I18N, VERSION, tunerM.GetId()));
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s (device %d)", PLUGIN_NAME_I18N, VERSION, tunerM.GetId()));
|
||||||
}
|
}
|
||||||
@ -182,16 +226,18 @@ bool cSatipRtsp::Setup(const char *uriP, int rtpPortP, int rtcpPortP, bool useTc
|
|||||||
cTimeMs processing(0);
|
cTimeMs processing(0);
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
|
|
||||||
switch (modeM) {
|
switch (SatipConfig.GetTransportMode()) {
|
||||||
case cmMulticast:
|
case cSatipConfig::eTransportModeMulticast:
|
||||||
// RTP/AVP;multicast;destination=<IP multicast address>;port=<RTP port>-<RTCP port>;ttl=<ttl>
|
// RTP/AVP;multicast;destination=<multicast group address>;port=<RTP port>-<RTCP port>;ttl=<ttl>[;source=<multicast source address>]
|
||||||
transport = cString::sprintf("RTP/AVP;multicast;port=%d-%d", rtpPortP, rtcpPortP);
|
transport = cString::sprintf("RTP/AVP;multicast");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case cmUnicast:
|
|
||||||
// RTP/AVP;unicast;client_port=<client RTP port>-<client RTCP port>
|
// RTP/AVP;unicast;client_port=<client RTP port>-<client RTCP port>
|
||||||
// RTP/AVP/TCP;unicast;client_port=<client RTP port>-<client RTCP port>
|
// RTP/AVP/TCP;unicast;client_port=<client RTP port>-<client RTCP port>
|
||||||
transport = cString::sprintf("RTP/AVP%s;unicast;client_port=%d-%d", useTcpP ? "/TCP" : "", rtpPortP, rtcpPortP);
|
if (useTcpP)
|
||||||
|
transport = cString::sprintf("RTP/AVP/TCP;unicast;interleaved=%u-%u", interleavedRtpIdM, interleavedRtcpIdM);
|
||||||
|
else
|
||||||
|
transport = cString::sprintf("RTP/AVP;unicast;client_port=%d-%d", rtpPortP, rtcpPortP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +250,9 @@ bool cSatipRtsp::Setup(const char *uriP, int rtpPortP, int rtcpPortP, bool useTc
|
|||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipRtsp::DataCallback);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipRtsp::DataCallback);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERLEAVEFUNCTION, NULL);
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERLEAVEDATA, NULL);
|
||||||
|
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
SATIP_CURL_EASY_PERFORM(handleM);
|
||||||
// Session id is now known - disable header parsing
|
// Session id is now known - disable header parsing
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, NULL);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, NULL);
|
||||||
@ -311,6 +360,8 @@ bool cSatipRtsp::Teardown(const char *uriP)
|
|||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipRtsp::DataCallback);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipRtsp::DataCallback);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERLEAVEFUNCTION, NULL);
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERLEAVEDATA, NULL);
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
SATIP_CURL_EASY_PERFORM(handleM);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL);
|
||||||
@ -352,6 +403,35 @@ void cSatipRtsp::ParseHeader(void)
|
|||||||
tunerM.SetSessionTimeout(skipspace(session), -1);
|
tunerM.SetSessionTimeout(skipspace(session), -1);
|
||||||
FREE_POINTER(session);
|
FREE_POINTER(session);
|
||||||
}
|
}
|
||||||
|
else if (strstr(r, "Transport:")) {
|
||||||
|
CURLcode res = CURLE_OK;
|
||||||
|
int rtp = -1, rtcp = -1, ttl = -1;
|
||||||
|
char *tmp = NULL, *destination = NULL, *source = NULL;
|
||||||
|
interleavedRtpIdM = 0;
|
||||||
|
interleavedRtcpIdM = 1;
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERLEAVEFUNCTION, NULL);
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERLEAVEDATA, NULL);
|
||||||
|
if (sscanf(r, "Transport:%m[^;];unicast;client_port=%11d-%11d", &tmp, &rtp, &rtcp) == 3) {
|
||||||
|
modeM = cSatipConfig::eTransportModeUnicast;
|
||||||
|
tunerM.SetupTransport(rtp, rtcp, NULL, NULL);
|
||||||
|
}
|
||||||
|
else if (sscanf(r, "Transport:%m[^;];multicast;destination=%m[^;];port=%11d-%11d;ttl=%11d;source=%m[^;]", &tmp, &destination, &rtp, &rtcp, &ttl, &source) == 6 ||
|
||||||
|
sscanf(r, "Transport:%m[^;];multicast;destination=%m[^;];port=%11d-%11d;ttl=%11d", &tmp, &destination, &rtp, &rtcp, &ttl) == 5) {
|
||||||
|
modeM = cSatipConfig::eTransportModeMulticast;
|
||||||
|
tunerM.SetupTransport(rtp, rtcp, destination, source);
|
||||||
|
}
|
||||||
|
else if (sscanf(r, "Transport:%m[^;];interleaved=%11d-%11d", &tmp, &rtp, &rtcp) == 3) {
|
||||||
|
interleavedRtpIdM = rtp;
|
||||||
|
interleavedRtcpIdM = rtcp;
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERLEAVEFUNCTION, cSatipRtsp::InterleaveCallback);
|
||||||
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERLEAVEDATA, this);
|
||||||
|
modeM = cSatipConfig::eTransportModeRtpOverTcp;
|
||||||
|
tunerM.SetupTransport(-1, -1, NULL, NULL);
|
||||||
|
}
|
||||||
|
FREE_POINTER(tmp);
|
||||||
|
FREE_POINTER(destination);
|
||||||
|
FREE_POINTER(source);
|
||||||
|
}
|
||||||
r = strtok_r(NULL, "\r\n", &s);
|
r = strtok_r(NULL, "\r\n", &s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
rtsp.h
10
rtsp.h
@ -22,22 +22,25 @@ class cSatipRtsp {
|
|||||||
private:
|
private:
|
||||||
static size_t HeaderCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
static size_t HeaderCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
||||||
static size_t DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
static size_t DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
||||||
|
static size_t InterleaveCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
||||||
static int DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP);
|
static int DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
eConnectTimeoutMs = 1500, // in milliseconds
|
eConnectTimeoutMs = 1500, // in milliseconds
|
||||||
|
eMaxDownloadSpeedMBits = 20, // in megabits per second
|
||||||
};
|
};
|
||||||
enum eCommunicationMode { cmUnicast, cmMulticast };
|
|
||||||
|
|
||||||
cSatipTunerIf &tunerM;
|
cSatipTunerIf &tunerM;
|
||||||
cSatipMemoryBuffer headerBufferM;
|
cSatipMemoryBuffer headerBufferM;
|
||||||
cSatipMemoryBuffer dataBufferM;
|
cSatipMemoryBuffer dataBufferM;
|
||||||
eCommunicationMode modeM;
|
|
||||||
CURL *handleM;
|
CURL *handleM;
|
||||||
struct curl_slist *headerListM;
|
struct curl_slist *headerListM;
|
||||||
cString errorNoMoreM;
|
cString errorNoMoreM;
|
||||||
cString errorOutOfRangeM;
|
cString errorOutOfRangeM;
|
||||||
cString errorCheckSyntaxM;
|
cString errorCheckSyntaxM;
|
||||||
|
int modeM;
|
||||||
|
unsigned int interleavedRtpIdM;
|
||||||
|
unsigned int interleavedRtcpIdM;
|
||||||
|
|
||||||
void Create(void);
|
void Create(void);
|
||||||
void Destroy(void);
|
void Destroy(void);
|
||||||
@ -53,6 +56,7 @@ public:
|
|||||||
explicit cSatipRtsp(cSatipTunerIf &tunerP);
|
explicit cSatipRtsp(cSatipTunerIf &tunerP);
|
||||||
virtual ~cSatipRtsp();
|
virtual ~cSatipRtsp();
|
||||||
|
|
||||||
|
cString GetActiveMode(void);
|
||||||
cString RtspUnescapeString(const char *strP);
|
cString RtspUnescapeString(const char *strP);
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
bool Options(const char *uriP);
|
bool Options(const char *uriP);
|
||||||
|
11
satip.c
11
satip.c
@ -305,7 +305,12 @@ void cPluginSatip::ParsePortRange(const char *paramP)
|
|||||||
rangeStart = 0;
|
rangeStart = 0;
|
||||||
rangeStop = 0;
|
rangeStop = 0;
|
||||||
}
|
}
|
||||||
if (rangeStop - rangeStart + 1 < deviceCountM * 2) {
|
if (rangeStart % 2) {
|
||||||
|
error("The given range start port must be even!");
|
||||||
|
rangeStart = 0;
|
||||||
|
rangeStop = 0;
|
||||||
|
}
|
||||||
|
else if (rangeStop - rangeStart + 1 < deviceCountM * 2) {
|
||||||
error("The given port range is to small: %d < %d!", rangeStop - rangeStart + 1, deviceCountM * 2);
|
error("The given port range is to small: %d < %d!", rangeStop - rangeStart + 1, deviceCountM * 2);
|
||||||
rangeStart = 0;
|
rangeStart = 0;
|
||||||
rangeStop = 0;
|
rangeStop = 0;
|
||||||
@ -401,8 +406,8 @@ bool cPluginSatip::SetupParse(const char *nameP, const char *valueP)
|
|||||||
for (unsigned int i = 0; i < DisabledFiltersCount; ++i)
|
for (unsigned int i = 0; i < DisabledFiltersCount; ++i)
|
||||||
SatipConfig.SetDisabledFilters(i, DisabledFilters[i]);
|
SatipConfig.SetDisabledFilters(i, DisabledFilters[i]);
|
||||||
}
|
}
|
||||||
else if (!strcasecmp(nameP, "UseRtpOverTcp"))
|
else if (!strcasecmp(nameP, "TransportMode"))
|
||||||
SatipConfig.SetUseRtpOverTcp(atoi(valueP));
|
SatipConfig.SetTransportMode(atoi(valueP));
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -338,6 +338,19 @@ cString cSatipSectionFilterHandler::GetInformation(void)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cSatipSectionFilterHandler::Exists(u_short pidP)
|
||||||
|
{
|
||||||
|
debug16("%s (%d) [device %d]", __PRETTY_FUNCTION__, pidP, deviceIndexM);
|
||||||
|
cMutexLock MutexLock(&mutexM);
|
||||||
|
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
||||||
|
if (filtersM[i] && (pidP == filtersM[i]->GetPid())) {
|
||||||
|
debug12("%s (%d) Found [device %d]", __PRETTY_FUNCTION__, pidP, deviceIndexM);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool cSatipSectionFilterHandler::Delete(unsigned int indexP)
|
bool cSatipSectionFilterHandler::Delete(unsigned int indexP)
|
||||||
{
|
{
|
||||||
debug16("%s (%d) [device %d]", __PRETTY_FUNCTION__, indexP, deviceIndexM);
|
debug16("%s (%d) [device %d]", __PRETTY_FUNCTION__, indexP, deviceIndexM);
|
||||||
|
@ -80,6 +80,7 @@ public:
|
|||||||
cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP);
|
cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP);
|
||||||
virtual ~cSatipSectionFilterHandler();
|
virtual ~cSatipSectionFilterHandler();
|
||||||
cString GetInformation(void);
|
cString GetInformation(void);
|
||||||
|
bool Exists(u_short pidP);
|
||||||
int Open(u_short pidP, u_char tidP, u_char maskP);
|
int Open(u_short pidP, u_char tidP, u_char maskP);
|
||||||
void Close(int handleP);
|
void Close(int handleP);
|
||||||
int GetPid(int handleP);
|
int GetPid(int handleP);
|
||||||
|
9
server.c
9
server.c
@ -147,6 +147,13 @@ cSatipServer::cSatipServer(const char *addressP, const int portP, const char *mo
|
|||||||
if (strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server
|
if (strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server
|
||||||
)
|
)
|
||||||
quirkM |= eSatipQuirkCiTnr;
|
quirkM |= eSatipQuirkCiTnr;
|
||||||
|
// These devices don't support auto-detection of pilot tones
|
||||||
|
if (strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400
|
||||||
|
strstr(*descriptionM, "DIGIBIT") || // Telestar Digibit R1
|
||||||
|
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
||||||
|
// Kathrein ExIP 414/E
|
||||||
|
)
|
||||||
|
quirkM |= eSatipQuirkForcePilot;
|
||||||
}
|
}
|
||||||
if ((quirkM & eSatipQuirkMask) & eSatipQuirkSessionId)
|
if ((quirkM & eSatipQuirkMask) & eSatipQuirkSessionId)
|
||||||
quirksM = cString::sprintf("%s%sSessionId", *quirksM, isempty(*quirksM) ? "" : ",");
|
quirksM = cString::sprintf("%s%sSessionId", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
@ -160,6 +167,8 @@ cSatipServer::cSatipServer(const char *addressP, const int portP, const char *mo
|
|||||||
quirksM = cString::sprintf("%s%sCiXpmt", *quirksM, isempty(*quirksM) ? "" : ",");
|
quirksM = cString::sprintf("%s%sCiXpmt", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
if ((quirkM & eSatipQuirkMask) & eSatipQuirkCiTnr)
|
if ((quirkM & eSatipQuirkMask) & eSatipQuirkCiTnr)
|
||||||
quirksM = cString::sprintf("%s%sCiTnr", *quirksM, isempty(*quirksM) ? "" : ",");
|
quirksM = cString::sprintf("%s%sCiTnr", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
|
if ((quirkM & eSatipQuirkMask) & eSatipQuirkForcePilot)
|
||||||
|
quirksM = cString::sprintf("%s%sForcePilot", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
debug3("%s description=%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM, *quirksM);
|
debug3("%s description=%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM, *quirksM);
|
||||||
// These devices support external CI
|
// These devices support external CI
|
||||||
if (strstr(*descriptionM, "OctopusNet") || // Digital Devices OctopusNet
|
if (strstr(*descriptionM, "OctopusNet") || // Digital Devices OctopusNet
|
||||||
|
1
server.h
1
server.h
@ -81,6 +81,7 @@ public:
|
|||||||
eSatipQuirkRtpOverTcp = 0x08,
|
eSatipQuirkRtpOverTcp = 0x08,
|
||||||
eSatipQuirkCiXpmt = 0x10,
|
eSatipQuirkCiXpmt = 0x10,
|
||||||
eSatipQuirkCiTnr = 0x20,
|
eSatipQuirkCiTnr = 0x20,
|
||||||
|
eSatipQuirkForcePilot = 0x40,
|
||||||
eSatipQuirkMask = 0xFF
|
eSatipQuirkMask = 0xFF
|
||||||
};
|
};
|
||||||
cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP);
|
cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP);
|
||||||
|
13
setup.c
13
setup.c
@ -344,8 +344,8 @@ eOSState cSatipMenuInfo::ProcessKey(eKeys keyP)
|
|||||||
cSatipPluginSetup::cSatipPluginSetup()
|
cSatipPluginSetup::cSatipPluginSetup()
|
||||||
: detachedModeM(SatipConfig.GetDetachedMode()),
|
: detachedModeM(SatipConfig.GetDetachedMode()),
|
||||||
deviceCountM(0),
|
deviceCountM(0),
|
||||||
useRtpOverTcpM(SatipConfig.GetUseRtpOverTcp()),
|
|
||||||
operatingModeM(SatipConfig.GetOperatingMode()),
|
operatingModeM(SatipConfig.GetOperatingMode()),
|
||||||
|
transportModeM(SatipConfig.GetTransportMode()),
|
||||||
ciExtensionM(SatipConfig.GetCIExtension()),
|
ciExtensionM(SatipConfig.GetCIExtension()),
|
||||||
eitScanM(SatipConfig.GetEITScan()),
|
eitScanM(SatipConfig.GetEITScan()),
|
||||||
numDisabledSourcesM(SatipConfig.GetDisabledSourcesCount()),
|
numDisabledSourcesM(SatipConfig.GetDisabledSourcesCount()),
|
||||||
@ -356,6 +356,9 @@ cSatipPluginSetup::cSatipPluginSetup()
|
|||||||
operatingModeTextsM[cSatipConfig::eOperatingModeLow] = tr("low");
|
operatingModeTextsM[cSatipConfig::eOperatingModeLow] = tr("low");
|
||||||
operatingModeTextsM[cSatipConfig::eOperatingModeNormal] = tr("normal");
|
operatingModeTextsM[cSatipConfig::eOperatingModeNormal] = tr("normal");
|
||||||
operatingModeTextsM[cSatipConfig::eOperatingModeHigh] = tr("high");
|
operatingModeTextsM[cSatipConfig::eOperatingModeHigh] = tr("high");
|
||||||
|
transportModeTextsM[cSatipConfig::eTransportModeUnicast] = tr("Unicast");
|
||||||
|
transportModeTextsM[cSatipConfig::eTransportModeMulticast] = tr("Multicast");
|
||||||
|
transportModeTextsM[cSatipConfig::eTransportModeRtpOverTcp] = tr("RTP-over-TCP");
|
||||||
for (unsigned int i = 0; i < ELEMENTS(cicamsM); ++i)
|
for (unsigned int i = 0; i < ELEMENTS(cicamsM); ++i)
|
||||||
cicamsM[i] = SatipConfig.GetCICAM(i);
|
cicamsM[i] = SatipConfig.GetCICAM(i);
|
||||||
for (unsigned int i = 0; i < ELEMENTS(ca_systems_table); ++i)
|
for (unsigned int i = 0; i < ELEMENTS(ca_systems_table); ++i)
|
||||||
@ -413,8 +416,8 @@ void cSatipPluginSetup::Setup(void)
|
|||||||
helpM.Append(tr("Define an ill-behaving filter to be blacklisted."));
|
helpM.Append(tr("Define an ill-behaving filter to be blacklisted."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Add(new cMenuEditBoolItem(tr("Use RTP-over-TCP mode"), &useRtpOverTcpM));
|
Add(new cMenuEditStraItem(tr("Transport mode"), &transportModeM, ELEMENTS(transportModeTextsM), transportModeTextsM));
|
||||||
helpM.Append(tr("Define whether the RTP-over-TCP mode shall be used.\n\nThis setting affects only SAT>IP devices supporting the feature."));
|
helpM.Append(tr("Define which transport mode shall be used.\n\nUnicast, Multicast, RTP-over-TCP"));
|
||||||
Add(new cOsdItem(tr("Active SAT>IP servers:"), osUnknown, false));
|
Add(new cOsdItem(tr("Active SAT>IP servers:"), osUnknown, false));
|
||||||
helpM.Append("");
|
helpM.Append("");
|
||||||
|
|
||||||
@ -563,16 +566,16 @@ void cSatipPluginSetup::StoreFilters(const char *nameP, int *valuesP)
|
|||||||
void cSatipPluginSetup::Store(void)
|
void cSatipPluginSetup::Store(void)
|
||||||
{
|
{
|
||||||
// Store values into setup.conf
|
// Store values into setup.conf
|
||||||
SetupStore("UseRtpOverTcp", useRtpOverTcpM);
|
|
||||||
SetupStore("OperatingMode", operatingModeM);
|
SetupStore("OperatingMode", operatingModeM);
|
||||||
|
SetupStore("TransportMode", transportModeM);
|
||||||
SetupStore("EnableCIExtension", ciExtensionM);
|
SetupStore("EnableCIExtension", ciExtensionM);
|
||||||
SetupStore("EnableEITScan", eitScanM);
|
SetupStore("EnableEITScan", eitScanM);
|
||||||
StoreCicams("CICAM", cicamsM);
|
StoreCicams("CICAM", cicamsM);
|
||||||
StoreSources("DisabledSources", disabledSourcesM);
|
StoreSources("DisabledSources", disabledSourcesM);
|
||||||
StoreFilters("DisabledFilters", disabledFilterIndexesM);
|
StoreFilters("DisabledFilters", disabledFilterIndexesM);
|
||||||
// Update global config
|
// Update global config
|
||||||
SatipConfig.SetUseRtpOverTcp(useRtpOverTcpM);
|
|
||||||
SatipConfig.SetOperatingMode(operatingModeM);
|
SatipConfig.SetOperatingMode(operatingModeM);
|
||||||
|
SatipConfig.SetTransportMode(transportModeM);
|
||||||
SatipConfig.SetCIExtension(ciExtensionM);
|
SatipConfig.SetCIExtension(ciExtensionM);
|
||||||
SatipConfig.SetEITScan(eitScanM);
|
SatipConfig.SetEITScan(eitScanM);
|
||||||
for (int i = 0; i < MAX_CICAM_COUNT; ++i)
|
for (int i = 0; i < MAX_CICAM_COUNT; ++i)
|
||||||
|
3
setup.h
3
setup.h
@ -17,9 +17,10 @@ class cSatipPluginSetup : public cMenuSetupPage
|
|||||||
private:
|
private:
|
||||||
bool detachedModeM;
|
bool detachedModeM;
|
||||||
int deviceCountM;
|
int deviceCountM;
|
||||||
int useRtpOverTcpM;
|
|
||||||
int operatingModeM;
|
int operatingModeM;
|
||||||
|
int transportModeM;
|
||||||
const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
|
const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
|
||||||
|
const char *transportModeTextsM[cSatipConfig::eTransportModeCount];
|
||||||
int ciExtensionM;
|
int ciExtensionM;
|
||||||
int cicamsM[MAX_CICAM_COUNT];
|
int cicamsM[MAX_CICAM_COUNT];
|
||||||
const char *cicamTextsM[CA_SYSTEMS_TABLE_SIZE];
|
const char *cicamTextsM[CA_SYSTEMS_TABLE_SIZE];
|
||||||
|
145
socket.c
145
socket.c
@ -21,7 +21,11 @@
|
|||||||
|
|
||||||
cSatipSocket::cSatipSocket()
|
cSatipSocket::cSatipSocket()
|
||||||
: socketPortM(0),
|
: socketPortM(0),
|
||||||
socketDescM(-1)
|
socketDescM(-1),
|
||||||
|
isMulticastM(false),
|
||||||
|
useSsmM(false),
|
||||||
|
streamAddrM(htonl(INADDR_ANY)),
|
||||||
|
sourceAddrM(htonl(INADDR_ANY))
|
||||||
{
|
{
|
||||||
debug1("%s", __PRETTY_FUNCTION__);
|
debug1("%s", __PRETTY_FUNCTION__);
|
||||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||||
@ -36,6 +40,12 @@ cSatipSocket::~cSatipSocket()
|
|||||||
|
|
||||||
bool cSatipSocket::Open(const int portP, const bool reuseP)
|
bool cSatipSocket::Open(const int portP, const bool reuseP)
|
||||||
{
|
{
|
||||||
|
// If socket is there already and it is bound to a different port, it must
|
||||||
|
// be closed first
|
||||||
|
if (portP != socketPortM) {
|
||||||
|
debug1("%s (%d, %d) Socket tear-down", __PRETTY_FUNCTION__, portP, reuseP);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
// Bind to the socket if it is not active already
|
// Bind to the socket if it is not active already
|
||||||
if (socketDescM < 0) {
|
if (socketDescM < 0) {
|
||||||
int yes;
|
int yes;
|
||||||
@ -55,6 +65,11 @@ bool cSatipSocket::Open(const int portP, const bool reuseP)
|
|||||||
ERROR_IF_FUNC(setsockopt(socketDescM, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)) < 0 && errno != ENOPROTOOPT,
|
ERROR_IF_FUNC(setsockopt(socketDescM, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)) < 0 && errno != ENOPROTOOPT,
|
||||||
"setsockopt(SO_REUSEPORT)", Close(), return false);
|
"setsockopt(SO_REUSEPORT)", Close(), return false);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef __FreeBSD__
|
||||||
|
// Allow packet information to be fetched
|
||||||
|
ERROR_IF_FUNC(setsockopt(socketDescM, SOL_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0,
|
||||||
|
"setsockopt(IP_PKTINFO)", Close(), return false);
|
||||||
|
#endif // __FreeBSD__
|
||||||
// Bind socket
|
// Bind socket
|
||||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||||
sockAddrM.sin_family = AF_INET;
|
sockAddrM.sin_family = AF_INET;
|
||||||
@ -63,23 +78,41 @@ bool cSatipSocket::Open(const int portP, const bool reuseP)
|
|||||||
ERROR_IF_FUNC(bind(socketDescM, (struct sockaddr *)&sockAddrM, sizeof(sockAddrM)) < 0,
|
ERROR_IF_FUNC(bind(socketDescM, (struct sockaddr *)&sockAddrM, sizeof(sockAddrM)) < 0,
|
||||||
"bind()", Close(), return false);
|
"bind()", Close(), return false);
|
||||||
// Update socket port
|
// Update socket port
|
||||||
ERROR_IF_FUNC(getsockname(socketDescM,(struct sockaddr*)&sockAddrM, &len) < 0,
|
ERROR_IF_FUNC(getsockname(socketDescM, (struct sockaddr*)&sockAddrM, &len) < 0,
|
||||||
"getsockname()", Close(), return false);
|
"getsockname()", Close(), return false);
|
||||||
socketPortM = ntohs(sockAddrM.sin_port);
|
socketPortM = ntohs(sockAddrM.sin_port);
|
||||||
|
isMulticastM = false;
|
||||||
}
|
}
|
||||||
debug1("%s (%d) socketPort=%d", __PRETTY_FUNCTION__, portP, socketPortM);
|
debug1("%s (%d) socketPort=%d", __PRETTY_FUNCTION__, portP, socketPortM);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cSatipSocket::OpenMulticast(const int portP, const char *streamAddrP, const char *sourceAddrP)
|
||||||
|
{
|
||||||
|
debug1("%s (%d, %s, %s)", __PRETTY_FUNCTION__, portP, streamAddrP, sourceAddrP);
|
||||||
|
if (Open(portP)) {
|
||||||
|
CheckAddress(streamAddrP, &streamAddrM);
|
||||||
|
if (!isempty(sourceAddrP))
|
||||||
|
useSsmM = CheckAddress(sourceAddrP, &sourceAddrM);
|
||||||
|
return Join();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void cSatipSocket::Close(void)
|
void cSatipSocket::Close(void)
|
||||||
{
|
{
|
||||||
debug1("%s sockerPort=%d", __PRETTY_FUNCTION__, socketPortM);
|
debug1("%s sockerPort=%d", __PRETTY_FUNCTION__, socketPortM);
|
||||||
// Check if socket exists
|
// Check if socket exists
|
||||||
if (socketDescM >= 0) {
|
if (socketDescM >= 0) {
|
||||||
|
Leave();
|
||||||
close(socketDescM);
|
close(socketDescM);
|
||||||
socketDescM = -1;
|
socketDescM = -1;
|
||||||
socketPortM = 0;
|
socketPortM = 0;
|
||||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||||
|
streamAddrM = htonl(INADDR_ANY);
|
||||||
|
sourceAddrM = htonl(INADDR_ANY);
|
||||||
|
isMulticastM = false;
|
||||||
|
useSsmM = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +135,96 @@ bool cSatipSocket::Flush(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cSatipSocket::CheckAddress(const char *addrP, in_addr_t *inAddrP)
|
||||||
|
{
|
||||||
|
if (inAddrP) {
|
||||||
|
// First try only the IP address
|
||||||
|
*inAddrP = inet_addr(addrP);
|
||||||
|
if (*inAddrP == htonl(INADDR_NONE)) {
|
||||||
|
debug1("%s (%s, ) Cannot convert to address", __PRETTY_FUNCTION__, addrP);
|
||||||
|
// It may be a host name, get the name
|
||||||
|
struct hostent *host = gethostbyname(addrP);
|
||||||
|
if (!host) {
|
||||||
|
char tmp[64];
|
||||||
|
error("gethostbyname() failed: %s is not valid address: %s", addrP,
|
||||||
|
strerror_r(h_errno, tmp, sizeof(tmp)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*inAddrP = inet_addr(*host->h_addr_list);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipSocket::Join(void)
|
||||||
|
{
|
||||||
|
debug1("%s", __PRETTY_FUNCTION__);
|
||||||
|
// Check if socket exists
|
||||||
|
if (socketDescM >= 0 && !isMulticastM) {
|
||||||
|
// Join a new multicast group
|
||||||
|
if (useSsmM) {
|
||||||
|
// Source-specific multicast (SSM) is used
|
||||||
|
struct group_source_req gsr;
|
||||||
|
struct sockaddr_in *grp;
|
||||||
|
struct sockaddr_in *src;
|
||||||
|
gsr.gsr_interface = 0; // if_nametoindex("any") ?
|
||||||
|
grp = (struct sockaddr_in*)&gsr.gsr_group;
|
||||||
|
grp->sin_family = AF_INET;
|
||||||
|
grp->sin_addr.s_addr = streamAddrM;
|
||||||
|
grp->sin_port = 0;
|
||||||
|
src = (struct sockaddr_in*)&gsr.gsr_source;
|
||||||
|
src->sin_family = AF_INET;
|
||||||
|
src->sin_addr.s_addr = sourceAddrM;
|
||||||
|
src->sin_port = 0;
|
||||||
|
ERROR_IF_RET(setsockopt(socketDescM, SOL_IP, MCAST_JOIN_SOURCE_GROUP, &gsr, sizeof(gsr)) < 0, "setsockopt(MCAST_JOIN_SOURCE_GROUP)", return false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
struct ip_mreq mreq;
|
||||||
|
mreq.imr_multiaddr.s_addr = streamAddrM;
|
||||||
|
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||||
|
ERROR_IF_RET(setsockopt(socketDescM, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_ADD_MEMBERSHIP)", return false);
|
||||||
|
}
|
||||||
|
// Update multicasting flag
|
||||||
|
isMulticastM = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSatipSocket::Leave(void)
|
||||||
|
{
|
||||||
|
debug1("%s", __PRETTY_FUNCTION__);
|
||||||
|
// Check if socket exists
|
||||||
|
if (socketDescM >= 0 && isMulticastM) {
|
||||||
|
// Leave the existing multicast group
|
||||||
|
if (useSsmM) {
|
||||||
|
// Source-specific multicast (SSM) is used
|
||||||
|
struct group_source_req gsr;
|
||||||
|
struct sockaddr_in *grp;
|
||||||
|
struct sockaddr_in *src;
|
||||||
|
gsr.gsr_interface = 0; // if_nametoindex("any") ?
|
||||||
|
grp = (struct sockaddr_in*)&gsr.gsr_group;
|
||||||
|
grp->sin_family = AF_INET;
|
||||||
|
grp->sin_addr.s_addr = streamAddrM;
|
||||||
|
grp->sin_port = 0;
|
||||||
|
src = (struct sockaddr_in*)&gsr.gsr_source;
|
||||||
|
src->sin_family = AF_INET;
|
||||||
|
src->sin_addr.s_addr = sourceAddrM;
|
||||||
|
src->sin_port = 0;
|
||||||
|
ERROR_IF_RET(setsockopt(socketDescM, SOL_IP, MCAST_LEAVE_SOURCE_GROUP, &gsr, sizeof(gsr)) < 0, "setsockopt(MCAST_LEAVE_SOURCE_GROUP)", return false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
struct ip_mreq mreq;
|
||||||
|
mreq.imr_multiaddr.s_addr = streamAddrM;
|
||||||
|
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||||
|
ERROR_IF_RET(setsockopt(socketDescM, SOL_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_DROP_MEMBERSHIP)", return false);
|
||||||
|
}
|
||||||
|
// Update multicasting flag
|
||||||
|
isMulticastM = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP)
|
int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP)
|
||||||
{
|
{
|
||||||
debug16("%s (, %d)", __PRETTY_FUNCTION__, bufferLenP);
|
debug16("%s (, %d)", __PRETTY_FUNCTION__, bufferLenP);
|
||||||
@ -132,8 +255,22 @@ int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP)
|
|||||||
|
|
||||||
if (socketDescM && bufferAddrP && (bufferLenP > 0))
|
if (socketDescM && bufferAddrP && (bufferLenP > 0))
|
||||||
len = (int)recvmsg(socketDescM, &msgh, MSG_DONTWAIT);
|
len = (int)recvmsg(socketDescM, &msgh, MSG_DONTWAIT);
|
||||||
if (len > 0)
|
if (len > 0) {
|
||||||
return len;
|
#ifndef __FreeBSD__
|
||||||
|
if (isMulticastM) {
|
||||||
|
// Process auxiliary received data and validate source address
|
||||||
|
for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
|
||||||
|
if ((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)) {
|
||||||
|
struct in_pktinfo *i = (struct in_pktinfo *)CMSG_DATA(cmsg);
|
||||||
|
if ((i->ipi_addr.s_addr == streamAddrM) || (htonl(INADDR_ANY) == streamAddrM))
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // __FreeBSD__
|
||||||
|
return len;
|
||||||
|
}
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
ERROR_IF_RET(len < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmsg()", return -1);
|
ERROR_IF_RET(len < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmsg()", return -1);
|
||||||
return 0;
|
return 0;
|
||||||
|
9
socket.h
9
socket.h
@ -15,14 +15,23 @@ private:
|
|||||||
int socketPortM;
|
int socketPortM;
|
||||||
int socketDescM;
|
int socketDescM;
|
||||||
struct sockaddr_in sockAddrM;
|
struct sockaddr_in sockAddrM;
|
||||||
|
bool isMulticastM;
|
||||||
|
bool useSsmM;
|
||||||
|
in_addr_t streamAddrM;
|
||||||
|
in_addr_t sourceAddrM;
|
||||||
|
bool CheckAddress(const char *addrP, in_addr_t *inAddrP);
|
||||||
|
bool Join(void);
|
||||||
|
bool Leave(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cSatipSocket();
|
cSatipSocket();
|
||||||
virtual ~cSatipSocket();
|
virtual ~cSatipSocket();
|
||||||
bool Open(const int portP = 0, const bool reuseP = false);
|
bool Open(const int portP = 0, const bool reuseP = false);
|
||||||
|
bool OpenMulticast(const int portP, const char *streamAddrP, const char *sourceAddrP);
|
||||||
virtual void Close(void);
|
virtual void Close(void);
|
||||||
int Fd(void) { return socketDescM; }
|
int Fd(void) { return socketDescM; }
|
||||||
int Port(void) { return socketPortM; }
|
int Port(void) { return socketPortM; }
|
||||||
|
bool IsMulticast(void) { return isMulticastM; }
|
||||||
bool IsOpen(void) { return (socketDescM >= 0); }
|
bool IsOpen(void) { return (socketDescM >= 0); }
|
||||||
bool Flush(void);
|
bool Flush(void);
|
||||||
int Read(unsigned char *bufferAddrP, unsigned int bufferLenP);
|
int Read(unsigned char *bufferAddrP, unsigned int bufferLenP);
|
||||||
|
53
tuner.c
53
tuner.c
@ -55,12 +55,13 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
|||||||
int i = SatipConfig.GetPortRangeStart() ? SatipConfig.GetPortRangeStop() - SatipConfig.GetPortRangeStart() - 1 : 100;
|
int i = SatipConfig.GetPortRangeStart() ? SatipConfig.GetPortRangeStop() - SatipConfig.GetPortRangeStart() - 1 : 100;
|
||||||
int port = SatipConfig.GetPortRangeStart();
|
int port = SatipConfig.GetPortRangeStart();
|
||||||
while (i-- > 0) {
|
while (i-- > 0) {
|
||||||
if (rtpM.Open(port) && rtcpM.Open(rtpM.Port() + 1))
|
// RTP must use an even port number
|
||||||
|
if (rtpM.Open(port) && (rtpM.Port() % 2 == 0) && rtcpM.Open(rtpM.Port() + 1))
|
||||||
break;
|
break;
|
||||||
rtpM.Close();
|
rtpM.Close();
|
||||||
rtcpM.Close();
|
rtcpM.Close();
|
||||||
if (SatipConfig.GetPortRangeStart())
|
if (SatipConfig.GetPortRangeStart())
|
||||||
++port;
|
port += 2;
|
||||||
}
|
}
|
||||||
if ((rtpM.Port() <= 0) || (rtcpM.Port() <= 0)) {
|
if ((rtpM.Port() <= 0) || (rtcpM.Port() <= 0)) {
|
||||||
error("Cannot open required RTP/RTCP ports [device %d]", deviceIdM);
|
error("Cannot open required RTP/RTCP ports [device %d]", deviceIdM);
|
||||||
@ -223,7 +224,7 @@ bool cSatipTuner::Connect(void)
|
|||||||
}
|
}
|
||||||
else if (rtspM.Options(*connectionUri)) {
|
else if (rtspM.Options(*connectionUri)) {
|
||||||
cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM);
|
cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM);
|
||||||
bool useTcp = SatipConfig.GetUseRtpOverTcp() && nextServerM.IsValid() && nextServerM.IsQuirk(cSatipServer::eSatipQuirkRtpOverTcp);
|
bool useTcp = SatipConfig.IsTransportModeRtpOverTcp() && nextServerM.IsValid() && nextServerM.IsQuirk(cSatipServer::eSatipQuirkRtpOverTcp);
|
||||||
// Flush any old content
|
// Flush any old content
|
||||||
//rtpM.Flush();
|
//rtpM.Flush();
|
||||||
//rtcpM.Flush();
|
//rtcpM.Flush();
|
||||||
@ -296,6 +297,11 @@ void cSatipTuner::ProcessVideoData(u_char *bufferP, int lengthP)
|
|||||||
reConnectM.Set(eConnectTimeoutMs);
|
reConnectM.Set(eConnectTimeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cSatipTuner::ProcessRtpData(u_char *bufferP, int lengthP)
|
||||||
|
{
|
||||||
|
rtpM.Process(bufferP, lengthP);
|
||||||
|
}
|
||||||
|
|
||||||
void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP)
|
void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP)
|
||||||
{
|
{
|
||||||
debug16("%s (%d) [device %d]", __PRETTY_FUNCTION__, lengthP, deviceIdM);
|
debug16("%s (%d) [device %d]", __PRETTY_FUNCTION__, lengthP, deviceIdM);
|
||||||
@ -349,6 +355,11 @@ void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP)
|
|||||||
reConnectM.Set(eConnectTimeoutMs);
|
reConnectM.Set(eConnectTimeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cSatipTuner::ProcessRtcpData(u_char *bufferP, int lengthP)
|
||||||
|
{
|
||||||
|
rtcpM.Process(bufferP, lengthP);
|
||||||
|
}
|
||||||
|
|
||||||
void cSatipTuner::SetStreamId(int streamIdP)
|
void cSatipTuner::SetStreamId(int streamIdP)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
@ -366,6 +377,37 @@ void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
|
|||||||
timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs;
|
timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cSatipTuner::SetupTransport(int rtpPortP, int rtcpPortP, const char *streamAddrP, const char *sourceAddrP)
|
||||||
|
{
|
||||||
|
cMutexLock MutexLock(&mutexM);
|
||||||
|
debug1("%s (%d, %d, %s, %s) [device %d]", __PRETTY_FUNCTION__, rtpPortP, rtcpPortP, streamAddrP, sourceAddrP, deviceIdM);
|
||||||
|
bool multicast = !isempty(streamAddrP);
|
||||||
|
// Adapt RTP to any transport media change
|
||||||
|
if (multicast != rtpM.IsMulticast() || rtpPortP != rtpM.Port()) {
|
||||||
|
cSatipPoller::GetInstance()->Unregister(rtpM);
|
||||||
|
rtpM.Close();
|
||||||
|
if (rtpPortP >= 0) {
|
||||||
|
if (multicast)
|
||||||
|
rtpM.OpenMulticast(rtpPortP, streamAddrP, sourceAddrP);
|
||||||
|
else
|
||||||
|
rtpM.Open(rtpPortP);
|
||||||
|
cSatipPoller::GetInstance()->Register(rtpM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Adapt RTCP to any transport media change
|
||||||
|
if (multicast != rtcpM.IsMulticast() || rtcpPortP != rtcpM.Port()) {
|
||||||
|
cSatipPoller::GetInstance()->Unregister(rtcpM);
|
||||||
|
rtcpM.Close();
|
||||||
|
if (rtcpPortP >= 0) {
|
||||||
|
if (multicast)
|
||||||
|
rtcpM.OpenMulticast(rtpPortP, streamAddrP, sourceAddrP);
|
||||||
|
else
|
||||||
|
rtcpM.Open(rtpPortP);
|
||||||
|
cSatipPoller::GetInstance()->Register(rtcpM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cString cSatipTuner::GetBaseUrl(const char *addressP, const int portP)
|
cString cSatipTuner::GetBaseUrl(const char *addressP, const int portP)
|
||||||
{
|
{
|
||||||
debug16("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, addressP, portP, deviceIdM);
|
debug16("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, addressP, portP, deviceIdM);
|
||||||
@ -393,6 +435,9 @@ bool cSatipTuner::SetSource(cSatipServer *serverP, const int transponderP, const
|
|||||||
streamAddrM = rtspM.RtspUnescapeString(*nextServerM.GetAddress());
|
streamAddrM = rtspM.RtspUnescapeString(*nextServerM.GetAddress());
|
||||||
streamParamM = rtspM.RtspUnescapeString(parameterP);
|
streamParamM = rtspM.RtspUnescapeString(parameterP);
|
||||||
streamPortM = nextServerM.GetPort();
|
streamPortM = nextServerM.GetPort();
|
||||||
|
// Modify parameter if required
|
||||||
|
if (nextServerM.IsQuirk(cSatipServer::eSatipQuirkForcePilot) && strstr(parameterP, "msys=dvbs2") && !strstr(parameterP, "plts="))
|
||||||
|
streamParamM = rtspM.RtspUnescapeString(*cString::sprintf("%s&plts=on", parameterP));
|
||||||
// Reconnect
|
// Reconnect
|
||||||
RequestState(tsSet, smExternal);
|
RequestState(tsSet, smExternal);
|
||||||
}
|
}
|
||||||
@ -643,5 +688,5 @@ cString cSatipTuner::GetSignalStatus(void)
|
|||||||
cString cSatipTuner::GetInformation(void)
|
cString cSatipTuner::GetInformation(void)
|
||||||
{
|
{
|
||||||
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
|
||||||
return (currentStateM >= tsTuned) ? cString::sprintf("%s?%s [stream=%d]", *GetBaseUrl(*streamAddrM, streamPortM), *streamParamM, streamIdM) : "connection failed";
|
return (currentStateM >= tsTuned) ? cString::sprintf("%s?%s (%s) [stream=%d]", *GetBaseUrl(*streamAddrM, streamPortM), *streamParamM, *rtspM.GetActiveMode(), streamIdM) : "connection failed";
|
||||||
}
|
}
|
||||||
|
3
tuner.h
3
tuner.h
@ -157,8 +157,11 @@ public:
|
|||||||
public:
|
public:
|
||||||
virtual void ProcessVideoData(u_char *bufferP, int lengthP);
|
virtual void ProcessVideoData(u_char *bufferP, int lengthP);
|
||||||
virtual void ProcessApplicationData(u_char *bufferP, int lengthP);
|
virtual void ProcessApplicationData(u_char *bufferP, int lengthP);
|
||||||
|
virtual void ProcessRtpData(u_char *bufferP, int lengthP);
|
||||||
|
virtual void ProcessRtcpData(u_char *bufferP, int lengthP);
|
||||||
virtual void SetStreamId(int streamIdP);
|
virtual void SetStreamId(int streamIdP);
|
||||||
virtual void SetSessionTimeout(const char *sessionP, int timeoutP);
|
virtual void SetSessionTimeout(const char *sessionP, int timeoutP);
|
||||||
|
virtual void SetupTransport(int rtpPortP, int rtcpPortP, const char *streamAddrP, const char *sourceAddrP);
|
||||||
virtual int GetId(void);
|
virtual int GetId(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,8 +14,11 @@ public:
|
|||||||
virtual ~cSatipTunerIf() {}
|
virtual ~cSatipTunerIf() {}
|
||||||
virtual void ProcessVideoData(u_char *bufferP, int lengthP) = 0;
|
virtual void ProcessVideoData(u_char *bufferP, int lengthP) = 0;
|
||||||
virtual void ProcessApplicationData(u_char *bufferP, int lengthP) = 0;
|
virtual void ProcessApplicationData(u_char *bufferP, int lengthP) = 0;
|
||||||
|
virtual void ProcessRtpData(u_char *bufferP, int lengthP) = 0;
|
||||||
|
virtual void ProcessRtcpData(u_char *bufferP, int lengthP) = 0;
|
||||||
virtual void SetStreamId(int streamIdP) = 0;
|
virtual void SetStreamId(int streamIdP) = 0;
|
||||||
virtual void SetSessionTimeout(const char *sessionP, int timeoutP) = 0;
|
virtual void SetSessionTimeout(const char *sessionP, int timeoutP) = 0;
|
||||||
|
virtual void SetupTransport(int rtpPortP, int rtcpPortP, const char *streamAddrP, const char *sourceAddrP) = 0;
|
||||||
virtual int GetId(void) = 0;
|
virtual int GetId(void) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user