diff options
author | Gerald Begumisa <ben_g@users.sourceforge.net> | 2008-10-09 21:55:51 +0000 |
---|---|---|
committer | Gerald Begumisa <ben_g@users.sourceforge.net> | 2008-10-09 21:55:51 +0000 |
commit | c09609077b6f5eb70db855eed4e909d9d563ffcc (patch) | |
tree | 2031d9259e4d2ec2c4d8830c0d92a5d09e416d43 | |
parent | 5bb054adba4ee2e174886852ddde6a70a4ecb9a9 (diff) |
Added RTCP support. Key functionality is the ability to set the local party basing on the RTCP SDES information. A new configuration parameter, RtcpDetect, has been added. To enable RTCP, set RtcpDetect to true. This configuration should be done under the VoIpPlugin section of config.xml.
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@562 09dcff7a-b715-0410-9601-b79a96267cd0
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h | 13 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/Rtp.cpp | 11 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/Rtp.h | 17 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/RtpSession.cpp | 186 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/RtpSession.h | 6 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIp.cpp | 209 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp | 12 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIpConfig.h | 2 |
8 files changed, 436 insertions, 20 deletions
diff --git a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h index cc1ed0a..6c7fa3f 100644 --- a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h +++ b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h @@ -101,6 +101,19 @@ typedef struct unsigned short duration; } RtpEventPayloadFormat; +// Structure of common header for RTCP +typedef struct { + unsigned char vpc; // version (2 bits), padding (1 bit), count (5 bits) + unsigned char pt; // RTCP packet type + unsigned short length; // RTCP packet length in words without this word (i.e minus 1) +} RtcpCommonHeaderStruct; + +typedef struct { + unsigned char type; + unsigned char length; + unsigned char data[0]; +} RtcpSdesCsrcItem; + //=================================================================== // Cisco Callmanager -> endpoint messages typedef struct diff --git a/orkaudio/audiocaptureplugins/voip/Rtp.cpp b/orkaudio/audiocaptureplugins/voip/Rtp.cpp index 61b93f1..9c0eaa6 100644 --- a/orkaudio/audiocaptureplugins/voip/Rtp.cpp +++ b/orkaudio/audiocaptureplugins/voip/Rtp.cpp @@ -47,3 +47,14 @@ void RtpEventInfo::ToString(CStdString& string) { string.Format("event:%d e:%d r:%d volume:%d duration:%d timestamp:%u", m_event, m_e, m_r, m_volume, m_duration, m_startTimestamp); } + +void RtcpSrcDescriptionPacketInfo::ToString(CStdString& string) +{ + char sourceIp[16]; + char destIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&m_sourceIp, sourceIp, sizeof(sourceIp)); + ACE_OS::inet_ntop(AF_INET, (void*)&m_destIp, destIp, sizeof(destIp)); + + string.Format("%s,%d %s,%d username:%s domain:%s port:%s", sourceIp, m_sourcePort, destIp, m_destPort, m_cnameUsername, m_cnameDomain, m_cnamePort); +} diff --git a/orkaudio/audiocaptureplugins/voip/Rtp.h b/orkaudio/audiocaptureplugins/voip/Rtp.h index b1568b1..6110499 100644 --- a/orkaudio/audiocaptureplugins/voip/Rtp.h +++ b/orkaudio/audiocaptureplugins/voip/Rtp.h @@ -58,5 +58,22 @@ public: }; typedef boost::shared_ptr<RtpEventInfo> RtpEventInfoRef; +class RtcpSrcDescriptionPacketInfo +{ +public: + void ToString(CStdString& string); + + struct in_addr m_sourceIp; + struct in_addr m_destIp; + unsigned short m_sourcePort; + unsigned short m_destPort; + + CStdString m_cnameUsername; + CStdString m_cnameDomain; + CStdString m_cnamePort; + CStdString m_fullCname; +}; +typedef boost::shared_ptr<RtcpSrcDescriptionPacketInfo> RtcpSrcDescriptionPacketInfoRef; + #endif diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp index abc9108..127168d 100644 --- a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp +++ b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp @@ -62,6 +62,10 @@ RtpSession::RtpSession(CStdString& trackingId) m_currentDtmfDuration = 0; m_currentRtpEventTs = 0; m_currentDtmfVolume = 0; + m_rtcpLocalParty = false; + m_rtcpRemoteParty = false; + m_remotePartyReported = false; + m_localPartyReported = false; m_sessionTelephoneEventPtDefined = false; m_rtpIp.s_addr = 0; m_skinnyLineInstance = 0; @@ -83,6 +87,93 @@ void RtpSession::Stop() } } +void RtpSession::ReportRtcpSrcDescription(RtcpSrcDescriptionPacketInfoRef& rtcpInfo) +{ + if(!m_rtcpLocalParty) + { + m_rtcpLocalParty = true; + + if(DLLCONFIG.m_inInMode == true) + { + char realm[256], *d = NULL; + + memset(realm, 0, sizeof(realm)); + snprintf(realm, sizeof(realm), "%s", (PCSTR)rtcpInfo->m_cnameDomain); + + if((d = ACE_OS::strchr(realm, '.'))) + { + *d = '\0'; + } + + m_localParty.Format("%s@%s", rtcpInfo->m_cnameUsername, realm); + } + else + { + m_localParty = rtcpInfo->m_cnameUsername; + } + + LOG4CXX_INFO(m_log, "[" + m_trackingId + "] Set local party to RTCP CNAME:" + m_localParty); + + // In some cases, we obtain this information after the session + // has long started. Therefore, in order for the reporting + // to reflect the RTCP CNAME information, we need to report. + if(m_localPartyReported) + { + CaptureEventRef event(new CaptureEvent()); + event->m_type = CaptureEvent::EtLocalParty; + event->m_value = m_localParty; + g_captureEventCallBack(event, m_capturePort); + } + } + else if(!m_rtcpRemoteParty) + { + CStdString testParty; + + if(DLLCONFIG.m_inInMode == true) + { + char realm[256], *d = NULL; + + memset(realm, 0, sizeof(realm)); + snprintf(realm, sizeof(realm), "%s", (PCSTR)rtcpInfo->m_cnameDomain); + + if((d = ACE_OS::strchr(realm, '.'))) + { + *d = '\0'; + } + + testParty.Format("%s@%s", rtcpInfo->m_cnameUsername, realm); + } + else + { + testParty = rtcpInfo->m_cnameUsername; + } + + if(testParty.Equals(m_localParty) == false) + { + m_rtcpRemoteParty = true; + + if(DLLCONFIG.m_inInMode == true) + { + m_remoteParty = testParty; + } + else + { + m_remoteParty = rtcpInfo->m_cnameUsername; + } + + LOG4CXX_INFO(m_log, "[" + m_trackingId + "] Set remote party to RTCP CNAME:" + m_remoteParty); + + if(m_remotePartyReported) + { + CaptureEventRef event(new CaptureEvent()); + event->m_type = CaptureEvent::EtRemoteParty; + event->m_value = m_remoteParty; + g_captureEventCallBack(event, m_capturePort); + } + } + } +} + void RtpSession::Start() { m_started = true; @@ -156,18 +247,24 @@ void RtpSession::ProcessMetadataRawRtp(RtpPacketInfoRef& rtpPacket) if(sourceIsLocal) { - /* With Raw RTP, the local party is not obtained through any intelligent - * signalling so we should probably do this check here? */ - if(DLLCONFIG.m_useMacIfNoLocalParty) - { - MemMacToHumanReadable((unsigned char*)rtpPacket->m_sourceMac, m_localParty); - } - else - { - m_localParty = szSourceIp; - } - - m_remoteParty = szDestIp; + if(!m_rtcpLocalParty) + { + /* With Raw RTP, the local party is not obtained through any intelligent + * signalling so we should probably do this check here? */ + if(DLLCONFIG.m_useMacIfNoLocalParty) + { + MemMacToHumanReadable((unsigned char*)rtpPacket->m_sourceMac, m_localParty); + } + else + { + m_localParty = szSourceIp; + } + } + if(!m_rtcpRemoteParty) + { + m_remoteParty = szDestIp; + } + m_localIp = rtpPacket->m_sourceIp; m_remoteIp = rtpPacket->m_destIp; memcpy(m_localMac, rtpPacket->m_sourceMac, sizeof(m_localMac)); @@ -175,18 +272,24 @@ void RtpSession::ProcessMetadataRawRtp(RtpPacketInfoRef& rtpPacket) } else { - /* With Raw RTP, the local party is not obtained through any intelligent - * signalling so we should probably do this check here? */ - if(DLLCONFIG.m_useMacIfNoLocalParty) - { - MemMacToHumanReadable((unsigned char*)rtpPacket->m_destMac, m_localParty); + if(!m_rtcpLocalParty) + { + /* With Raw RTP, the local party is not obtained through any intelligent + * signalling so we should probably do this check here? */ + if(DLLCONFIG.m_useMacIfNoLocalParty) + { + MemMacToHumanReadable((unsigned char*)rtpPacket->m_destMac, m_localParty); + } + else + { + m_localParty = szDestIp; + } } - else + if(!m_rtcpRemoteParty) { - m_localParty = szDestIp; + m_remoteParty = szSourceIp; } - m_remoteParty = szSourceIp; m_localIp = rtpPacket->m_destIp; m_remoteIp = rtpPacket->m_sourceIp; memcpy(m_localMac, rtpPacket->m_destMac, sizeof(m_localMac)); @@ -521,12 +624,14 @@ void RtpSession::ReportMetadata() event->m_value = m_localParty; } g_captureEventCallBack(event, m_capturePort); + m_localPartyReported = true; // Report remote party event.reset(new CaptureEvent()); event->m_type = CaptureEvent::EtRemoteParty; event->m_value = m_remoteParty; g_captureEventCallBack(event, m_capturePort); + m_remotePartyReported = true; // Report direction event.reset(new CaptureEvent()); @@ -1904,6 +2009,47 @@ void RtpSessions::Stop(RtpSessionRef& session) } } +bool RtpSessions::ReportRtcpSrcDescription(RtcpSrcDescriptionPacketInfoRef& rtcpInfo) +{ + CStdString port = IntToString((rtcpInfo->m_sourcePort - 1)); + char szSourceIp[16]; + char szDestIp[16]; + std::map<CStdString, RtpSessionRef>::iterator pair; + RtpSessionRef session; + + ACE_OS::inet_ntop(AF_INET, (void*)&rtcpInfo->m_sourceIp, szSourceIp, sizeof(szSourceIp)); + CStdString sourceIpAndPort = CStdString(szSourceIp) + "," + port; + + pair = m_byIpAndPort.find(sourceIpAndPort); + if (pair != m_byIpAndPort.end()) + { + session = pair->second; + if(session.get() != NULL) + { + session->ReportRtcpSrcDescription(rtcpInfo); + return true; + } + } + + // Does a session exist with this destination Ip+Port + port = IntToString(rtcpInfo->m_destPort - 1); + ACE_OS::inet_ntop(AF_INET, (void*)&rtcpInfo->m_destIp, szDestIp, sizeof(szDestIp)); + CStdString destIpAndPort = CStdString(szDestIp) + "," + port; + + pair = m_byIpAndPort.find(destIpAndPort); + if (pair != m_byIpAndPort.end()) + { + session = pair->second; + if(session.get() != NULL) + { + session->ReportRtcpSrcDescription(rtcpInfo); + return true; + } + } + + return false; +} + void RtpSessions::ReportRtpPacket(RtpPacketInfoRef& rtpPacket) { diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.h b/orkaudio/audiocaptureplugins/voip/RtpSession.h index 089086f..f9286d1 100644 --- a/orkaudio/audiocaptureplugins/voip/RtpSession.h +++ b/orkaudio/audiocaptureplugins/voip/RtpSession.h @@ -141,6 +141,7 @@ public: bool AddRtpPacket(RtpPacketInfoRef& rtpPacket); void ReportSipInvite(SipInviteInfoRef& invite); void ReportSipErrorPacket(SipFailureMessageInfoRef& info); + void ReportRtcpSrcDescription(RtcpSrcDescriptionPacketInfoRef& rtcpInfo); bool OrkUidMatches(CStdString &oUid); bool PartyMatches(CStdString &party); void UpdateMetadataSkinny(); @@ -159,6 +160,10 @@ public: CStdString m_localParty; CStdString m_remoteParty; CStdString m_localPartyName; + bool m_localPartyReported; + bool m_remotePartyReported; + bool m_rtcpLocalParty; + bool m_rtcpRemoteParty; CaptureEvent::DirectionEnum m_direction; int m_numRtpPackets; struct in_addr m_endPointIp; // only used for Skinny @@ -240,6 +245,7 @@ public: void ReportSkinnySoftKeyHold(SkSoftKeyEventMessageStruct* skEvent, IpHeaderStruct* ipHeader); void ReportSkinnySoftKeyResume(SkSoftKeyEventMessageStruct* skEvent, IpHeaderStruct* ipHeader); void ReportRtpPacket(RtpPacketInfoRef& rtpPacket); + bool ReportRtcpSrcDescription(RtcpSrcDescriptionPacketInfoRef& rtcpInfo); void ReportSipErrorPacket(SipFailureMessageInfoRef& sipError); void ReportSip200Ok(Sip200OkInfoRef info); void ReportSipSessionProgress(SipSessionProgressInfoRef& info); diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp index f2d06d0..409e923 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp @@ -54,6 +54,7 @@ static LoggerPtr s_sipTcpPacketLog; static LoggerPtr s_skinnyPacketLog; static LoggerPtr s_sipExtractionLog; static LoggerPtr s_voipPluginLog; +static LoggerPtr s_rtcpPacketLog; static time_t s_lastHooveringTime; static time_t s_lastPause; static time_t s_lastPacketTimestamp; @@ -1081,6 +1082,206 @@ bool TryIax2MiniVoiceFrame(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* return Iax2SessionsSingleton::instance()->ReportIax2Packet(info); } +bool TryRtcp(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + RtcpCommonHeaderStruct* rtcpHeader = (RtcpCommonHeaderStruct*)udpPayload; + RtcpCommonHeaderStruct* r = NULL; + RtcpCommonHeaderStruct* rtcpEnd = NULL; + RtcpCommonHeaderStruct* rtcpThisPktEnd = NULL; + CStdString logMsg; + + if(!DLLCONFIG.m_rtcpDetect) + { + return false; + } + + if((ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)) < sizeof(RtcpCommonHeaderStruct)) + { + // Packet too small + return false; + } + + unsigned short version = (rtcpHeader->vpc & 0x00c0) >> 6; + unsigned short p = (rtcpHeader->vpc & 0x0020) >> 5; + unsigned short count = (rtcpHeader->vpc & 0x001f); + + if(version != 2) + { + // Failed first header validity check in RFC1889 A.2 + return false; + } + + if(rtcpHeader->pt != 200 && rtcpHeader->pt != 201) + { + // Failed second header validity check in RFC1889 A.2 + return false; + } + + if(p != 0) + { + // Failed third header validity check in RFC1889 A.2 + return false; + } + + rtcpEnd = (RtcpCommonHeaderStruct*)((char*)udpPayload + (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct))); + r = rtcpHeader; + unsigned short mv = 0; + + r = (RtcpCommonHeaderStruct*)((unsigned int *)r + ntohs(r->length) + 1); + while(r < rtcpEnd && ((rtcpEnd - r) >= sizeof(RtcpCommonHeaderStruct))) + { + mv = (r->vpc & 0x00c0) >> 6; + if(mv != 2) + { + break; + } + r = (RtcpCommonHeaderStruct*)((unsigned int *)r + ntohs(r->length) + 1); + } + + if(r != rtcpEnd) + { + // Failed final header validity check in RFC1889 A.2 + return false; + } + + char sourceIp[16], destIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&ipHeader->ip_src, sourceIp, sizeof(sourceIp)); + ACE_OS::inet_ntop(AF_INET, (void*)&ipHeader->ip_dest, destIp, sizeof(destIp)); + + // As per RFC we should be fairly sure we have an RTCP packet and + // henceforth our return value will be true + + // Now let's see whether we can obtain an SDES packet + char cname[256]; + RtcpSdesCsrcItem *csrcItem = NULL; + r = rtcpHeader; + + memset(cname, 0, sizeof(cname)); + + r = (RtcpCommonHeaderStruct*)((unsigned int *)r + ntohs(r->length) + 1); + while(r < rtcpEnd && ((rtcpEnd - r) >= sizeof(RtcpCommonHeaderStruct))) + { + version = (r->vpc & 0x00c0) >> 6; + p = (r->vpc & 0x0020) >> 5; + count = (r->vpc & 0x001f); + + rtcpThisPktEnd = (RtcpCommonHeaderStruct*)((unsigned int *)r + ntohs(r->length) + 1); + + if(r->pt == 202 && count) + { + // Check if we have CNAME in the first CSRC + csrcItem = (RtcpSdesCsrcItem *)((unsigned int *)r + 2); + + while((csrcItem < (RtcpSdesCsrcItem *)rtcpThisPktEnd) && (csrcItem->type != 1) && (csrcItem->type != 0)) + { + csrcItem = (RtcpSdesCsrcItem *)((char*)csrcItem + (int)csrcItem->length); + } + + if(csrcItem < (RtcpSdesCsrcItem *)rtcpThisPktEnd && csrcItem->type == 1) + { + break; + } + + csrcItem = NULL; + } + + r = (RtcpCommonHeaderStruct*)((unsigned int *)r + ntohs(r->length) + 1); + } + + if(csrcItem == NULL) + { + // No CNAME + return true; + } + + RtcpSrcDescriptionPacketInfoRef info(new RtcpSrcDescriptionPacketInfo()); + + info->m_sourceIp = ipHeader->ip_src; + info->m_destIp = ipHeader->ip_dest; + info->m_sourcePort = ntohs(udpHeader->source); + info->m_destPort = ntohs(udpHeader->dest); + + memcpy(cname, csrcItem->data, ((csrcItem->length > 254) ? 254 : csrcItem->length)); + + if(csrcItem->length == 0 || strncasecmp(cname, "ext", ((3 > csrcItem->length) ? csrcItem->length : 3))) + { + if(DLLCONFIG.m_inInMode == false) + { + // Not an extension + return true; + } + else + { + if(csrcItem->length == 0) + { + return true; + } + } + } + + info->m_fullCname = cname; + + /* + * Now parse the CNAME. As per RFC1889, 6.4.1, the CNAME is either + * in the format "user@host" or "host". However we will also support + * "user@host:port" or "host:port" + */ + char *x = NULL, *y = NULL, *z = NULL; + + x = cname; + y = ACE_OS::strchr(cname, '@'); + if(!y) + { + // CNAME is in the "host" or "host:port" format only, no user + y = ACE_OS::strchr(cname, ':'); + if(!y) + { + // We have no port + GrabToken(cname, cname+strlen(cname), info->m_cnameDomain); + } + else + { + *y++ = '\0'; + GrabToken(x, x+strlen(x), info->m_cnameDomain); + if(*y) + { + GrabToken(y, y+strlen(y), info->m_cnamePort); + } + } + } + else + { + *y++ = '\0'; + GrabToken(x, x+strlen(x), info->m_cnameUsername); + if(*y) + { + z = ACE_OS::strchr(y, ':'); + if(!z) + { + // We have no port + GrabToken(y, y+strlen(y), info->m_cnameDomain); + } + else + { + *z++ = '\0'; + GrabToken(y, y+strlen(y), info->m_cnameDomain); + if(*z) + { + GrabToken(z, z+strlen(z), info->m_cnamePort); + } + } + } + } + + info->ToString(logMsg); + LOG4CXX_DEBUG(s_rtcpPacketLog, logMsg); + + RtpSessionsSingleton::instance()->ReportRtcpSrcDescription(info); + + return true; +} + + bool TryRtp(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpHeaderStruct* udpHeader, u_char* udpPayload) { bool result = false; @@ -2370,6 +2571,13 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char detectedUsefulPacket = TryLogFailedSip(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd); } + if(!detectedUsefulPacket) { + if(DLLCONFIG.m_rtcpDetect == true) + { + detectedUsefulPacket = TryRtcp(ethernetHeader, ipHeader, udpHeader, udpPayload); + } + } + if(DLLCONFIG.m_iax2Support == false) { detectedUsefulPacket = true; // Stop trying to detect if this UDP packet could be of interest @@ -2763,6 +2971,7 @@ void VoIp::Initialize() s_packetLog = Logger::getLogger("packet"); s_packetStatsLog = Logger::getLogger("packet.pcapstats"); s_rtpPacketLog = Logger::getLogger("packet.rtp"); + s_rtcpPacketLog = Logger::getLogger("packet.rtcp"); s_sipPacketLog = Logger::getLogger("packet.sip"); s_sipTcpPacketLog = Logger::getLogger("packet.tcpsip"); s_skinnyPacketLog = Logger::getLogger("packet.skinny"); diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp index 63b274f..5143e7b 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp @@ -46,6 +46,8 @@ VoIpConfig::VoIpConfig() m_sipDetectSessionProgress = true; // Enabled by default m_sipReportFullAddress = false; m_sipDynamicMediaAddress = false; + m_rtcpDetect = false; + m_inInMode = false; m_useMacIfNoLocalParty = false; // Uses IP address by default m_localPartyForceLocalIp = false; @@ -109,6 +111,8 @@ void VoIpConfig::Define(Serializer* s) s->BoolValue("SipReportFullAddress", m_sipReportFullAddress); s->BoolValue("SipDynamicMediaAddress", m_sipDynamicMediaAddress); s->IpRangesValue("SipIgnoredMediaAddresses", m_sipIgnoredMediaAddresses); + s->BoolValue("RtcpDetect", m_rtcpDetect); + s->BoolValue("InInMode", m_inInMode); s->BoolValue("UseMacIfNoLocalParty", m_useMacIfNoLocalParty); s->BoolValue("LocalPartyForceLocalIp", m_localPartyForceLocalIp); @@ -340,6 +344,14 @@ void VoIpConfig::Validate() m_sangomaEnable = true; m_rtpDetectOnOddPorts = true; } + + if(m_inInMode == true) + { + CStdString inInVar = "ININCrn"; + + m_rtcpDetect = true; + m_sipExtractFields.push_back(inInVar); + } } bool VoIpConfig::IsPartOfLan(struct in_addr addr) diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h index de13605..7e43247 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h @@ -81,6 +81,8 @@ public: bool m_sipReportFullAddress; bool m_sipDynamicMediaAddress; IpRanges m_sipIgnoredMediaAddresses; + bool m_rtcpDetect; + bool m_inInMode; bool m_useMacIfNoLocalParty; bool m_localPartyForceLocalIp; |