diff options
author | Gerald Begumisa <ben_g@users.sourceforge.net> | 2007-08-24 21:37:49 +0000 |
---|---|---|
committer | Gerald Begumisa <ben_g@users.sourceforge.net> | 2007-08-24 21:37:49 +0000 |
commit | 576816f821b60bc8580b310248bac409ed30915e (patch) | |
tree | 7fa422abd5e89d26fd8c0488d53a436ce4a09b75 /orkaudio/audiocaptureplugins/voip/VoIp.cpp | |
parent | 9d30c0398e4447bf0b8b539caf738498fa45fb9f (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.cpp | 60 |
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); } |