From 6d612d25b50447faffd8a78404dc08f1b9d28151 Mon Sep 17 00:00:00 2001 From: Gerald Begumisa Date: Tue, 18 Aug 2009 20:16:48 +0000 Subject: Added support for recording of Asterisk-DAHDI channels using Xorcom's Asterisk patch. git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@635 09dcff7a-b715-0410-9601-b79a96267cd0 --- orkaudio/audiocaptureplugins/voip/RtpSession.cpp | 155 ++++++++++++++++++++++- orkaudio/audiocaptureplugins/voip/RtpSession.h | 2 + orkaudio/audiocaptureplugins/voip/VoIp.cpp | 9 +- orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp | 13 ++ orkaudio/audiocaptureplugins/voip/VoIpConfig.h | 3 + 5 files changed, 174 insertions(+), 8 deletions(-) diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp index 35b5d9c..a8695eb 100644 --- a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp +++ b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp @@ -1004,8 +1004,9 @@ bool RtpSession::AddRtpPacket(RtpPacketInfoRef& rtpPacket) } else { - // Comparing destination IP address to find out if side1, see (1) - if((unsigned int)rtpPacket->m_destIp.s_addr == (unsigned int)m_lastRtpPacketSide1->m_destIp.s_addr) + // Comparing destination IP address and port to find out if side1, see (1) + if((unsigned int)rtpPacket->m_destIp.s_addr == (unsigned int)m_lastRtpPacketSide1->m_destIp.s_addr && + rtpPacket->m_destPort == m_lastRtpPacketSide1->m_destPort) { if(rtpPacket->m_timestamp == m_lastRtpPacketSide1->m_timestamp) { @@ -1151,10 +1152,76 @@ void RtpSession::ReportSipInvite(SipInviteInfoRef& invite) else { CStdString inviteString; - invite->ToString(inviteString); CStdString logMsg; - logMsg.Format("[%s] associating INVITE:%s", m_trackingId, inviteString); - LOG4CXX_INFO(m_log, logMsg); + invite->ToString(inviteString); + + if(DLLCONFIG.m_dahdiIntercept == true) + { + // With Xorcom interception, we update whichever party is currently + // set to "s" with the new party in either m_from or m_to of the + // INVITE + + if(m_localParty.CompareNoCase(CStdString("s")) == 0) + { + if(m_remoteParty.CompareNoCase(invite->m_to) != 0) + { + // remoteparty is set to m_from + m_localParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(invite->m_to); + logMsg.Format("[%s] dahdiIntercept: reset localparty:%s from INVITE:%s", m_trackingId, m_localParty, inviteString); + } + else + { + // remoteparty is set to m_to + m_localParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(invite->m_from); + logMsg.Format("[%s] dahdiIntercept: reset localparty:%s from INVITE:%s", m_trackingId, m_localParty, inviteString); + } + + // Report Local party + CaptureEventRef event(new CaptureEvent()); + event->m_type = CaptureEvent::EtLocalParty; + event->m_value = m_localParty; + g_captureEventCallBack(event, m_capturePort); + } + else if(m_remoteParty.CompareNoCase(CStdString("s")) == 0) + { + CStdString translatedTo, translatedFrom; + + translatedTo = RtpSessionsSingleton::instance()->GetLocalPartyMap(invite->m_to); + translatedFrom = RtpSessionsSingleton::instance()->GetLocalPartyMap(invite->m_from); + + if(m_localParty.CompareNoCase(translatedTo) != 0) + { + // localparty is set to m_from + m_remoteParty = invite->m_to; + logMsg.Format("[%s] dahdiIntercept: reset remoteparty:%s from INVITE:%s", m_trackingId, m_remoteParty, inviteString); + } + else + { + // localparty is set to m_to + m_remoteParty = invite->m_from; + logMsg.Format("[%s] dahdiIntercept: reset remoteparty:%s from INVITE:%s", m_trackingId, m_remoteParty, inviteString); + } + + // Report remote party + CaptureEventRef event(new CaptureEvent()); + event->m_type = CaptureEvent::EtRemoteParty; + event->m_value = m_remoteParty; + g_captureEventCallBack(event, m_capturePort); + } + else + { + logMsg.Format("[%s] dahdiIntercept: ignoring INVITE:%s", m_trackingId, inviteString); + } + + LOG4CXX_INFO(m_log, logMsg); + + return; + } + else + { + logMsg.Format("[%s] associating INVITE:%s", m_trackingId, inviteString); + LOG4CXX_INFO(m_log, logMsg); + } } m_invites.push_front(invite); if(invite->m_telephoneEventPtDefined) @@ -1385,10 +1452,18 @@ void RtpSessions::ReportSipInvite(SipInviteInfoRef& invite) } } - if(!session->m_ipAndPort.Equals(ipAndPort) && DLLCONFIG.m_sipDynamicMediaAddress) + if(DLLCONFIG.m_sipAllowMultipleMediaAddresses == true) { - SetMediaAddress(session, invite->m_fromRtpIp, rtpPort); + MapOtherMediaAddress(session, ipAndPort); } + else + { + if(!session->m_ipAndPort.Equals(ipAndPort) && DLLCONFIG.m_sipDynamicMediaAddress) + { + SetMediaAddress(session, invite->m_fromRtpIp, rtpPort); + } + } + return; } @@ -1830,6 +1905,59 @@ void RtpSessions::CraftMediaAddress(CStdString& mediaAddress, struct in_addr ipA mediaAddress.Format("%s,%u", szIpAddress, udpPort); } +void RtpSessions::MapOtherMediaAddress(RtpSessionRef& session, CStdString& ipAndPort) +{ + std::map::iterator pair = m_byIpAndPort.find(ipAndPort); + + if (pair != m_byIpAndPort.end()) + { + RtpSessionRef session2 = pair->second; + CStdString origOrkUid; + + origOrkUid = session->GetOrkUid(); + if(session2->OrkUidMatches(origOrkUid)) + { + CStdString logMsg; + char szEndPointIp[16]; + + if(m_log->isInfoEnabled()) + { + CStdString logMsg; + char szEndPointIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&session->m_endPointIp, szEndPointIp, sizeof(szEndPointIp)); + logMsg.Format("[%s] already mapped other media address:%s callId:%s endpoint:%s", session->m_trackingId, ipAndPort, session->m_callId, szEndPointIp); + LOG4CXX_INFO(m_log, logMsg); + } + + return; + } + + CStdString logMsg; + + logMsg.Format("Unable to map other media address:%s, we have another session:%s with that mapping", ipAndPort, session2->GetOrkUid()); + LOG4CXX_WARN(m_log, logMsg); + + return; + } + + if(m_log->isInfoEnabled()) + { + char szEndPointIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&session->m_endPointIp, szEndPointIp, sizeof(szEndPointIp)); + CStdString logMsg; + logMsg.Format("[%s] mapped other media address:%s callId:%s endpoint:%s", session->m_trackingId, ipAndPort, session->m_callId, szEndPointIp); + LOG4CXX_INFO(m_log, logMsg); + } + + session->m_otherIpAndPortMappings.push_back(ipAndPort); + m_byIpAndPort.insert(std::make_pair(ipAndPort, session)); + + CStdString numSessions = IntToString(m_byIpAndPort.size()); + LOG4CXX_DEBUG(m_log, CStdString("ByIpAndPort: ") + numSessions); +} + + void RtpSessions::SetMediaAddress(RtpSessionRef& session, struct in_addr mediaIp, unsigned short mediaPort) { if(mediaPort == 0) @@ -2195,6 +2323,19 @@ void RtpSessions::Stop(RtpSessionRef& session) { m_byCallId.erase(session->m_callId); } + if(session->m_otherIpAndPortMappings.size() > 0) + { + std::list::iterator it; + + for(it = session->m_otherIpAndPortMappings.begin(); it != session->m_otherIpAndPortMappings.end(); it++) + { + CStdString mapping = *it; + + m_byIpAndPort.erase(mapping); + } + + session->m_otherIpAndPortMappings.clear(); + } } bool RtpSessions::ReportRtcpSrcDescription(RtcpSrcDescriptionPacketInfoRef& rtcpInfo) diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.h b/orkaudio/audiocaptureplugins/voip/RtpSession.h index 804511c..0c77e85 100644 --- a/orkaudio/audiocaptureplugins/voip/RtpSession.h +++ b/orkaudio/audiocaptureplugins/voip/RtpSession.h @@ -186,6 +186,7 @@ public: bool m_onHold; bool m_keep; bool m_nonLookBackSessionStarted; + std::list m_otherIpAndPortMappings; private: void ProcessMetadataSip(RtpPacketInfoRef&); @@ -285,6 +286,7 @@ private: RtpSessionRef findByEndpointIpAndLineInstance(struct in_addr endpointIpAddr, int lineInstance); bool ChangeCallId(RtpSessionRef& session, unsigned int newId); void SetMediaAddress(RtpSessionRef& session, struct in_addr mediaIp, unsigned short mediaPort); + void MapOtherMediaAddress(RtpSessionRef& session, CStdString& ipAndPort); CStdString GenerateSkinnyCallId(struct in_addr endpointIp, unsigned int callId); void UpdateSessionWithCallInfo(SkCallInfoStruct*, RtpSessionRef&); diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp index cc0bf77..97671d0 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp @@ -2348,7 +2348,14 @@ bool TrySipInvite(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader if((unsigned int)info->m_fromRtpIp.s_addr == 0) { // In case connection address could not be extracted, use SIP invite sender IP address - info->m_fromRtpIp = ipHeader->ip_src; + if(DLLCONFIG.m_dahdiIntercept == true) + { + info->m_fromRtpIp = ipHeader->ip_dest; + } + else + { + info->m_fromRtpIp = ipHeader->ip_src; + } } info->m_senderIp = ipHeader->ip_src; info->m_receiverIp = ipHeader->ip_dest; diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp index 1071303..e9d5a8a 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp @@ -50,6 +50,7 @@ VoIpConfig::VoIpConfig() m_sipReportNamesAsTags = false; m_sipRequestUriAsLocalParty = true; m_sipTreat200OkAsInvite = false; + m_sipAllowMultipleMediaAddresses = false; m_rtcpDetect = false; m_inInMode = false; @@ -79,6 +80,8 @@ VoIpConfig::VoIpConfig() m_lanIpRanges.m_asciiIpRanges.push_back(CStdString("192.168.0.0/16")); m_lanIpRanges.m_asciiIpRanges.push_back(CStdString("172.16.0.0/20")); m_lanIpRanges.Compute(); + + m_dahdiIntercept = false; } void VoIpConfig::Define(Serializer* s) @@ -125,6 +128,7 @@ void VoIpConfig::Define(Serializer* s) s->BoolValue("SipReportNamesAsTags", m_sipReportNamesAsTags); s->BoolValue("SipRequestUriAsLocalParty", m_sipRequestUriAsLocalParty); s->BoolValue("SipTreat200OkAsInvite", m_sipTreat200OkAsInvite); + s->BoolValue("SipAllowMultipleMediaAddresses", m_sipAllowMultipleMediaAddresses); s->BoolValue("RtcpDetect", m_rtcpDetect); s->BoolValue("InInMode", m_inInMode); @@ -155,6 +159,8 @@ void VoIpConfig::Define(Serializer* s) s->IpRangesValue("LanIpRanges", m_lanIpRanges); s->IpRangesValue("MediaAddressBlockedIpRanges", m_mediaAddressBlockedIpRanges); + + s->BoolValue("DahdiIntercept", m_dahdiIntercept); } void VoIpConfig::Validate() @@ -377,6 +383,13 @@ void VoIpConfig::Validate() { m_sipDirectionReferenceUserAgents.push_back("Asterisk"); } + + if(m_dahdiIntercept == true) + { + m_sipAllowMultipleMediaAddresses = true; + m_rtpDetectOnOddPorts = true; + m_sipRequestUriAsLocalParty = false; + } } bool VoIpConfig::IsPartOfLan(struct in_addr addr) diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h index 7dace48..5d5cd32 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h @@ -87,6 +87,7 @@ public: bool m_sipReportNamesAsTags; bool m_sipRequestUriAsLocalParty; bool m_sipTreat200OkAsInvite; + bool m_sipAllowMultipleMediaAddresses; bool m_rtcpDetect; bool m_inInMode; @@ -120,6 +121,8 @@ public: std::list m_sipDirectionReferenceUserAgents; IpRanges m_lanIpRanges; IpRanges m_mediaAddressBlockedIpRanges; + + bool m_dahdiIntercept; }; //======================================== -- cgit v1.2.3