summaryrefslogtreecommitdiff
path: root/orkaudio/audiocaptureplugins/voip/VoIp.cpp
diff options
context:
space:
mode:
authorGerald Begumisa <ben_g@users.sourceforge.net>2007-08-24 21:37:49 +0000
committerGerald Begumisa <ben_g@users.sourceforge.net>2007-08-24 21:37:49 +0000
commit576816f821b60bc8580b310248bac409ed30915e (patch)
tree7fa422abd5e89d26fd8c0488d53a436ce4a09b75 /orkaudio/audiocaptureplugins/voip/VoIp.cpp
parent9d30c0398e4447bf0b8b539caf738498fa45fb9f (diff)
Added support for SIP 200 OK message with ability to adjust the session RTP IP address and port if NAT is detected
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@474 09dcff7a-b715-0410-9601-b79a96267cd0
Diffstat (limited to 'orkaudio/audiocaptureplugins/voip/VoIp.cpp')
-rw-r--r--orkaudio/audiocaptureplugins/voip/VoIp.cpp60
1 files changed, 56 insertions, 4 deletions
diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp
index 2db26d7..60bcf0d 100644
--- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp
+++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp
@@ -1360,6 +1360,55 @@ bool TrySipTcp(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, T
return result;
}
+bool TrySip200Ok(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_200_OK_SIZE || sipEnd > (char*)packetEnd)
+ {
+ ; // packet too short
+ }
+ else if (memcmp(SIP_RESPONSE_200_OK, (void*)udpPayload, SIP_RESPONSE_200_OK_SIZE) == 0)
+ {
+ result = true;
+
+ Sip200OkInfoRef info(new Sip200OkInfo());
+
+ char* callIdField = memFindAfter("\r\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)
+ {
+ info->m_hasSdp = true;
+
+ GrabToken(audioField, sipEnd, info->m_fromRtpPort);
+
+ CStdString connectionAddress;
+ GrabToken(connectionAddressField, sipEnd, connectionAddress);
+ struct in_addr fromIp;
+ if(connectionAddress.size())
+ {
+ if(ACE_OS::inet_aton((PCSTR)connectionAddress, &fromIp))
+ {
+ info->m_fromRtpIp = fromIp;
+ }
+ }
+ }
+
+ RtpSessionsSingleton::instance()->ReportSip200Ok(info);
+ }
+ return result;
+}
+
bool TrySipInvite(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpHeaderStruct* udpHeader, u_char* udpPayload, u_char* packetEnd)
{
bool result = false;
@@ -1367,12 +1416,11 @@ bool TrySipInvite(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader
int sipLength = ntohs(udpHeader->len) - sizeof(UdpHeaderStruct);
char* sipEnd = (char*)udpPayload + sipLength;
- if(sipLength < sizeof(SIP_METHOD_INVITE) || sipEnd > (char*)packetEnd)
+ if(sipLength < SIP_METHOD_INVITE_SIZE || sipEnd > (char*)packetEnd)
{
- return false;
+ ; // packet too short
}
-
- if (memcmp(SIP_METHOD_INVITE, (void*)udpPayload, SIP_METHOD_INVITE_SIZE) == 0)
+ else if (memcmp(SIP_METHOD_INVITE, (void*)udpPayload, SIP_METHOD_INVITE_SIZE) == 0)
{
result = true;
@@ -1828,6 +1876,10 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char
}
if(!detectedUsefulPacket) {
+ detectedUsefulPacket= TrySip200Ok(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd);
+ }
+
+ if(!detectedUsefulPacket) {
detectedUsefulPacket = TrySipBye(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd);
}