mirror of
				https://github.com/rofafor/vdr-plugin-satip.git
				synced 2023-10-10 11:37:42 +00:00 
			
		
		
		
	Add a preliminary multicast support.
This commit is contained in:
		
							
								
								
									
										5
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								README
									
									
									
									
									
								
							@@ -116,6 +116,11 @@ Setup menu:
 | 
			
		||||
                             "Disable filter" options which allow you
 | 
			
		||||
                             to disable the individual section filters.
 | 
			
		||||
                             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.
 | 
			
		||||
- [Yellow:Devices]           Opens SAT>IP device status menu.
 | 
			
		||||
- [Blue:Info]                Opens SAT>IP information/statistics menu.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								config.c
									
									
									
									
									
								
							@@ -19,7 +19,7 @@ cSatipConfig::cSatipConfig(void)
 | 
			
		||||
  useBytesM(1),
 | 
			
		||||
  portRangeStartM(0),
 | 
			
		||||
  portRangeStopM(0),
 | 
			
		||||
  useRtpOverTcpM(false),
 | 
			
		||||
  transportModeM(eTransportModeUnicast),
 | 
			
		||||
  detachedModeM(false),
 | 
			
		||||
  disableServerQuirksM(false),
 | 
			
		||||
  useSingleModelServersM(false)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								config.h
									
									
									
									
									
								
							@@ -21,7 +21,7 @@ private:
 | 
			
		||||
  unsigned int useBytesM;
 | 
			
		||||
  unsigned int portRangeStartM;
 | 
			
		||||
  unsigned int portRangeStopM;
 | 
			
		||||
  bool useRtpOverTcpM;
 | 
			
		||||
  unsigned int transportModeM;
 | 
			
		||||
  bool detachedModeM;
 | 
			
		||||
  bool disableServerQuirksM;
 | 
			
		||||
  bool useSingleModelServersM;
 | 
			
		||||
