From 4e8cb6eada05742ca5d7c578b512d89c3ace83c1 Mon Sep 17 00:00:00 2001 From: Henri Herscher Date: Tue, 1 Nov 2005 21:12:24 +0000 Subject: Completed skinny support git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@25 09dcff7a-b715-0410-9601-b79a96267cd0 --- .../audiocaptureplugins/voip/PacketHeaderDefs.h | 3 + orkaudio/audiocaptureplugins/voip/RtpSession.cpp | 149 ++++++++++++++++++++- orkaudio/audiocaptureplugins/voip/RtpSession.h | 17 ++- orkaudio/audiocaptureplugins/voip/VoIp.cpp | 15 ++- 4 files changed, 166 insertions(+), 18 deletions(-) diff --git a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h index ae488bb..f108974 100644 --- a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h +++ b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h @@ -135,6 +135,9 @@ typedef struct #define SKINNY_MSG_STOP_MEDIA_TRANSMISSION "StopMediaTransmission" #define SKINNY_MSG_CALL_INFO_MESSAGE "CallInfoMessage" +#define SKINNY_CALL_TYPE_INBOUND 1 +#define SKINNY_CALL_TYPE_OUTBOUND 2 + typedef enum { SkStartMediaTransmission = 0x008A, diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp index c8b49dd..c54c25b 100644 --- a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp +++ b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp @@ -44,11 +44,14 @@ RtpSession::RtpSession() void RtpSession::Stop() { - LOG4CXX_DEBUG(m_log, m_capturePort + " Session stop"); - CaptureEventRef stopEvent(new CaptureEvent); - stopEvent->m_type = CaptureEvent::EtStop; - stopEvent->m_timestamp = time(NULL); - g_captureEventCallBack(stopEvent, m_capturePort); + if(m_started) + { + LOG4CXX_DEBUG(m_log, m_capturePort + " Session stop"); + CaptureEventRef stopEvent(new CaptureEvent); + stopEvent->m_type = CaptureEvent::EtStop; + stopEvent->m_timestamp = time(NULL); + g_captureEventCallBack(stopEvent, m_capturePort); + } } void RtpSession::Start() @@ -182,6 +185,18 @@ void RtpSession::ProcessMetadataSip(RtpPacketInfoRef& rtpPacket) } } +void RtpSession::ProcessMetadataSkinny(RtpPacketInfoRef& rtpPacket) +{ + // In skinny, we know that ipAndPort are those from the CallManager. + // However, what we want as a capture port are IP+Port of the phone + m_capturePort.Format("%s,%u", ACE_OS::inet_ntoa(rtpPacket->m_sourceIp), rtpPacket->m_sourcePort); + if(m_capturePort.Equals(m_ipAndPort)) + { + m_capturePort.Format("%s,%u", ACE_OS::inet_ntoa(rtpPacket->m_destIp), rtpPacket->m_destPort); + } +} + + void RtpSession::ReportMetadata() { // report Local party @@ -219,6 +234,12 @@ void RtpSession::AddRtpPacket(RtpPacketInfoRef& rtpPacket) Start(); ReportMetadata(); } + else if(m_protocol == ProtSkinny) + { + ProcessMetadataSkinny(rtpPacket); + Start(); + ReportMetadata(); + } } m_lastRtpPacket = rtpPacket; m_numRtpPackets++; @@ -260,6 +281,10 @@ int RtpSession::ProtocolToEnum(CStdString& protocol) { protocolEnum = ProtSip; } + else if (protocol.CompareNoCase(PROT_SKINNY) == 0) + { + protocolEnum = ProtSkinny; + } return protocolEnum; } @@ -274,6 +299,9 @@ CStdString RtpSession::ProtocolToString(int protocolEnum) case ProtSip: protocolString = PROT_SIP; break; + case ProtSkinny: + protocolString = PROT_SKINNY; + break; default: protocolString = PROT_UNKN; } @@ -293,13 +321,20 @@ void RtpSessions::ReportSipInvite(SipInviteInfoRef& invite) std::map::iterator pair; pair = m_byIpAndPort.find(ipAndPort); - if (pair != m_byIpAndPort.end()) { // A session exists ont the same IP+port, stop old session RtpSessionRef session = pair->second; Stop(session); } + pair = m_byCallId.find(invite->m_callId); + if (pair != m_byCallId.end()) + { + // A session exists ont the same CallId, stop old session + RtpSessionRef session = pair->second; + Stop(session); + } + // create new session and insert into both maps RtpSessionRef session(new RtpSession()); session->m_ipAndPort = ipAndPort; @@ -323,6 +358,87 @@ void RtpSessions::ReportSipBye(SipByeInfo bye) } } +void RtpSessions::ReportSkinnyCallInfo(SkCallInfoStruct* callInfo) +{ + CStdString callId = IntToString(callInfo->callId); + std::map::iterator pair; + pair = m_byCallId.find(callId); + if (pair != m_byCallId.end()) + { + // A session exists ont the same CallId, stop old session + RtpSessionRef session = pair->second; + Stop(session); + } + + // create new session and insert into both maps + RtpSessionRef session(new RtpSession()); + session->m_callId = callId; + session->m_protocol = RtpSession::ProtSkinny; + switch(callInfo->callType) + { + case SKINNY_CALL_TYPE_INBOUND: + session->m_localParty = callInfo->calledParty; + session->m_remoteParty = callInfo->callingParty; + session->m_direction = CaptureEvent::DirIn; + break; + case SKINNY_CALL_TYPE_OUTBOUND: + session->m_localParty = callInfo->callingParty; + session->m_remoteParty = callInfo->calledParty; + session->m_direction = CaptureEvent::DirOut; + break; + } + m_byCallId.insert(std::make_pair(session->m_callId, session)); +} + +void RtpSessions::ReportSkinnyStartMediaTransmission(SkStartMediaTransmissionStruct* startMedia) +{ + // Lookup by callId + CStdString callId = IntToString(startMedia->conferenceId); + std::map::iterator pair; + pair = m_byCallId.find(callId); + + if (pair != m_byCallId.end()) + { + // Session found + RtpSessionRef session = pair->second; + + if(session->m_ipAndPort.size() == 0) + { + CStdString ipAndPort; + ipAndPort.Format("%s,%u", ACE_OS::inet_ntoa(startMedia->remoteIpAddr), startMedia->remoteTcpPort); + + pair = m_byIpAndPort.find(ipAndPort); + if (pair != m_byIpAndPort.end()) + { + // A session exists ont the same IP+port, stop old session + RtpSessionRef session = pair->second; + Stop(session); + } + session->m_ipAndPort = ipAndPort; + m_byIpAndPort.insert(std::make_pair(session->m_ipAndPort, session)); + } + else + { + // The session has already had a StartMediaTransmission message. + } + } +} + +void RtpSessions::ReportSkinnyStopMediaTransmission(SkStopMediaTransmissionStruct* stopMedia) +{ + CStdString callId = IntToString(stopMedia->conferenceId); + + std::map::iterator pair; + pair = m_byCallId.find(callId); + + if (pair != m_byCallId.end()) + { + // Session found: stop it + RtpSessionRef session = pair->second; + Stop(session); + } +} + void RtpSessions::Stop(RtpSessionRef& session) { session->Stop(); @@ -381,7 +497,7 @@ void RtpSessions::Hoover(time_t now) CStdString numSessions = IntToString(m_byIpAndPort.size()); LOG4CXX_DEBUG(m_log, "Hoover - check " + numSessions + " sessions time:" + IntToString(now)); - // Go round the sessions and find inactive ones + // Go round the ipAndPort session index and find inactive sessions std::map::iterator pair; std::list toDismiss; @@ -401,5 +517,24 @@ void RtpSessions::Hoover(time_t now) LOG4CXX_DEBUG(m_log, session->m_ipAndPort + " Expired"); Stop(session); } + + // Go round the callId session index and find inactive sessions + toDismiss.clear(); + for(pair = m_byCallId.begin(); pair != m_byCallId.end(); pair++) + { + RtpSessionRef session = pair->second; + if((now - session->m_lastUpdated) > 10) + { + toDismiss.push_back(session); + } + } + + // discard inactive sessions + for (it = toDismiss.begin(); it != toDismiss.end() ; it++) + { + RtpSessionRef session = *it; + LOG4CXX_DEBUG(m_log, session->m_ipAndPort + " Expired"); + Stop(session); + } } diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.h b/orkaudio/audiocaptureplugins/voip/RtpSession.h index 3fd07c1..c3caadc 100644 --- a/orkaudio/audiocaptureplugins/voip/RtpSession.h +++ b/orkaudio/audiocaptureplugins/voip/RtpSession.h @@ -18,6 +18,7 @@ #include "Rtp.h" #include #include "ace/Singleton.h" +#include "PacketHeaderDefs.h" class SipInviteInfo { @@ -67,8 +68,9 @@ class RtpSession public: #define PROT_RAW_RTP "RawRtp" #define PROT_SIP "Sip" +#define PROT_SKINNY "Skinny" #define PROT_UNKN "Unkn" - typedef enum{ProtRawRtp, ProtSip, ProtUnkn} ProtocolEnum; + typedef enum{ProtRawRtp, ProtSip, ProtSkinny, ProtUnkn} ProtocolEnum; static int ProtocolToEnum(CStdString& protocol); static CStdString ProtocolToString(int protocolEnum); @@ -78,16 +80,21 @@ public: void AddRtpPacket(RtpPacketInfoRef& rtpPacket); void ReportSipInvite(SipInviteInfoRef& invite); - CStdString m_ipAndPort; + CStdString m_ipAndPort; // IP address and TCP port of one side of the session, serves as a key for session storage and retrieval. Not necessarily the same as the capturePort (capturePort is usually the client (phone) IP+port) CStdString m_callId; SipInviteInfoRef m_invite; time_t m_lastUpdated; ProtocolEnum m_protocol; + CStdString m_localParty; + CStdString m_remoteParty; + CaptureEvent::DirectionEnum m_direction; + private: void ProcessMetadataSip(RtpPacketInfoRef&); void ProcessMetadataSipIncoming(); void ProcessMetadataSipOutgoing(); void ProcessMetadataRawRtp(RtpPacketInfoRef&); + void ProcessMetadataSkinny(RtpPacketInfoRef& rtpPacket); void ReportMetadata(); RtpPacketInfoRef m_lastRtpPacket; @@ -99,9 +106,6 @@ private: int m_inviteeTcpPort; LoggerPtr m_log; CStdString m_capturePort; - CStdString m_localParty; - CStdString m_remoteParty; - CaptureEvent::DirectionEnum m_direction; bool m_started; }; typedef boost::shared_ptr RtpSessionRef; @@ -114,6 +118,9 @@ public: void Stop(RtpSessionRef& session); void ReportSipInvite(SipInviteInfoRef& invite); void ReportSipBye(SipByeInfo bye); + void ReportSkinnyCallInfo(SkCallInfoStruct*); + void ReportSkinnyStartMediaTransmission(SkStartMediaTransmissionStruct*); + void ReportSkinnyStopMediaTransmission(SkStopMediaTransmissionStruct*); void ReportRtpPacket(RtpPacketInfoRef& rtpPacket); void Hoover(time_t now); private: diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp index b2f83bf..adc21da 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp @@ -268,25 +268,27 @@ void HandleSkinnyMessage(SkinnyHeaderStruct* skinnyHeader) { bool useful = true; CStdString debug; - SkStartMediaTransmissionStruct* start; - SkStopMediaTransmissionStruct* stop; + SkStartMediaTransmissionStruct* startMedia; + SkStopMediaTransmissionStruct* stopMedia; SkCallInfoStruct* callInfo; switch(skinnyHeader->messageType) { case SkStartMediaTransmission: - start = (SkStartMediaTransmissionStruct*)skinnyHeader; + startMedia = (SkStartMediaTransmissionStruct*)skinnyHeader; if(s_skinnyLog->isDebugEnabled()) { - debug.Format(" CallId:%u %s,%u", start->conferenceId, ACE_OS::inet_ntoa(start->remoteIpAddr), start->remoteTcpPort); + debug.Format(" CallId:%u %s,%u", startMedia->conferenceId, ACE_OS::inet_ntoa(startMedia->remoteIpAddr), startMedia->remoteTcpPort); } + RtpSessionsSingleton::instance()->ReportSkinnyStartMediaTransmission(startMedia); break; case SkStopMediaTransmission: - stop = (SkStopMediaTransmissionStruct*)skinnyHeader; + stopMedia = (SkStopMediaTransmissionStruct*)skinnyHeader; if(s_skinnyLog->isDebugEnabled()) { - debug.Format(" CallId:%u", stop->conferenceId); + debug.Format(" CallId:%u", stopMedia->conferenceId); } + RtpSessionsSingleton::instance()->ReportSkinnyStopMediaTransmission(stopMedia); break; case SkCallInfoMessage: callInfo = (SkCallInfoStruct*)skinnyHeader; @@ -294,6 +296,7 @@ void HandleSkinnyMessage(SkinnyHeaderStruct* skinnyHeader) { debug.Format(" CallId:%u calling:%s called:%s", callInfo->callId, callInfo->callingParty, callInfo->calledParty); } + RtpSessionsSingleton::instance()->ReportSkinnyCallInfo(callInfo); break; default: useful = false; -- cgit v1.2.3