Add support for interface binding via a defined source address.

This commit is contained in:
Rolf Ahrenberg 2017-07-19 17:47:22 +03:00
parent 438f5c9254
commit 3a9dc9a634
11 changed files with 82 additions and 27 deletions

2
README
View File

@ -52,7 +52,7 @@ 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>[:<port>]|<model>[:<filter>]|<description>[:<quirk>];...'
vdr -P 'satip -s [<srcaddress>@]<ipaddress>[:<port>]|<model>[:<filter>]|<description>[:<quirk>];...'
vdr -P 'satip -s 192.168.0.1|DVBS2-2,DVBT2-2|OctopusNet'
vdr -P 'satip -s 192.168.0.1|DVBS2-4|OctopusNet;192.168.0.2|DVBT2-4|minisatip:0x18'
vdr -P 'satip -s 192.168.0.1:554|DVBS2-2:S19.2E|OctopusNet;192.168.0.2:8554|DVBS2-4:S19.2E,S1W|minisatip'

View File

@ -30,10 +30,10 @@ bool cSatipDiscover::Initialize(cSatipDiscoverServers *serversP)
{
debug1("%s", __PRETTY_FUNCTION__);
if (instanceS) {
if (serversP) {
for (cSatipDiscoverServer *s = serversP->First(); s; s = serversP->Next(s))
instanceS->AddServer(s->IpAddress(), s->IpPort(), s->Model(), s->Filters(), s->Description(), s->Quirk());
}
if (serversP) {
for (cSatipDiscoverServer *s = serversP->First(); s; s = serversP->Next(s))
instanceS->AddServer(s->SrcAddress(), s->IpAddress(), s->IpPort(), s->Model(), s->Filters(), s->Description(), s->Quirk());
}
else
instanceS->Activate();
}
@ -271,12 +271,12 @@ void cSatipDiscover::ParseDeviceInfo(const char *addrP, const int portP)
model = modelNode.text().as_string("DVBS2-1");
}
#endif
AddServer(addrP, portP, model, NULL, desc, cSatipServer::eSatipQuirkNone);
AddServer(NULL, addrP, portP, model, NULL, desc, cSatipServer::eSatipQuirkNone);
}
void cSatipDiscover::AddServer(const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP)
void cSatipDiscover::AddServer(const char *srcAddrP, const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP)
{
debug1("%s (%s, %d, %s, %s, %s, %d)", __PRETTY_FUNCTION__, addrP, portP, modelP, filtersP, descP, quirkP);
debug1("%s (%s, %s, %d, %s, %s, %s, %d)", __PRETTY_FUNCTION__, srcAddrP, addrP, portP, modelP, filtersP, descP, quirkP);
cMutexLock MutexLock(&mutexM);
if (SatipConfig.GetUseSingleModelServers() && modelP && !isempty(modelP)) {
int n = 0;
@ -285,9 +285,9 @@ void cSatipDiscover::AddServer(const char *addrP, const int portP, const char *m
while (r) {
r = skipspace(r);
cString desc = cString::sprintf("%s #%d", !isempty(descP) ? descP : "MyBrokenHardware", n++);
cSatipServer *tmp = new cSatipServer(addrP, portP, r, filtersP, desc, quirkP);
cSatipServer *tmp = new cSatipServer(srcAddrP, addrP, portP, r, filtersP, desc, quirkP);
if (!serversM.Update(tmp)) {
info("Adding server '%s|%s|%s' Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
info("Adding server '%s|%s|%s' Bind: %s Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->SrcAddress()) ? tmp->SrcAddress() : "default", !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
serversM.Add(tmp);
}
else
@ -297,9 +297,9 @@ void cSatipDiscover::AddServer(const char *addrP, const int portP, const char *m
FREE_POINTER(p);
}
else {
cSatipServer *tmp = new cSatipServer(addrP, portP, modelP, filtersP, descP, quirkP);
cSatipServer *tmp = new cSatipServer(srcAddrP, addrP, portP, modelP, filtersP, descP, quirkP);
if (!serversM.Update(tmp)) {
info("Adding server '%s|%s|%s' Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
info("Adding server '%s|%s|%s' Bind: %s Filters: %s CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), !isempty(tmp->SrcAddress()) ? tmp->SrcAddress() : "default", !isempty(tmp->Filters()) ? tmp->Filters() : "none", tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
serversM.Add(tmp);
}
else
@ -391,6 +391,13 @@ bool cSatipDiscover::HasServerCI(cSatipServer *serverP)
return serversM.HasCI(serverP);
}
cString cSatipDiscover::GetSourceAddress(cSatipServer *serverP)
{
debug16("%s", __PRETTY_FUNCTION__);
cMutexLock MutexLock(&mutexM);
return serversM.GetSrcAddress(serverP);
}
cString cSatipDiscover::GetServerAddress(cSatipServer *serverP)
{
debug16("%s", __PRETTY_FUNCTION__);

View File

@ -23,17 +23,19 @@ class cSatipDiscoverServer : public cListObject {
private:
int ipPortM;
int quirkM;
cString srcAddressM;
cString ipAddressM;
cString descriptionM;
cString modelM;
cString filtersM;
public:
cSatipDiscoverServer(const char *ipAddressP, const int ipPortP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP)
cSatipDiscoverServer(const char *srcAddressP, const char *ipAddressP, const int ipPortP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP)
{
ipAddressM = ipAddressP; ipPortM = ipPortP; modelM = modelP; filtersM = filtersP; descriptionM = descriptionP; quirkM = quirkP;
srcAddressM = srcAddressP; ipAddressM = ipAddressP; ipPortM = ipPortP; modelM = modelP; filtersM = filtersP; descriptionM = descriptionP; quirkM = quirkP;
}
int IpPort(void) { return ipPortM; }
int Quirk(void) { return quirkM; }
const char *SrcAddress(void) { return *srcAddressM; }
const char *IpAddress(void) { return *ipAddressM; }
const char *Model(void) { return *modelM; }
const char *Filters(void) { return *filtersM; }
@ -69,7 +71,7 @@ private:
void Deactivate(void);
int ParseRtspPort(void);
void ParseDeviceInfo(const char *addrP, const int portP);
void AddServer(const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP);
void AddServer(const char *srcAddrP, const char *addrP, const int portP, const char *modelP, const char *filtersP, const char *descP, const int quirkP);
void Fetch(const char *urlP);
// constructor
cSatipDiscover();
@ -98,6 +100,7 @@ public:
bool IsServerQuirk(cSatipServer *serverP, int quirkP);
bool HasServerCI(cSatipServer *serverP);
cString GetServerAddress(cSatipServer *serverP);
cString GetSourceAddress(cSatipServer *serverP);
int GetServerPort(cSatipServer *serverP);
cString GetServerList(void);
int NumProvidedSystems(void);

16
rtsp.c
View File

@ -193,6 +193,22 @@ void cSatipRtsp::Reset(void)
Create();
}
bool cSatipRtsp::SetInterface(const char *bindAddrP)
{
debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, bindAddrP, tunerM.GetId());
bool result = true;
CURLcode res = CURLE_OK;
if (handleM && !isempty(bindAddrP)) {
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERFACE, *cString::sprintf("host!%s", bindAddrP));
}
else {
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_INTERFACE, NULL);
}
return result;
}
bool cSatipRtsp::Options(const char *uriP)
{
debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, uriP, tunerM.GetId());

1
rtsp.h
View File

@ -59,6 +59,7 @@ public:
cString GetActiveMode(void);
cString RtspUnescapeString(const char *strP);
void Reset(void);
bool SetInterface(const char *bindAddrP);
bool Options(const char *uriP);
bool Setup(const char *uriP, int rtpPortP, int rtcpPortP, bool useTcpP);
bool SetSession(const char *sessionP);

14
satip.c
View File

@ -232,7 +232,7 @@ void cPluginSatip::ParseServer(const char *paramP)
while (r) {
r = skipspace(r);
debug3("%s server[%d]=%s", __PRETTY_FUNCTION__, n, r);
cString serverAddr, serverModel, serverFilters, serverDescription;
cString sourceAddr, serverAddr, serverModel, serverFilters, serverDescription;
int serverQuirk = cSatipServer::eSatipQuirkNone;
int serverPort = SATIP_DEFAULT_RTSP_PORT;
int n2 = 0;
@ -243,8 +243,14 @@ void cPluginSatip::ParseServer(const char *paramP)
switch (n2++) {
case 0:
{
char *r3 = strchr(r2, '@');
if (r3) {
*r3 = 0;
sourceAddr = r2;
r2 = r3 + 1;
}
serverAddr = r2;
char *r3 = strchr(r2, ':');
r3 = strchr(r2, ':');
if (r3) {
serverPort = strtol(r3 + 1, NULL, 0);
serverAddr = serverAddr.Truncate(r3 - r2);
@ -277,10 +283,10 @@ void cPluginSatip::ParseServer(const char *paramP)
r2 = strtok_r(NULL, "|", &s2);
}
if (*serverAddr && *serverModel && *serverDescription) {
debug1("%s ipaddr=%s port=%d model=%s (%s) desc=%s (%d)", __PRETTY_FUNCTION__, *serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk);
debug1("%s srcaddr=%s ipaddr=%s port=%d model=%s (%s) desc=%s (%d)", __PRETTY_FUNCTION__, *sourceAddr, *serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk);
if (!serversM)
serversM = new cSatipDiscoverServers();
serversM->Add(new cSatipDiscoverServer(*serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk));
serversM->Add(new cSatipDiscoverServer(*sourceAddr, *serverAddr, serverPort, *serverModel, *serverFilters, *serverDescription, serverQuirk));
}
++n;
r = strtok_r(NULL, ";", &s);

View File

@ -80,8 +80,9 @@ bool cSatipFrontends::Detach(int deviceIdP, int transponderP)
// --- cSatipServer -----------------------------------------------------------
cSatipServer::cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP)
: addressM((addressP && *addressP) ? addressP : "0.0.0.0"),
cSatipServer::cSatipServer(const char *srcAddressP, const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP)
: srcAddressM((srcAddressP && *srcAddressP) ? srcAddressP : ""),
addressM((addressP && *addressP) ? addressP : "0.0.0.0"),
modelM((modelP && *modelP) ? modelP : "DVBS-1"),
filtersM((filtersP && *filtersP) ? filtersP : ""),
descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"),
@ -128,12 +129,14 @@ cSatipServer::cSatipServer(const char *addressP, const int portP, const char *mo
quirkM |= eSatipQuirkRtpOverTcp;
// These devices contain a play (add/delpids) parameter bug:
if (strstr(*descriptionM, "FRITZ!Box 6490 Cable") || // FRITZ!Box 6490 Cable
strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") // FRITZ!WLAN Repeater DVB-C
strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C
strstr(*descriptionM, "fritzdvbc") // FRITZ!WLAN Repeater DVB-C (old firmware)
)
quirkM |= eSatipQuirkPlayPids;
// These devices contain a frontend locking bug:
if (strstr(*descriptionM, "FRITZ!Box 6490 Cable") || // FRITZ!Box 6490 Cable
strstr(*descriptionM, "FRITZ!WLAN Repeater DVB-C") || // FRITZ!WLAN Repeater DVB-C
strstr(*descriptionM, "fritzdvbc") || // FRITZ!WLAN Repeater DVB-C (old firmware)
strstr(*descriptionM, "Schwaiger Sat>IP Server") // Schwaiger MS41IP
)
quirkM |= eSatipQuirkForceLock;
@ -445,6 +448,18 @@ void cSatipServers::Cleanup(uint64_t intervalMsP)
}
}
cString cSatipServers::GetSrcAddress(cSatipServer *serverP)
{
cString address = "";
for (cSatipServer *s = First(); s; s = Next(s)) {
if (s == serverP) {
address = s->SrcAddress();
break;
}
}
return address;
}
cString cSatipServers::GetAddress(cSatipServer *serverP)
{
cString address = "";
@ -485,7 +500,10 @@ cString cSatipServers::List(void)
{
cString list = "";
for (cSatipServer *s = First(); s; s = Next(s))
list = cString::sprintf("%s%c %s|%s|%s\n", *list, s->IsActive() ? '+' : '-', s->Address(), s->Model(), s->Description());
if (isempty(s->SrcAddress()))
list = cString::sprintf("%s%c %s|%s|%s\n", *list, s->IsActive() ? '+' : '-', s->Address(), s->Model(), s->Description());
else
list = cString::sprintf("%s%c %s@%s|%s|%s\n", *list, s->IsActive() ? '+' : '-', s->SrcAddress(), s->Address(), s->Model(), s->Description());
return list;
}

View File

@ -57,6 +57,7 @@ private:
enum {
eSatipMaxSourceFilters = 16
};
cString srcAddressM;
cString addressM;
cString modelM;
cString filtersM;
@ -84,7 +85,7 @@ public:
eSatipQuirkForcePilot = 0x40,
eSatipQuirkMask = 0xFF
};
cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP);
cSatipServer(const char *srcAddressP, const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP, const int quirkP);
virtual ~cSatipServer();
virtual int Compare(const cListObject &listObjectP) const;
bool Assign(int deviceIdP, int sourceP, int systemP, int transponderP);
@ -98,6 +99,7 @@ public:
int GetModulesDVBC(void);
int GetModulesDVBC2(void);
void Activate(bool onOffP) { activeM = onOffP; }
const char *SrcAddress(void) { return *srcAddressM; }
const char *Address(void) { return *addressM; }
const char *Model(void) { return *modelM; }
const char *Filters(void) { return *filtersM; }
@ -128,6 +130,7 @@ public:
bool HasCI(cSatipServer *serverP);
void Cleanup(uint64_t intervalMsP = 0);
cString GetAddress(cSatipServer *serverP);
cString GetSrcAddress(cSatipServer *serverP);
cString GetString(cSatipServer *serverP);
int GetPort(cSatipServer *serverP);
cString List(void);

View File

@ -105,7 +105,7 @@ cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP)
: cOsdMenu(tr("SAT>IP Server"), 20),
serverM(serverP),
activeM(serverP && serverP->IsActive()),
addressM(serverP ? serverP->Address() : "---"),
addressM(serverP ? (isempty(serverP->SrcAddress()) ? serverP->Address() : *cString::sprintf("%s@%s", serverP->SrcAddress(), serverP->Address())) : "---"),
modelM(serverP ? serverP->Model() : "---"),
descriptionM(serverP ? serverP->Description() : "---"),
ciExtensionM(serverP && serverP->HasCI() ? trVDR("yes") : trVDR("no")),
@ -167,7 +167,7 @@ cSatipServerItem::cSatipServerItem(cSatipServer *serverP)
{
SetSelectable(true);
// Must begin with a '#' character!
SetText(*cString::sprintf("%s %s (%s)\t%s", serverM->IsActive() ? "+" : "-", serverM->Address(), serverM->Model(), serverM->Description()));
SetText(*cString::sprintf("%s %s (%s)\t%s", serverM->IsActive() ? "+" : "-", isempty(serverM->SrcAddress()) ? serverM->Address() : *cString::sprintf("%s@%s", serverM->SrcAddress(), serverM->Address()), serverM->Model(), serverM->Description()));
}
void cSatipServerItem::SetMenuItem(cSkinDisplayMenu *displayMenuP, int indexP, bool currentP, bool selectableP)

View File

@ -224,7 +224,7 @@ bool cSatipTuner::Connect(void)
return true;
}
}
else if (rtspM.Options(*connectionUri)) {
else if (rtspM.SetInterface(nextServerM.IsValid() ? *nextServerM.GetSrcAddress() : NULL) && rtspM.Options(*connectionUri)) {
cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM);
bool useTcp = SatipConfig.IsTransportModeRtpOverTcp() && nextServerM.IsValid() && nextServerM.IsQuirk(cSatipServer::eSatipQuirkRtpOverTcp);
// Flush any old content

View File

@ -69,6 +69,7 @@ public:
void Set(cSatipServer *serverP, const int transponderP) { serverM = serverP; transponderM = transponderP; }
void Reset(void) { serverM = NULL; transponderM = 0; }
cString GetAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerAddress(serverM) : ""; }
cString GetSrcAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetSourceAddress(serverM) : ""; }
int GetPort(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerPort(serverM) : SATIP_DEFAULT_RTSP_PORT; }
cString GetInfo(void) { return cString::sprintf("server=%s deviceid=%d transponder=%d", serverM ? "assigned" : "null", deviceIdM, transponderM); }
};