@@ -37,6 +37,12 @@ public:
 | 
			
		||||
    eOperatingModeHigh,
 | 
			
		||||
    eOperatingModeCount
 | 
			
		||||
  };
 | 
			
		||||
  enum eTransportMode {
 | 
			
		||||
    eTransportModeUnicast = 0,
 | 
			
		||||
    eTransportModeMulticast,
 | 
			
		||||
    eTransportModeRtpOverTcp,
 | 
			
		||||
    eTransportModeCount
 | 
			
		||||
  };
 | 
			
		||||
  enum eTraceMode {
 | 
			
		||||
    eTraceModeNormal  = 0x0000,
 | 
			
		||||
    eTraceModeDebug1  = 0x0001,
 | 
			
		||||
@@ -70,7 +76,10 @@ public:
 | 
			
		||||
  int GetCICAM(unsigned int indexP) const;
 | 
			
		||||
  unsigned int GetEITScan(void) const { return eitScanM; }
 | 
			
		||||
  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 GetDisableServerQuirks(void) const { return disableServerQuirksM; }
 | 
			
		||||
  bool GetUseSingleModelServers(void) const { return useSingleModelServersM; }
 | 
			
		||||
@@ -87,7 +96,7 @@ public:
 | 
			
		||||
  void SetCICAM(unsigned int indexP, int cicamP);
 | 
			
		||||
  void SetEITScan(unsigned int onOffP) { eitScanM = 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 SetDisableServerQuirks(bool onOffP) { disableServerQuirksM = onOffP; }
 | 
			
		||||
  void SetUseSingleModelServers(bool onOffP) { useSingleModelServersM = onOffP; }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								po/ca_ES.po
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								po/ca_ES.po
									
									
									
									
									
								
							@@ -85,6 +85,15 @@ msgstr "Normal"
 | 
			
		||||
msgid "high"
 | 
			
		||||
msgstr "Alt"
 | 
			
		||||
 | 
			
		||||
msgid "Unicast"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Multicast"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "RTP-over-TCP"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Button$Devices"
 | 
			
		||||
msgstr "Dispositius"
 | 
			
		||||
 | 
			
		||||
@@ -178,13 +187,13 @@ msgstr "Filtra"
 | 
			
		||||
msgid "Define an ill-behaving filter to be blacklisted."
 | 
			
		||||
msgstr "Definir un filtre mal comportar a la llista negra."
 | 
			
		||||
 | 
			
		||||
msgid "Use RTP-over-TCP mode"
 | 
			
		||||
msgid "Transport mode"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Define whether the RTP-over-TCP mode shall be used.\n"
 | 
			
		||||
"Define which transport mode shall be used.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"This setting affects only SAT>IP devices supporting the feature."
 | 
			
		||||
"Unicast, Multicast, RTP-over-TCP"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Active SAT>IP servers:"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								po/de_DE.po
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								po/de_DE.po
									
									
									
									
									
								
							@@ -85,6 +85,15 @@ msgstr "normal"
 | 
			
		||||
msgid "high"
 | 
			
		||||
msgstr "hoch"
 | 
			
		||||
 | 
			
		||||
msgid "Unicast"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Multicast"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "RTP-over-TCP"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Button$Devices"
 | 
			
		||||
msgstr "Geräte"
 | 
			
		||||
 | 
			
		||||
@@ -178,13 +187,13 @@ msgstr "Filter"
 | 
			
		||||
msgid "Define an ill-behaving filter to be blacklisted."
 | 
			
		||||
msgstr "Bestimme einen fehlerhaften Filter der ausgeblendet werden soll."
 | 
			
		||||
 | 
			
		||||
msgid "Use RTP-over-TCP mode"
 | 
			
		||||
msgid "Transport mode"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Define whether the RTP-over-TCP mode shall be used.\n"
 | 
			
		||||
"Define which transport mode shall be used.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"This setting affects only SAT>IP devices supporting the feature."
 | 
			
		||||
"Unicast, Multicast, RTP-over-TCP"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Active SAT>IP servers:"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								po/es_ES.po
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								po/es_ES.po
									
									
									
									
									
								
							@@ -85,6 +85,15 @@ msgstr "Normal"
 | 
			
		||||
msgid "high"
 | 
			
		||||
msgstr "Alto"
 | 
			
		||||
 | 
			
		||||
msgid "Unicast"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Multicast"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "RTP-over-TCP"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Button$Devices"
 | 
			
		||||
msgstr "Dispositivos"
 | 
			
		||||
 | 
			
		||||
@@ -178,13 +187,13 @@ msgstr "Filtra"
 | 
			
		||||
msgid "Define an ill-behaving filter to be blacklisted."
 | 
			
		||||
msgstr "Define un filtro para poner en la lista negra."
 | 
			
		||||
 | 
			
		||||
msgid "Use RTP-over-TCP mode"
 | 
			
		||||
msgid "Transport mode"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Define whether the RTP-over-TCP mode shall be used.\n"
 | 
			
		||||
"Define which transport mode shall be used.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"This setting affects only SAT>IP devices supporting the feature."
 | 
			
		||||
"Unicast, Multicast, RTP-over-TCP"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Active SAT>IP servers:"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								po/fi_FI.po
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								po/fi_FI.po
									
									
									
									
									
								
							@@ -85,6 +85,15 @@ msgstr "normaali"
 | 
			
		||||
msgid "high"
 | 
			
		||||
msgstr "korkea"
 | 
			
		||||
 | 
			
		||||
msgid "Unicast"
 | 
			
		||||
msgstr "Unicast"
 | 
			
		||||
 | 
			
		||||
msgid "Multicast"
 | 
			
		||||
msgstr "Multicast"
 | 
			
		||||
 | 
			
		||||
msgid "RTP-over-TCP"
 | 
			
		||||
msgstr "RTP-over-TCP"
 | 
			
		||||
 | 
			
		||||
msgid "Button$Devices"
 | 
			
		||||
msgstr "Laitteet"
 | 
			
		||||
 | 
			
		||||
@@ -177,17 +186,17 @@ msgstr "Suodatin"
 | 
			
		||||
msgid "Define an ill-behaving filter to be blacklisted."
 | 
			
		||||
msgstr "Määrittele käytöstä poistettava suodatin, joka lisätään mustalle listalle."
 | 
			
		||||
 | 
			
		||||
msgid "Use RTP-over-TCP mode"
 | 
			
		||||
msgstr "Käytä RTP-over-TCP -moodia"
 | 
			
		||||
msgid "Transport mode"
 | 
			
		||||
msgstr "Siirtoyhteystapa"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Define whether the RTP-over-TCP mode shall be used.\n"
 | 
			
		||||
"Define which transport mode shall be used.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"This setting affects only SAT>IP devices supporting the feature."
 | 
			
		||||
"Unicast, Multicast, RTP-over-TCP"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Määrittele RTP-over-TCP -moodin käyttöönotto.\n"
 | 
			
		||||
"Määrittele käytettävä siirtoyhteystapa.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Tämä asetus vaikuttaa vain SAT>IP-laitteisiin, jotka tukevat kyseistä ominaisuutta."
 | 
			
		||||
"Unicast, Multicast, RTP-over-TCP"
 | 
			
		||||
 | 
			
		||||
msgid "Active SAT>IP servers:"
 | 
			
		||||
msgstr "Aktiiviset SAT>IP-palvelimet:"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								rtsp.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								rtsp.c
									
									
									
									
									
								
							@@ -17,7 +17,6 @@ cSatipRtsp::cSatipRtsp(cSatipTunerIf &tunerP)
 | 
			
		||||
: tunerM(tunerP),
 | 
			
		||||
  headerBufferM(),
 | 
			
		||||
  dataBufferM(),
 | 
			
		||||
  modeM(cmUnicast),
 | 
			
		||||
  handleM(NULL),
 | 
			
		||||
  headerListM(NULL),
 | 
			
		||||
  errorNoMoreM(""),
 | 
			
		||||
@@ -182,13 +181,12 @@ bool cSatipRtsp::Setup(const char *uriP, int rtpPortP, int rtcpPortP, bool useTc
 | 
			
		||||
     cTimeMs processing(0);
 | 
			
		||||
     CURLcode res = CURLE_OK;
 | 
			
		||||
 | 
			
		||||
     switch (modeM) {
 | 
			
		||||
       case cmMulticast:
 | 
			
		||||
            // RTP/AVP;multicast;destination=<IP multicast address>;port=<RTP port>-<RTCP port>;ttl=<ttl>
 | 
			
		||||
            transport = cString::sprintf("RTP/AVP;multicast;port=%d-%d", rtpPortP, rtcpPortP);
 | 
			
		||||
     switch (SatipConfig.GetTransportMode()) {
 | 
			
		||||
       case cSatipConfig::eTransportModeMulticast:
 | 
			
		||||
            // RTP/AVP;multicast;destination=<multicast group address>;port=<RTP port>-<RTCP port>;ttl=<ttl>[;source=<multicast source address>]
 | 
			
		||||
            transport = cString::sprintf("RTP/AVP;multicast");
 | 
			
		||||
            break;
 | 
			
		||||
       default:
 | 
			
		||||
       case cmUnicast:
 | 
			
		||||
            // RTP/AVP;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);
 | 
			
		||||
@@ -352,6 +350,26 @@ void cSatipRtsp::ParseHeader(void)
 | 
			
		||||
              tunerM.SetSessionTimeout(skipspace(session), -1);
 | 
			
		||||
           FREE_POINTER(session);
 | 
			
		||||
           }
 | 
			
		||||
        else if (strstr(r, "Transport:")) {
 | 
			
		||||
           int rtp = -1, rtcp = -1, ttl = -1;
 | 
			
		||||
           char *tmp = NULL, *destination = NULL, *source = NULL;
 | 
			
		||||
           if (sscanf(r, "Transport:%m[^;];unicast;client_port=%11d-%11d", &tmp, &rtp, &rtcp) == 3)
 | 
			
		||||
              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)
 | 
			
		||||
              tunerM.SetupTransport(rtp, rtcp, destination, source);
 | 
			
		||||
           // TODO: else if (sscanf(r, "Transport:%m[^;];interleaved=%11d-%11d", &tmp, &rtp, &rtcp) == 3)
 | 
			
		||||
           // Stream data such as RTP packets is encapsulated by an ASCII dollar
 | 
			
		||||
           // sign (24 hexadecimal), followed by a one-byte channel identifier,
 | 
			
		||||
           // followed by the length of the encapsulated binary data as a binary,
 | 
			
		||||
           // two-byte integer in network byte order. The stream data follows
 | 
			
		||||
           // immediately afterwards, without a CRLF, but including the upper-layer
 | 
			
		||||
           // protocol headers. Each $ block contains exactly one upper-layer
 | 
			
		||||
           // protocol data unit, e.g., one RTP packet.
 | 
			
		||||
           FREE_POINTER(tmp);
 | 
			
		||||
           FREE_POINTER(destination);
 | 
			
		||||
           FREE_POINTER(source);
 | 
			
		||||
           }
 | 
			
		||||
        r = strtok_r(NULL, "\r\n", &s);
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								rtsp.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								rtsp.h
									
									
									
									
									
								
							@@ -27,12 +27,10 @@ private:
 | 
			
		||||
  enum {
 | 
			
		||||
    eConnectTimeoutMs = 1500,  // in milliseconds
 | 
			
		||||
  };
 | 
			
		||||
  enum eCommunicationMode { cmUnicast, cmMulticast };
 | 
			
		||||
 | 
			
		||||
  cSatipTunerIf &tunerM;
 | 
			
		||||
  cSatipMemoryBuffer headerBufferM;
 | 
			
		||||
  cSatipMemoryBuffer dataBufferM;
 | 
			
		||||
  eCommunicationMode modeM;
 | 
			
		||||
  CURL *handleM;
 | 
			
		||||
  struct curl_slist *headerListM;
 | 
			
		||||
  cString errorNoMoreM;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								satip.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								satip.c
									
									
									
									
									
								
							@@ -305,7 +305,12 @@ void cPluginSatip::ParsePortRange(const char *paramP)
 | 
			
		||||
     rangeStart = 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);
 | 
			
		||||
     rangeStart = 0;
 | 
			
		||||
     rangeStop = 0;
 | 
			
		||||
@@ -401,8 +406,8 @@ bool cPluginSatip::SetupParse(const char *nameP, const char *valueP)
 | 
			
		||||
     for (unsigned int i = 0; i < DisabledFiltersCount; ++i)
 | 
			
		||||
         SatipConfig.SetDisabledFilters(i, DisabledFilters[i]);
 | 
			
		||||
     }
 | 
			
		||||
  else if (!strcasecmp(nameP, "UseRtpOverTcp"))
 | 
			
		||||
     SatipConfig.SetUseRtpOverTcp(atoi(valueP));
 | 
			
		||||
  else if (!strcasecmp(nameP, "TransportMode"))
 | 
			
		||||
     SatipConfig.SetTransportMode(atoi(valueP));
 | 
			
		||||
  else
 | 
			
		||||
     return false;
 | 
			
		||||
  return true;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								setup.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								setup.c
									
									
									
									
									
								
							@@ -344,8 +344,8 @@ eOSState cSatipMenuInfo::ProcessKey(eKeys keyP)
 | 
			
		||||
cSatipPluginSetup::cSatipPluginSetup()
 | 
			
		||||
: detachedModeM(SatipConfig.GetDetachedMode()),
 | 
			
		||||
  deviceCountM(0),
 | 
			
		||||
  useRtpOverTcpM(SatipConfig.GetUseRtpOverTcp()),
 | 
			
		||||
  operatingModeM(SatipConfig.GetOperatingMode()),
 | 
			
		||||
  transportModeM(SatipConfig.GetTransportMode()),
 | 
			
		||||
  ciExtensionM(SatipConfig.GetCIExtension()),
 | 
			
		||||
  eitScanM(SatipConfig.GetEITScan()),
 | 
			
		||||
  numDisabledSourcesM(SatipConfig.GetDisabledSourcesCount()),
 | 
			
		||||
@@ -356,6 +356,9 @@ cSatipPluginSetup::cSatipPluginSetup()
 | 
			
		||||
  operatingModeTextsM[cSatipConfig::eOperatingModeLow]    = tr("low");
 | 
			
		||||
  operatingModeTextsM[cSatipConfig::eOperatingModeNormal] = tr("normal");
 | 
			
		||||
  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)
 | 
			
		||||
      cicamsM[i] = SatipConfig.GetCICAM(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."));
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
  Add(new cMenuEditBoolItem(tr("Use RTP-over-TCP mode"), &useRtpOverTcpM));
 | 
			
		||||
  helpM.Append(tr("Define whether the RTP-over-TCP mode shall be used.\n\nThis setting affects only SAT>IP devices supporting the feature."));
 | 
			
		||||
  Add(new cMenuEditStraItem(tr("Transport mode"), &transportModeM, ELEMENTS(transportModeTextsM) - 1, transportModeTextsM)); // TODO: RTP-over-TCP
 | 
			
		||||
  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));
 | 
			
		||||
  helpM.Append("");
 | 
			
		||||
 | 
			
		||||
