From 1b42814d7ab545334fa97982b1b3023731a0cd64 Mon Sep 17 00:00:00 2001 From: Henri Herscher Date: Mon, 25 Jun 2007 19:22:12 +0000 Subject: Added support for capturing audio from any Sangoma telephony board (Sangoma driver needs to be capable of generating RTP copy of voice traffic). git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@451 09dcff7a-b715-0410-9601-b79a96267cd0 --- orkaudio/audiocaptureplugins/voip/RtpSession.cpp | 43 ++++++++++++++++++++---- orkaudio/audiocaptureplugins/voip/VoIp.cpp | 2 +- orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp | 39 +++++++++++++++++++++ orkaudio/audiocaptureplugins/voip/VoIpConfig.h | 5 +++ 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp index 397874f..a51e00d 100644 --- a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp +++ b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp @@ -135,7 +135,14 @@ void RtpSession::ProcessMetadataRawRtp(RtpPacketInfoRef& rtpPacket) char szDestIp[16]; ACE_OS::inet_ntop(AF_INET, (void*)&rtpPacket->m_destIp, szDestIp, sizeof(szDestIp)); - m_capturePort = m_ipAndPort; + if(DLLCONFIG.m_sangomaEnable) + { + m_capturePort = IntToString(rtpPacket->m_sourcePort % 1000); + } + else + { + m_capturePort = m_ipAndPort; + } if(sourceIsLocal) { @@ -621,7 +628,7 @@ bool RtpSession::AddRtpPacket(RtpPacketInfoRef& rtpPacket) if(m_log->isDebugEnabled()) { CStdString debug; - debug.Format("[%s] %s: Add RTP packet ts:%u arrival:%u ch:%d", m_trackingId, m_capturePort, rtpPacket->m_timestamp, rtpPacket->m_arrivalTimestamp, channel); + debug.Format("[%s] %s: Add RTP packet srcPort:%u dstPort:%u seq:%u ts:%u arrival:%u ch:%d", m_trackingId, m_capturePort, rtpPacket->m_sourcePort, rtpPacket->m_destPort, rtpPacket->m_seqNum, rtpPacket->m_timestamp, rtpPacket->m_arrivalTimestamp, channel); LOG4CXX_DEBUG(m_log, debug); } @@ -1267,9 +1274,27 @@ void RtpSessions::ReportRtpPacket(RtpPacketInfoRef& rtpPacket) RtpSessionRef session; CStdString logMsg; - if(rtpPacket->m_sourcePort == 1075) + int sourcePort = rtpPacket->m_sourcePort; + int destPort = rtpPacket->m_destPort; + + if(DLLCONFIG.m_sangomaEnable && sourcePort == destPort) { - int i=0; + if(sourcePort > DLLCONFIG.m_sangomaTxTcpPortStart) + { + // This is a TX packet + sourcePort = sourcePort - DLLCONFIG.m_sangomaTcpPortDelta; + rtpPacket->m_sourcePort = sourcePort; + // flip the least significant bit of the most significant byte + rtpPacket->m_sourceIp.s_addr ^= 0x00000001; + } + else + { + // This is an RX packet + sourcePort = sourcePort + DLLCONFIG.m_sangomaTcpPortDelta; + rtpPacket->m_sourcePort = sourcePort; + // flip the least significant bit of the most significant byte + rtpPacket->m_destIp.s_addr ^= 0x00000001; + } } // Add RTP packet to session with matching source or dest IP+Port. @@ -1277,7 +1302,7 @@ void RtpSessions::ReportRtpPacket(RtpPacketInfoRef& rtpPacket) // phone call, so this RTP packet can potentially be reported to two sessions. // Does a session exist with this source Ip+Port - CStdString port = IntToString(rtpPacket->m_sourcePort); + CStdString port = IntToString(sourcePort); char szSourceIp[16]; ACE_OS::inet_ntop(AF_INET, (void*)&rtpPacket->m_sourceIp, szSourceIp, sizeof(szSourceIp)); CStdString sourceIpAndPort = CStdString(szSourceIp) + "," + port; @@ -1304,7 +1329,7 @@ void RtpSessions::ReportRtpPacket(RtpPacketInfoRef& rtpPacket) } // Does a session exist with this destination Ip+Port - port = IntToString(rtpPacket->m_destPort); + port = IntToString(destPort); char szDestIp[16]; ACE_OS::inet_ntop(AF_INET, (void*)&rtpPacket->m_destIp, szDestIp, sizeof(szDestIp)); CStdString destIpAndPort = CStdString(szDestIp) + "," + port; @@ -1329,7 +1354,7 @@ void RtpSessions::ReportRtpPacket(RtpPacketInfoRef& rtpPacket) } } - if(numSessionsFound == 2) + if(numSessionsFound == 2 && session1.get() != session2.get()) { // Need to "merge" the two sessions (ie discard one of them) // Can happen when RTP stream detected before skinny StartMediaTransmission @@ -1433,6 +1458,10 @@ void RtpSessions::ReportRtpPacket(RtpPacketInfoRef& rtpPacket) { ipAndPort = sourceIpAndPort; } + else if(DLLCONFIG.m_sangomaEnable) + { + ipAndPort = sourceIpAndPort; + } else { ipAndPort = destIpAndPort; diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp index 17c8d9e..c41d477 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp @@ -1022,7 +1022,7 @@ bool TryRtp(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpH rtpInfo->ToString(logMsg); LOG4CXX_DEBUG(s_rtpPacketLog, logMsg); } - if(payloadLength < 800) // sanity check, speech RTP payload should always be smaller + if(payloadLength < 900) // sanity check, speech RTP payload should always be smaller { RtpSessionsSingleton::instance()->ReportRtpPacket(rtpInfo); } diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp index a079cd6..80aff5d 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp @@ -45,6 +45,10 @@ VoIpConfig::VoIpConfig() m_skinnyIgnoreOpenReceiveChannelAck = false; m_skinnyDynamicMediaAddress = false; m_skinnyAllowCallInfoUpdate = false; + + m_sangomaEnable = false; + m_sangomaRxTcpPortStart = 0; + m_sangomaTxTcpPortStart = 0; } void VoIpConfig::Define(Serializer* s) @@ -82,6 +86,9 @@ void VoIpConfig::Define(Serializer* s) s->BoolValue("SkinnyIgnoreOpenReceiveChannelAck", m_skinnyIgnoreOpenReceiveChannelAck); s->BoolValue("SkinnyDynamicMediaAddress", m_skinnyDynamicMediaAddress); s->BoolValue("SkinnyAllowCallInfoUpdate", m_skinnyAllowCallInfoUpdate); + + s->IntValue("SangomaRxTcpPortStart", m_sangomaRxTcpPortStart); + s->IntValue("SangomaTxTcpPortStart", m_sangomaTxTcpPortStart); } void VoIpConfig::Validate() @@ -249,6 +256,38 @@ void VoIpConfig::Validate() exception.Format("VoIpConfig: RtpSessionOnHoldTimeOutSec must be > 0 (currently:%d) please fix config.xml", m_rtpSessionWithSignallingTimeoutSec); throw (exception); } + + if(m_sangomaRxTcpPortStart == 0) + { + } + else if(m_sangomaRxTcpPortStart > 65000 || m_sangomaRxTcpPortStart < 2000 || ((m_sangomaRxTcpPortStart%1000) != 0) ) + { + CStdString exception; + exception.Format("VoIpConfig: SangomaRxTcpPort must be between 2000 and 65000 and be a multiple of 1000 (currently:%d) please fix config.xml", m_sangomaRxTcpPortStart); + throw (exception); + } + if(m_sangomaTxTcpPortStart == 0) + { + } + else if(m_sangomaTxTcpPortStart > 65000 || m_sangomaTxTcpPortStart < 2000 || ((m_sangomaTxTcpPortStart%1000) != 0) ) + { + CStdString exception; + exception.Format("VoIpConfig: SangomaTxTcpPort must be between 2000 and 65000 and be a multiple of 1000 (currently:%d) please fix config.xml", m_sangomaTxTcpPortStart); + throw (exception); + } + + if(m_sangomaRxTcpPortStart > m_sangomaTxTcpPortStart) + { + CStdString exception; + exception.Format("VoIpConfig: SangomaTxTcpPort should always be bigger than SangomaRxTcpPort please fix config.xml"); + throw (exception); + } + else if(m_sangomaRxTcpPortStart > 0 && m_sangomaTxTcpPortStart>0) + { + m_sangomaTcpPortDelta = m_sangomaTxTcpPortStart - m_sangomaRxTcpPortStart; + m_sangomaEnable = true; + m_rtpDetectOnOddPorts = true; + } } bool VoIpConfig::IsPartOfLan(struct in_addr addr) diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h index a9a4749..ea6186f 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h @@ -81,6 +81,11 @@ public: std::list m_dnisNumbers; std::list m_sipExtractFields; + + bool m_sangomaEnable; // not a config parm, derived from the two following + int m_sangomaTcpPortDelta; + int m_sangomaRxTcpPortStart; + int m_sangomaTxTcpPortStart; }; //======================================== -- cgit v1.2.3