summaryrefslogtreecommitdiff
path: root/orkaudio/audiocaptureplugins/voip
diff options
context:
space:
mode:
authorGerald Begumisa <ben_g@users.sourceforge.net>2008-08-27 13:39:16 +0000
committerGerald Begumisa <ben_g@users.sourceforge.net>2008-08-27 13:39:16 +0000
commitb6519c2c1e4fa79049e5d5fba05a78d890c68aaf (patch)
tree3c515172a1a96c9555f1cda91f937b63181b1c73 /orkaudio/audiocaptureplugins/voip
parent758c81485d816de9fbf76889979e6bd853f118dd (diff)
A new configuration parameter, SipDetectSessionProgress, has been added. This parameter defaults to "true" and should be configured under the VoIpPlugin section of config.xml if it needs to be turned off. With this parameter set to "true", the SIP Session Progress message (SIP/2.0 183 Session Progress) is detected. The SDP in the message is used to force media address change on the session.
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@557 09dcff7a-b715-0410-9601-b79a96267cd0
Diffstat (limited to 'orkaudio/audiocaptureplugins/voip')
-rw-r--r--orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h2
-rw-r--r--orkaudio/audiocaptureplugins/voip/RtpSession.cpp35
-rw-r--r--orkaudio/audiocaptureplugins/voip/RtpSession.h19
-rw-r--r--orkaudio/audiocaptureplugins/voip/VoIp.cpp153
-rw-r--r--orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp2
-rw-r--r--orkaudio/audiocaptureplugins/voip/VoIpConfig.h1
6 files changed, 211 insertions, 1 deletions
diff --git a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h
index ce33534..cc1ed0a 100644
--- a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h
+++ b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h
@@ -347,9 +347,11 @@ struct Iax2MetaTrunkEntryTs {
#define SIP_METHOD_INVITE_SIZE 6
#define SIP_METHOD_BYE_SIZE 3
#define SIP_RESPONSE_200_OK_SIZE 11
+#define SIP_RESPONSE_SESSION_PROGRESS_SIZE 28
#define SIP_METHOD_INVITE "INVITE"
#define SIP_METHOD_BYE "BYE"
#define SIP_RESPONSE_200_OK "SIP/2.0 200"
+#define SIP_RESPONSE_SESSION_PROGRESS "SIP/2.0 183 Session Progress"
#endif
diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp
index d6f147f..0a0bc91 100644
--- a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp
+++ b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp
@@ -1173,6 +1173,20 @@ void RtpSessions::ReportSipErrorPacket(SipFailureMessageInfoRef& info)
return;
}
+void RtpSessions::ReportSipSessionProgress(SipSessionProgressInfoRef& info)
+{
+ std::map<CStdString, RtpSessionRef>::iterator pair;
+
+ pair = m_byCallId.find(info->m_callId);
+ if (pair != m_byCallId.end())
+ {
+ RtpSessionRef session = pair->second;
+ unsigned short mediaPort = ACE_OS::atoi(info->m_mediaPort);
+
+ SetMediaAddress(session, info->m_mediaIp, mediaPort);
+ }
+}
+
void RtpSessions::ReportSip200Ok(Sip200OkInfoRef info)
{
std::map<CStdString, RtpSessionRef>::iterator pair;
@@ -2328,3 +2342,24 @@ void Sip200OkInfo::ToString(CStdString& string)
string.Format("sender:%s from:%s to:%s rcvr:%s callid:%s", senderIp, m_from, m_to, receiverIp, m_callId);
}
}
+
+SipSessionProgressInfo::SipSessionProgressInfo()
+{
+ m_mediaIp.s_addr = 0;
+ m_senderIp.s_addr = 0;
+ m_receiverIp.s_addr = 0;
+}
+
+void SipSessionProgressInfo::ToString(CStdString& string)
+{
+ char mediaIp[16];
+ ACE_OS::inet_ntop(AF_INET, (void*)&m_mediaIp, mediaIp, sizeof(mediaIp));
+
+ char senderIp[16];
+ ACE_OS::inet_ntop(AF_INET, (void*)&m_senderIp, senderIp, sizeof(senderIp));
+
+ char receiverIp[16];
+ ACE_OS::inet_ntop(AF_INET, (void*)&m_receiverIp, receiverIp, sizeof(receiverIp));
+
+ string.Format("sender:%s from:%s RTP:%s,%s to:%s rcvr:%s callid:%s", senderIp, m_from, mediaIp, m_mediaPort, m_to, receiverIp, m_callId);
+}
diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.h b/orkaudio/audiocaptureplugins/voip/RtpSession.h
index abf7787..089086f 100644
--- a/orkaudio/audiocaptureplugins/voip/RtpSession.h
+++ b/orkaudio/audiocaptureplugins/voip/RtpSession.h
@@ -92,10 +92,26 @@ public:
CStdString m_from;
CStdString m_to;
};
-
typedef boost::shared_ptr<Sip200OkInfo> Sip200OkInfoRef;
+class SipSessionProgressInfo
+{
+public:
+ SipSessionProgressInfo();
+ void ToString(CStdString& string);
+
+ CStdString m_callId;
+ struct in_addr m_mediaIp;
+ CStdString m_mediaPort;
+
+ struct in_addr m_senderIp;
+ struct in_addr m_receiverIp;
+ CStdString m_from;
+ CStdString m_to;
+};
+typedef boost::shared_ptr<SipSessionProgressInfo> SipSessionProgressInfoRef;
+
//=============================================================
class EndpointInfo
@@ -226,6 +242,7 @@ public:
void ReportRtpPacket(RtpPacketInfoRef& rtpPacket);
void ReportSipErrorPacket(SipFailureMessageInfoRef& sipError);
void ReportSip200Ok(Sip200OkInfoRef info);
+ void ReportSipSessionProgress(SipSessionProgressInfoRef& info);
void Hoover(time_t now);
EndpointInfoRef GetEndpointInfo(struct in_addr endpointIp);
void StartCapture(CStdString& party);
diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp
index 1f8620b..948d364 100644
--- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp
+++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp
@@ -1454,6 +1454,152 @@ bool TrySipTcp(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, T
return result;
}
+bool TrySipSessionProgress(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpHeaderStruct* udpHeader, u_char* udpPayload, u_char* packetEnd)
+{
+ bool result = false;
+
+ int sipLength = ntohs(udpHeader->len) - sizeof(UdpHeaderStruct);
+ char* sipEnd = (char*)udpPayload + sipLength;
+
+ if(sipLength < SIP_RESPONSE_SESSION_PROGRESS_SIZE || sipEnd > (char*)packetEnd)
+ {
+ ; // packet too short
+ }
+ else if(memcmp(SIP_RESPONSE_SESSION_PROGRESS, (void*)udpPayload, SIP_RESPONSE_SESSION_PROGRESS_SIZE) == 0)
+ {
+ bool hasSdp = false;
+ SipSessionProgressInfoRef info(new SipSessionProgressInfo());
+
+ result = true;
+
+ char* fromField = memFindAfter("From:", (char*)udpPayload, sipEnd);
+ if(!fromField)
+ {
+ fromField = memFindAfter("\nf:", (char*)udpPayload, sipEnd);
+ }
+ char* toField = memFindAfter("To:", (char*)udpPayload, sipEnd);
+ if(!toField)
+ {
+ toField = memFindAfter("\nt:", (char*)udpPayload, sipEnd);
+ }
+
+ char* callIdField = memFindAfter("Call-ID:", (char*)udpPayload, sipEnd);
+ if(!callIdField)
+ {
+ callIdField = memFindAfter("\ni:", (char*)udpPayload, sipEnd);
+ }
+
+ char* audioField = NULL;
+ char* connectionAddressField = NULL;
+
+ if(callIdField)
+ {
+ GrabTokenSkipLeadingWhitespaces(callIdField, sipEnd, info->m_callId);
+ audioField = memFindAfter("m=audio ", callIdField, sipEnd);
+ connectionAddressField = memFindAfter("c=IN IP4 ", callIdField, sipEnd);
+ }
+ if(audioField && connectionAddressField)
+ {
+ hasSdp = true;
+
+ GrabToken(audioField, sipEnd, info->m_mediaPort);
+
+ CStdString connectionAddress;
+ GrabToken(connectionAddressField, sipEnd, connectionAddress);
+ struct in_addr mediaIp;
+ if(connectionAddress.size())
+ {
+ if(ACE_OS::inet_aton((PCSTR)connectionAddress, &mediaIp))
+ {
+ info->m_mediaIp = mediaIp;
+ }
+ }
+ }
+
+ if(fromField)
+ {
+ if(s_sipExtractionLog->isDebugEnabled())
+ {
+ CStdString from;
+ GrabLine(fromField, sipEnd, from);
+ LOG4CXX_DEBUG(s_sipExtractionLog, "from: " + from);
+ }
+
+ char* fromFieldEnd = memFindEOL(fromField, sipEnd);
+
+ char* sipUser = memFindAfter("sip:", fromField, fromFieldEnd);
+ if(sipUser)
+ {
+ if(DLLCONFIG.m_sipReportFullAddress)
+ {
+ GrabSipUserAddress(sipUser, fromFieldEnd, info->m_from);
+ }
+ else
+ {
+ GrabSipUriUser(sipUser, fromFieldEnd, info->m_from);
+ }
+ }
+ else
+ {
+ if(DLLCONFIG.m_sipReportFullAddress)
+ {
+ GrabSipUserAddress(fromField, fromFieldEnd, info->m_from);
+ }
+ else
+ {
+ GrabSipUriUser(fromField, fromFieldEnd, info->m_from);
+ }
+ }
+ }
+ if(toField)
+ {
+ CStdString to;
+ char* toFieldEnd = GrabLine(toField, sipEnd, to);
+ LOG4CXX_DEBUG(s_sipExtractionLog, "to: " + to);
+
+ char* sipUser = memFindAfter("sip:", toField, toFieldEnd);
+ if(sipUser)
+ {
+ if(DLLCONFIG.m_sipReportFullAddress)
+ {
+ GrabSipUserAddress(sipUser, toFieldEnd, info->m_to);
+ }
+ else
+ {
+ GrabSipUriUser(sipUser, toFieldEnd, info->m_to);
+ }
+ }
+ else
+ {
+ if(DLLCONFIG.m_sipReportFullAddress)
+ {
+ GrabSipUserAddress(toField, toFieldEnd, info->m_to);
+ }
+ else
+ {
+ GrabSipUriUser(toField, toFieldEnd, info->m_to);
+ }
+ }
+ }
+ info->m_senderIp = ipHeader->ip_src;
+ info->m_receiverIp = ipHeader->ip_dest;
+
+ CStdString logMsg;
+
+ info->ToString(logMsg);
+ logMsg = "183 Session Progress: " + logMsg;
+ if(!hasSdp)
+ {
+ logMsg = logMsg + " dropped because it lacks the SDP";
+ }
+ else
+ {
+ RtpSessionsSingleton::instance()->ReportSipSessionProgress(info);
+ }
+ LOG4CXX_INFO(s_sipPacketLog, logMsg);
+ }
+}
+
bool TrySip200Ok(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpHeaderStruct* udpHeader, u_char* udpPayload, u_char* packetEnd)
{
bool result = false;
@@ -2209,6 +2355,13 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char
}
if(!detectedUsefulPacket) {
+ if(DLLCONFIG.m_sipDetectSessionProgress == true)
+ {
+ TrySipSessionProgress(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd);
+ }
+ }
+
+ if(!detectedUsefulPacket) {
detectedUsefulPacket = TrySipBye(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd);
}
diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp
index f0701df..7100fb3 100644
--- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp
+++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp
@@ -43,6 +43,7 @@ VoIpConfig::VoIpConfig()
m_sipOverTcpSupport = false; // Disabled by default
m_sipLogFailedCalls = false;
m_sipUse200OkMediaAddress = false;
+ m_sipDetectSessionProgress = true; // Enabled by default
m_sipReportFullAddress = false;
m_sipDynamicMediaAddress = false;
@@ -104,6 +105,7 @@ void VoIpConfig::Define(Serializer* s)
s->BoolValue("SipOverTcpSupport", m_sipOverTcpSupport);
s->BoolValue("SipLogFailedCalls", m_sipLogFailedCalls);
s->BoolValue("SipUse200OkMediaAddress", m_sipUse200OkMediaAddress);
+ s->BoolValue("SipDetectSessionProgress", m_sipDetectSessionProgress);
s->BoolValue("SipReportFullAddress", m_sipReportFullAddress);
s->BoolValue("SipDynamicMediaAddress", m_sipDynamicMediaAddress);
s->IpRangesValue("SipIgnoredMediaAddresses", m_sipIgnoredMediaAddresses);
diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h
index d8a4a6d..de13605 100644
--- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h
+++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h
@@ -77,6 +77,7 @@ public:
bool m_sipOverTcpSupport;
bool m_sipLogFailedCalls;
bool m_sipUse200OkMediaAddress;
+ bool m_sipDetectSessionProgress;
bool m_sipReportFullAddress;
bool m_sipDynamicMediaAddress;
IpRanges m_sipIgnoredMediaAddresses;