@@ -563,16 +566,16 @@ void cSatipPluginSetup::StoreFilters(const char *nameP, int *valuesP)
 | 
			
		||||
void cSatipPluginSetup::Store(void)
 | 
			
		||||
{
 | 
			
		||||
  // Store values into setup.conf
 | 
			
		||||
  SetupStore("UseRtpOverTcp", useRtpOverTcpM);
 | 
			
		||||
  SetupStore("OperatingMode", operatingModeM);
 | 
			
		||||
  SetupStore("TransportMode", transportModeM);
 | 
			
		||||
  SetupStore("EnableCIExtension", ciExtensionM);
 | 
			
		||||
  SetupStore("EnableEITScan", eitScanM);
 | 
			
		||||
  StoreCicams("CICAM", cicamsM);
 | 
			
		||||
  StoreSources("DisabledSources", disabledSourcesM);
 | 
			
		||||
  StoreFilters("DisabledFilters", disabledFilterIndexesM);
 | 
			
		||||
  // Update global config
 | 
			
		||||
  SatipConfig.SetUseRtpOverTcp(useRtpOverTcpM);
 | 
			
		||||
  SatipConfig.SetOperatingMode(operatingModeM);
 | 
			
		||||
  SatipConfig.SetTransportMode(transportModeM);
 | 
			
		||||
  SatipConfig.SetCIExtension(ciExtensionM);
 | 
			
		||||
  SatipConfig.SetEITScan(eitScanM);
 | 
			
		||||
  for (int i = 0; i < MAX_CICAM_COUNT; ++i)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								setup.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								setup.h
									
									
									
									
									
								
							@@ -17,9 +17,10 @@ class cSatipPluginSetup : public cMenuSetupPage
 | 
			
		||||
private:
 | 
			
		||||
  bool detachedModeM;
 | 
			
		||||
  int deviceCountM;
 | 
			
		||||
  int useRtpOverTcpM;
 | 
			
		||||
  int operatingModeM;
 | 
			
		||||
  int transportModeM;
 | 
			
		||||
  const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount];
 | 
			
		||||
  const char *transportModeTextsM[cSatipConfig::eTransportModeCount];
 | 
			
		||||
  int ciExtensionM;
 | 
			
		||||
  int cicamsM[MAX_CICAM_COUNT];
 | 
			
		||||
  const char *cicamTextsM[CA_SYSTEMS_TABLE_SIZE];
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										145
									
								
								socket.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								socket.c
									
									
									
									
									
								
							@@ -21,7 +21,11 @@
 | 
			
		||||
 | 
			
		||||
