summaryrefslogtreecommitdiff
path: root/orkaudio/audiocaptureplugins/voip/RtpSession.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'orkaudio/audiocaptureplugins/voip/RtpSession.cpp')
-rw-r--r--orkaudio/audiocaptureplugins/voip/RtpSession.cpp243
1 files changed, 216 insertions, 27 deletions
diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp
index 0d64a7a..4a9c39e 100644
--- a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp
+++ b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp
@@ -70,6 +70,7 @@ RtpSession::RtpSession(CStdString& trackingId)
m_rtpIp.s_addr = 0;
m_skinnyLineInstance = 0;
m_onDemand = false;
+ m_newRtpStream = true;
}
void RtpSession::Stop()
@@ -88,6 +89,11 @@ void RtpSession::Stop()
}
}
+bool RtpSession::Stopped()
+{
+ return m_stopped;
+}
+
void RtpSession::ReportRtcpSrcDescription(RtcpSrcDescriptionPacketInfoRef& rtcpInfo)
{
if(!m_rtcpLocalParty)
@@ -107,6 +113,9 @@ void RtpSession::ReportRtcpSrcDescription(RtcpSrcDescriptionPacketInfoRef& rtcpI
}
m_localParty.Format("%s@%s", rtcpInfo->m_cnameUsername, realm);
+ CStdString lp;
+ lp = m_localParty;
+ m_localParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(lp);
}
else
{
@@ -155,11 +164,12 @@ void RtpSession::ReportRtcpSrcDescription(RtcpSrcDescriptionPacketInfoRef& rtcpI
if(DLLCONFIG.m_inInMode == true)
{
- m_remoteParty = testParty;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(testParty);
}
else
{
- m_remoteParty = rtcpInfo->m_cnameUsername;
+ CStdString rp = rtcpInfo->m_cnameUsername;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(rp);
}
LOG4CXX_INFO(m_log, "[" + m_trackingId + "] Set remote party to RTCP CNAME:" + m_remoteParty);
@@ -264,7 +274,8 @@ void RtpSession::ProcessMetadataRawRtp(RtpPacketInfoRef& rtpPacket)
}
if(!m_rtcpRemoteParty)
{
- m_remoteParty = szDestIp;
+ CStdString rp(szDestIp);
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(rp);
}
m_localIp = rtpPacket->m_sourceIp;
@@ -290,7 +301,8 @@ void RtpSession::ProcessMetadataRawRtp(RtpPacketInfoRef& rtpPacket)
}
if(!m_rtcpRemoteParty)
{
- m_remoteParty = szSourceIp;
+ CStdString rp(szSourceIp);
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(rp);
}
m_localIp = rtpPacket->m_destIp;
@@ -334,13 +346,13 @@ void RtpSession::ProcessMetadataSipIncoming()
if((DLLCONFIG.m_sipRequestUriAsLocalParty == true) && (m_invite->m_requestUri.CompareNoCase(m_invite->m_to) != 0))
{
m_localParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_requestUri);
- m_remoteParty = m_invite->m_from;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_from);
m_direction = CaptureEvent::DirIn;
m_localEntryPoint = m_invite->m_to;
}
else
{
- m_remoteParty = m_invite->m_from;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_from);
m_localParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_to);
m_direction = CaptureEvent::DirIn;
}
@@ -369,13 +381,13 @@ void RtpSession::ProcessMetadataSipOutgoing()
if((DLLCONFIG.m_sipRequestUriAsLocalParty == true) && (m_invite->m_requestUri.CompareNoCase(m_invite->m_to) != 0))
{
m_localParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_requestUri);
- m_remoteParty = m_invite->m_from;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_from);
m_direction = CaptureEvent::DirIn;
m_localEntryPoint = m_invite->m_to;
}
else
{
- m_remoteParty = m_invite->m_to;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_to);
m_localParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_from);
m_direction = CaptureEvent::DirOut;
}
@@ -463,13 +475,13 @@ void RtpSession::UpdateMetadataSip(RtpPacketInfoRef& rtpPacket, bool sourceRtpAd
if((DLLCONFIG.m_sipRequestUriAsLocalParty == true) && (m_invite->m_requestUri.CompareNoCase(m_invite->m_to) != 0))
{
m_localParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_requestUri);
- m_remoteParty = m_invite->m_from;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(m_invite->m_from);
m_direction = CaptureEvent::DirIn;
m_localEntryPoint = m_invite->m_to;
}
else
{
- m_remoteParty = invite->m_from;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(invite->m_from);
m_localParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(invite->m_to);
}
@@ -1006,9 +1018,12 @@ bool RtpSession::AddRtpPacket(RtpPacketInfoRef& rtpPacket)
else
{
// 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( m_newRtpStream == true ||
+ ( (unsigned int)rtpPacket->m_destIp.s_addr == (unsigned int)m_lastRtpPacketSide1->m_destIp.s_addr &&
+ rtpPacket->m_destPort == m_lastRtpPacketSide1->m_destPort ) )
{
+ m_newRtpStream = false;
+
if(rtpPacket->m_timestamp == m_lastRtpPacketSide1->m_timestamp)
{
m_hasDuplicateRtp = true;
@@ -1091,9 +1106,10 @@ bool RtpSession::AddRtpPacket(RtpPacketInfoRef& rtpPacket)
bool hasDestAddress = m_rtpAddressList.HasAddressOrAdd(rtpPacket->m_destIp, rtpPacket->m_destPort);
if( hasSourceAddress == false || hasDestAddress == false )
{
+ m_newRtpStream = true;
rtpPacket->ToString(logMsg);
- logMsg.Format("[%s] new RTP stream s%d: %s",
- m_trackingId, channel, logMsg);
+ logMsg.Format("[%s] new RTP stream: %s",
+ m_trackingId, logMsg);
LOG4CXX_INFO(m_log, logMsg);
if(m_protocol == ProtSip && m_started) // make sure this only happens if ReportMetadata() already been called for the session
@@ -1184,13 +1200,13 @@ void RtpSession::ReportSipBye(SipByeInfoRef& bye)
if(m_localParty.CompareNoCase(translatedTo) != 0)
{
// localparty is set to m_from
- m_remoteParty = bye->m_to;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(bye->m_to);
logMsg.Format("[%s] dahdiIntercept: reset remoteparty:%s from BYE:%s", m_trackingId, m_remoteParty, byeString);
}
else
{
// localparty is set to m_to
- m_remoteParty = bye->m_from;
+ m_remoteParty = RtpSessionsSingleton::instance()->GetLocalPartyMap(bye->m_from);
logMsg.Format("[%s] dahdiIntercept: reset remoteparty:%s from BYE:%s", m_trackingId, m_remoteParty, byeString);
}
@@ -1561,6 +1577,34 @@ void RtpSessions::ReportSipSessionProgress(SipSessionProgressInfoRef& info)
}
}
+void RtpSessions::ReportSip302MovedTemporarily(Sip302MovedTemporarilyInfoRef& info)
+{
+ CStdString m_trackingId;
+
+ // Contact: is mapped to the To:
+ SaveLocalPartyMap(info->m_contact, info->m_to);
+
+ // If there is already a session, log that information
+ std::map<CStdString, RtpSessionRef>::iterator pair;
+
+ pair = m_byCallId.find(info->m_callId);
+ if (pair != m_byCallId.end())
+ {
+ RtpSessionRef session = pair->second;
+
+ m_trackingId = session->m_trackingId;
+ }
+
+ if(m_trackingId.size())
+ {
+ LOG4CXX_INFO(m_log, "[" + m_trackingId + "] " + info->m_contact + " mapped to " + info->m_to + " by SIP 302 Moved Temporarily");
+ }
+ else
+ {
+ LOG4CXX_INFO(m_log, info->m_contact + " mapped to " + info->m_to + " by SIP 302 Moved Temporarily (session unknown)");
+ }
+}
+
void RtpSessions::ReportSip200Ok(Sip200OkInfoRef info)
{
std::map<CStdString, RtpSessionRef>::iterator pair;
@@ -1630,19 +1674,20 @@ void RtpSessions::ReportSipBye(SipByeInfoRef& bye)
void RtpSessions::UpdateEndpointWithCallInfo(SkCallInfoStruct* callInfo, IpHeaderStruct* ipHeader)
{
CStdString extension;
+ CStdString callId = GenerateSkinnyCallId(ipHeader->ip_dest, callInfo->callId);
switch(callInfo->callType)
{
case SKINNY_CALL_TYPE_INBOUND:
{
extension = callInfo->calledParty;
- SetEndpointExtension(extension, &ipHeader->ip_dest);
+ SetEndpointExtension(extension, &ipHeader->ip_dest, callId);
break;
}
case SKINNY_CALL_TYPE_OUTBOUND:
{
extension = callInfo->callingParty;
- SetEndpointExtension(extension, &ipHeader->ip_dest);
+ SetEndpointExtension(extension, &ipHeader->ip_dest, callId);
break;
}
}
@@ -1652,6 +1697,7 @@ void RtpSessions::UpdateSessionWithCallInfo(SkCallInfoStruct* callInfo, RtpSessi
{
session->m_skinnyLineInstance = callInfo->lineInstance;
CStdString lp;
+ CStdString rp;
CStdString logMsg;
char szEndPointIp[16];
@@ -1662,12 +1708,14 @@ void RtpSessions::UpdateSessionWithCallInfo(SkCallInfoStruct* callInfo, RtpSessi
{
case SKINNY_CALL_TYPE_INBOUND:
lp = callInfo->calledParty;
+ rp = callInfo->callingParty;
session->m_localParty = GetLocalPartyMap(lp);
- session->m_remoteParty = callInfo->callingParty;
+ session->m_remoteParty = GetLocalPartyMap(rp);
session->m_direction = CaptureEvent::DirIn;
break;
case SKINNY_CALL_TYPE_FORWARD:
lp = callInfo->calledParty;
+ rp = callInfo->callingParty;
if(endpoint.get() && ((endpoint->m_extension).size() > 0))
{
session->m_localParty = GetLocalPartyMap(endpoint->m_extension);
@@ -1675,22 +1723,90 @@ void RtpSessions::UpdateSessionWithCallInfo(SkCallInfoStruct* callInfo, RtpSessi
logMsg.Format("[%s] callType is FORWARD: set localparty:%s (obtained from endpoint:%s)", session->m_trackingId, session->m_localParty, szEndPointIp);
LOG4CXX_DEBUG(m_log, logMsg);
}
- session->m_remoteParty = callInfo->callingParty;
+ session->m_remoteParty = GetLocalPartyMap(rp);
session->m_direction = CaptureEvent::DirIn;
break;
case SKINNY_CALL_TYPE_OUTBOUND:
lp = callInfo->callingParty;
+ rp = callInfo->calledParty;
session->m_localParty = GetLocalPartyMap(lp);
- session->m_remoteParty = callInfo->calledParty;
+ session->m_remoteParty = GetLocalPartyMap(rp);
session->m_direction = CaptureEvent::DirOut;
break;
default:
lp = callInfo->calledParty;
+ rp = callInfo->callingParty;
session->m_localParty = GetLocalPartyMap(lp);
- session->m_remoteParty = callInfo->callingParty;
+ session->m_remoteParty = GetLocalPartyMap(rp);
}
}
+bool RtpSessions::TrySkinnySession(RtpPacketInfoRef& rtpPacket, EndpointInfoRef& endpoint)
+{
+ std::map<unsigned int, EndpointInfoRef>::iterator pair;
+ std::map<CStdString, RtpSessionRef>::iterator sessionpair;
+ RtpSessionRef session;
+ bool srcmatch = false;
+ CStdString logMsg;
+
+ pair = m_endpoints.find((unsigned int)(rtpPacket->m_sourceIp.s_addr));
+ if(pair != m_endpoints.end())
+ {
+ endpoint = pair->second;
+ srcmatch = true;
+ }
+ else
+ {
+ pair = m_endpoints.find((unsigned int)(rtpPacket->m_destIp.s_addr));
+ if(pair == m_endpoints.end())
+ {
+ return false;
+ }
+
+ endpoint = pair->second;
+ }
+
+ if(!(endpoint->m_latestCallId).size())
+ {
+ return false;
+ }
+
+ sessionpair = m_byCallId.find(endpoint->m_latestCallId);
+ if(sessionpair == m_byCallId.end())
+ {
+ return false;
+ }
+
+ session = sessionpair->second;
+ if(session->Stopped())
+ {
+ return false;
+ }
+
+ char szEndPointIp[16];
+ char szRtpSrcIp[16];
+ char szRtpDstIp[16];
+
+ ACE_OS::inet_ntop(AF_INET, (void*)&rtpPacket->m_sourceIp, szRtpSrcIp, sizeof(szRtpSrcIp));
+ ACE_OS::inet_ntop(AF_INET, (void*)&rtpPacket->m_destIp, szRtpDstIp, sizeof(szRtpDstIp));
+
+ if(srcmatch == true)
+ {
+ SetMediaAddress(session, rtpPacket->m_sourceIp, rtpPacket->m_sourcePort);
+ ACE_OS::inet_ntop(AF_INET, (void*)&rtpPacket->m_sourceIp, szEndPointIp, sizeof(szEndPointIp));
+ }
+ else
+ {
+ SetMediaAddress(session, rtpPacket->m_destIp, rtpPacket->m_destPort);
+ ACE_OS::inet_ntop(AF_INET, (void*)&rtpPacket->m_destIp, szEndPointIp, sizeof(szEndPointIp));
+ }
+
+ logMsg.Format("[%s] RTP stream detected on endpoint:%s extension:%s RTP:%s,%d %s,%d callid:%s", session->m_trackingId, szEndPointIp, endpoint->m_extension, szRtpSrcIp, rtpPacket->m_sourcePort, szRtpDstIp, rtpPacket->m_destPort, endpoint->m_latestCallId);
+ LOG4CXX_INFO(m_log, logMsg);
+
+ return true;
+}
+
void RtpSessions::ReportSkinnyCallInfo(SkCallInfoStruct* callInfo, IpHeaderStruct* ipHeader)
{
CStdString callId = GenerateSkinnyCallId(ipHeader->ip_dest, callInfo->callId);
@@ -1775,6 +1891,7 @@ void RtpSessions::ReportSkinnyCallInfo(SkCallInfoStruct* callInfo, IpHeaderStruc
session->m_callId = callId;
session->m_endPointIp = ipHeader->ip_dest; // CallInfo message always goes from CM to endpoint
session->m_protocol = RtpSession::ProtSkinny;
+ session->m_skinnyLastCallInfoTime = ACE_OS::gettimeofday();
UpdateSessionWithCallInfo(callInfo, session);
session->ReportSkinnyCallInfo(callInfo, ipHeader);
@@ -2060,12 +2177,18 @@ void RtpSessions::SetMediaAddress(RtpSessionRef& session, struct in_addr mediaIp
if(oldSession.get())
{
// A session exists on the same IP+port
- if(oldSession->m_protocol == RtpSession::ProtRawRtp || oldSession->m_numRtpPackets == 0)
+ if(oldSession->m_protocol == RtpSession::ProtRawRtp || oldSession->m_numRtpPackets == 0 ||
+ (session->m_protocol == RtpSession::ProtSkinny && DLLCONFIG.m_skinnyAllowMediaAddressTransfer) )
{
logMsg.Format("[%s] on %s replaces [%s]",
session->m_trackingId, mediaAddress, oldSession->m_trackingId);
LOG4CXX_INFO(m_log, logMsg);
- Stop(oldSession);
+ //Stop(oldSession); // Let the session go into timeout rather than stop is straight away, useful for skinny internal calls where media address back and forth must not kill sessions with the best metadata.
+ }
+ else if(oldSession->m_trackingId.Equals(session->m_trackingId))
+ {
+ // Old and new are the same session, do nothing
+ doChangeMediaAddress = false;
}
else
{
@@ -2276,7 +2399,7 @@ void RtpSessions::ReportSkinnyStopMediaTransmission(SkStopMediaTransmissionStruc
}
}
-void RtpSessions::SetEndpointExtension(CStdString& extension, struct in_addr* endpointIp)
+void RtpSessions::SetEndpointExtension(CStdString& extension, struct in_addr* endpointIp, CStdString& callId)
{
std::map<unsigned int, EndpointInfoRef>::iterator pair;
EndpointInfoRef endpoint;
@@ -2287,12 +2410,21 @@ void RtpSessions::SetEndpointExtension(CStdString& extension, struct in_addr* en
// Update the existing endpoint info
endpoint = pair->second;
endpoint->m_extension = extension;
+ if(callId.size())
+ {
+ endpoint->m_latestCallId = callId;
+ }
}
else
{
// Create endpoint info for the new endpoint
endpoint.reset(new EndpointInfo());
endpoint->m_extension = extension;
+ memcpy(&endpoint->m_ip, endpointIp, sizeof(endpoint->m_ip));
+ if(callId.size())
+ {
+ endpoint->m_latestCallId = callId;
+ }
m_endpoints.insert(std::make_pair((unsigned int)(endpointIp->s_addr), endpoint));
}
if(endpoint.get())
@@ -2301,19 +2433,21 @@ void RtpSessions::SetEndpointExtension(CStdString& extension, struct in_addr* en
char szEndpointIp[16];
ACE_OS::inet_ntop(AF_INET, (void*)endpointIp, szEndpointIp, sizeof(szEndpointIp));
- logMsg.Format("Extension:%s is on endpoint:%s", endpoint->m_extension, szEndpointIp);
+ logMsg.Format("Extension:%s callId:%s is on endpoint:%s", endpoint->m_extension, endpoint->m_latestCallId, szEndpointIp);
LOG4CXX_INFO(m_log, logMsg);
}
}
void RtpSessions::ReportSkinnyLineStat(SkLineStatStruct* lineStat, IpHeaderStruct* ipHeader)
{
+ CStdString callId = "";
+
if(strlen(lineStat->lineDirNumber) > 1)
{
CStdString extension;
extension = lineStat->lineDirNumber;
- SetEndpointExtension(extension, &ipHeader->ip_dest);
+ SetEndpointExtension(extension, &ipHeader->ip_dest, callId);
}
}
@@ -2612,6 +2746,14 @@ void RtpSessions::ReportRtpPacket(RtpPacketInfoRef& rtpPacket)
}
else if((numSessionsFound == 0) && (CONFIG.m_lookBackRecording == true))
{
+ EndpointInfoRef endpoint;
+
+ // Check if this is a Skinny session
+ if(TrySkinnySession(rtpPacket, endpoint) == true)
+ {
+ return;
+ }
+
// create new Raw RTP session and insert into IP+Port map
CStdString trackingId = m_alphaCounter.GetNext();
RtpSessionRef session(new RtpSession(trackingId));
@@ -2649,6 +2791,35 @@ void RtpSessions::ReportRtpPacket(RtpPacketInfoRef& rtpPacket)
LOG4CXX_DEBUG(m_log, CStdString("ByIpAndPort: ") + numSessions);
LOG4CXX_INFO(m_log, "[" + trackingId + "] created by RTP packet");
+
+ if(endpoint.get())
+ {
+ // Skinny endpoint was got but no RTP session or existing
+ // RTP session is already stopped
+ char szEndpointIp[16];
+ char szRtpSrcIp[16];
+ char szRtpDstIp[16];
+ CStdString logMsg;
+
+ ACE_OS::inet_ntop(AF_INET, (void*)&endpoint->m_ip, szEndpointIp, sizeof(szEndpointIp));
+ ACE_OS::inet_ntop(AF_INET, (void*)&rtpPacket->m_sourceIp, szRtpSrcIp, sizeof(szRtpSrcIp));
+ ACE_OS::inet_ntop(AF_INET, (void*)&rtpPacket->m_destIp, szRtpDstIp, sizeof(szRtpDstIp));
+
+ session->m_localParty = endpoint->m_extension;
+ if(endpoint->m_ip.s_addr == rtpPacket->m_sourceIp.s_addr)
+ {
+ session->m_remoteParty = szRtpDstIp;
+ }
+ else
+ {
+ session->m_remoteParty = szRtpSrcIp;
+ }
+
+ logMsg.Format("[%s] RTP stream detected on endpoint:%s extension:%s RTP:%s,%d %s,%d", session->m_trackingId, szEndpointIp, endpoint->m_extension, szRtpSrcIp, rtpPacket->m_sourcePort, szRtpDstIp, rtpPacket->m_destPort);
+ LOG4CXX_INFO(m_log, logMsg);
+
+ return;
+ }
}
}
@@ -3100,6 +3271,24 @@ void SipInviteInfo::ToString(CStdString& string)
}
//==========================================================
+Sip302MovedTemporarilyInfo::Sip302MovedTemporarilyInfo()
+{
+ m_senderIp.s_addr = 0;
+ m_receiverIp.s_addr = 0;
+}
+
+void Sip302MovedTemporarilyInfo::ToString(CStdString& string)
+{
+ char senderIp[16];
+ char receiverIp[16];
+
+ ACE_OS::inet_ntop(AF_INET, (void*)&m_senderIp, senderIp, sizeof(senderIp));
+ ACE_OS::inet_ntop(AF_INET, (void*)&m_receiverIp, receiverIp, sizeof(receiverIp));
+
+ string.Format("sender:%s rcvr:%s from:%s@%s to:%s@%s contact:%s@%s fromname:%s toname:%s contactname:%s callid:%s", senderIp, receiverIp, m_from, m_fromDomain, m_to, m_toDomain, m_contact, m_contactDomain, m_fromName, m_toName, m_contactName, m_callId);
+}
+
+//==========================================================
SipFailureMessageInfo::SipFailureMessageInfo()
{
m_senderIp.s_addr = 0;