diff --git a/README b/README index 0d414ab..25339d8 100644 --- a/README +++ b/README @@ -52,7 +52,7 @@ separated list of "||" 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 [:]|[:]|[:];...' +vdr -P 'satip -s [@][:]|[:]|[:];...' 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' diff --git a/discover.c b/discover.c index 7c128a8..37f8a44 100644 --- a/discover.c +++ b/discover.c @@ -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__); diff --git a/discover.h b/discover.h index 52c3d30..6c594b7 100644 --- a/discover.h +++ b/discover.h @@ -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); diff --git a/rtsp.c b/rtsp.c index 87c194a..2f31699 100644 --- a/rtsp.c +++ b/rtsp.c @@ -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()); diff --git a/rtsp.h b/rtsp.h index fb09c27..d49f1ac 100644 --- a/rtsp.h +++ b/rtsp.h @@ -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); diff --git a/satip.c b/satip.c index 0d00647..e906d69 100644 --- a/satip.c +++ b/satip.c @@ -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); diff --git a/server.c b/server.c index b7964df..0df2b9b 100644 --- a/server.c +++ b/server.c @@ -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; } diff --git a/server.h b/server.h index ea9ae2d..c8d387e 100644 --- a/server.h +++ b/server.h @@ -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); diff --git a/setup.c b/setup.c index c178c61..baa4d57 100644 --- a/setup.c +++ b/setup.c @@ -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) diff --git a/tuner.c b/tuner.c index 607dfb8..0cc0ad9 100644 --- a/tuner.c +++ b/tuner.c @@ -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 diff --git a/tuner.h b/tuner.h index 075b49d..37cd40b 100644 --- a/tuner.h +++ b/tuner.h @@ -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); } };