cSatipSocket::cSatipSocket()
 | 
			
		||||
: socketPortM(0),
 | 
			
		||||
  socketDescM(-1)
 | 
			
		||||
  socketDescM(-1),
 | 
			
		||||
  isMulticastM(false),
 | 
			
		||||
  useSsmM(false),
 | 
			
		||||
  streamAddrM(htonl(INADDR_ANY)),
 | 
			
		||||
  sourceAddrM(htonl(INADDR_ANY))
 | 
			
		||||
{
 | 
			
		||||
  debug1("%s", __PRETTY_FUNCTION__);
 | 
			
		||||
  memset(&sockAddrM, 0, sizeof(sockAddrM));
 | 
			
		||||
@@ -36,6 +40,12 @@ cSatipSocket::~cSatipSocket()
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
  if (socketDescM < 0) {
 | 
			
		||||
     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,
 | 
			
		||||
                   "setsockopt(SO_REUSEPORT)", Close(), return false);
 | 
			
		||||
#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
 | 
			
		||||
     memset(&sockAddrM, 0, sizeof(sockAddrM));
 | 
			
		||||
     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,
 | 
			
		||||
                   "bind()", Close(), return false);
 | 
			
		||||
     // 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);
 | 
			
		||||
     socketPortM = ntohs(sockAddrM.sin_port);
 | 
			
		||||
     isMulticastM = false;
 | 
			
		||||
     }
 | 
			
		||||
  debug1("%s (%d) socketPort=%d", __PRETTY_FUNCTION__, portP, socketPortM);
 | 
			
		||||
  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)
 | 
			
		||||
{
 | 
			
		||||
  debug1("%s sockerPort=%d", __PRETTY_FUNCTION__, socketPortM);
 | 
			
		||||
  // Check if socket exists
 | 
			
		||||
  if (socketDescM >= 0) {
 | 
			
		||||
     Leave();
 | 
			
		||||
     close(socketDescM);
 | 
			
		||||
     socketDescM = -1;
 | 
			
		||||
     socketPortM = 0;
 | 
			
		||||
     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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
  debug16("%s (, %d)", __PRETTY_FUNCTION__, bufferLenP);
 | 
			
		||||
@@ -132,8 +255,22 @@ int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP)
 | 
			
		||||
 | 
			
		||||
    if (socketDescM && bufferAddrP && (bufferLenP > 0))
 | 
			
		||||
       len = (int)recvmsg(socketDescM, &msgh, MSG_DONTWAIT);
 | 
			
		||||
    if (len > 0)
 | 
			
		||||
       return len;
 | 
			
		||||
    if (len > 0) {
 | 
			
		||||
#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);
 | 
			
		||||
  ERROR_IF_RET(len < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmsg()", return -1);
 | 
			
		||||
  return 0;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								socket.h
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								socket.h
									
									
									
									
									
								
							@@ -15,14 +15,23 @@ private:
 | 
			
		||||
  int socketPortM;
 | 
			
		||||
  int socketDescM;
 | 
			
		||||
  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:
 | 
			
		||||
  cSatipSocket();
 | 
			
		||||
  virtual ~cSatipSocket();
 | 
			
		||||
  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);
 | 
			
		||||
  int Fd(void) { return socketDescM; }
 | 
			
		||||
  int Port(void) { return socketPortM; }
 | 
			
		||||
  bool IsMulticast(void) { return isMulticastM; }
 | 
			
		||||
  bool IsOpen(void) { return (socketDescM >= 0); }
 | 
			
		||||
  bool Flush(void);
 | 
			
		||||
  int Read(unsigned char *bufferAddrP, unsigned int bufferLenP);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								tuner.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								tuner.c
									
									
									
									
									
								
							@@ -55,12 +55,13 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
 | 
			
		||||
  int i = SatipConfig.GetPortRangeStart() ? SatipConfig.GetPortRangeStop() - SatipConfig.GetPortRangeStart() - 1 : 100;
 | 
			
		||||
  int port = SatipConfig.GetPortRangeStart();
 | 
			
		||||
  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;
 | 
			
		||||
        rtpM.Close();
 | 
			
		||||
        rtcpM.Close();
 | 
			
		||||
        if (SatipConfig.GetPortRangeStart())
 | 
			
		||||
           ++port;
 | 
			
		||||
           port += 2;
 | 
			
		||||
        }
 | 
			
		||||
  if ((rtpM.Port() <= 0) || (rtcpM.Port() <= 0)) {
 | 
			
		||||
     error("Cannot open required RTP/RTCP ports [device %d]", deviceIdM);
 | 
			
		||||
@@ -223,7 +224,7 @@ bool cSatipTuner::Connect(void)
 | 
			
		||||
        }
 | 
			
		||||
     else if (rtspM.Options(*connectionUri)) {
 | 
			
		||||
        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
 | 
			
		||||
        //rtpM.Flush();
 | 
			
		||||
        //rtcpM.Flush();
 | 
			
		||||
@@ -366,6 +367,33 @@ void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
 | 
			
		||||
  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 (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 (multicast)
 | 
			
		||||
        rtcpM.OpenMulticast(rtpPortP, streamAddrP, sourceAddrP);
 | 
			
		||||
     else
 | 
			
		||||
        rtcpM.Open(rtpPortP);
 | 
			
		||||
     cSatipPoller::GetInstance()->Register(rtcpM);
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cString cSatipTuner::GetBaseUrl(const char *addressP, const int portP)
 | 
			
		||||
{
 | 
			
		||||
  debug16("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, addressP, portP, deviceIdM);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								tuner.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tuner.h
									
									
									
									
									
								
							@@ -159,6 +159,7 @@ public:
 | 
			
		||||
  virtual void ProcessApplicationData(u_char *bufferP, int lengthP);
 | 
			
		||||
  virtual void SetStreamId(int streamIdP);
 | 
			
		||||
  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);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ public:
 | 
			
		||||
  virtual void ProcessApplicationData(u_char *bufferP, int lengthP) = 0;
 | 
			
		||||
  virtual void SetStreamId(int streamIdP) = 0;
 | 
			
		||||
  virtual void SetSessionTimeout(const char *sessionP, int timeoutP) = 0;
 | 
			
		||||
  virtual void SetupTransport(int rtpPortP, int rtcpPortP, const char *streamAddrP, const char *sourceAddrP) = 0;
 | 
			
		||||
  virtual int GetId(void) = 0;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user