From b6519c2c1e4fa79049e5d5fba05a78d890c68aaf Mon Sep 17 00:00:00 2001 From: Gerald Begumisa Date: Wed, 27 Aug 2008 13:39:16 +0000 Subject: 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 --- orkaudio/audiocaptureplugins/voip/VoIp.cpp | 153 +++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) (limited to 'orkaudio/audiocaptureplugins/voip/VoIp.cpp') 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; @@ -2208,6 +2354,13 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char detectedUsefulPacket= TrySip200Ok(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd); } + if(!detectedUsefulPacket) { + if(DLLCONFIG.m_sipDetectSessionProgress == true) + { + TrySipSessionProgress(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd); + } + } + if(!detectedUsefulPacket) { detectedUsefulPacket = TrySipBye(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd); } -- cgit v1.2.3