diff options
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp | 28 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h | 29 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIp.cpp | 129 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp | 2 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIpConfig.h | 1 |
5 files changed, 167 insertions, 22 deletions
diff --git a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp index f3462a3..526680b 100644 --- a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp +++ b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp @@ -88,6 +88,20 @@ bool SkinnyValidateStartMediaTransmission(SkStartMediaTransmissionStruct* smt, u return valid; } +bool SkinnyValidateCcm7_1StartMediaTransmission(SkCcm7_1StartMediaTransmissionStruct *smt, u_char* packetEnd) +{ + bool valid = true; + if(((u_char*)smt + sizeof(SkCcm7_1StartMediaTransmissionStruct)) > packetEnd) + { + valid = false; + } + else if (smt->remoteTcpPort > 65535) + { + valid = false; + } + return valid; +} + bool SkinnyValidateStopMediaTransmission(SkStopMediaTransmissionStruct* smt, u_char* packetEnd) { bool valid = true; @@ -200,6 +214,20 @@ bool SkinnyValidateOpenReceiveChannelAck(SkOpenReceiveChannelAckStruct* orca, u_ return valid; } +bool SkinnyValidateCcm7_1SkOpenReceiveChannelAckStruct(SkCcm7_1SkOpenReceiveChannelAckStruct *orca, u_char* packetEnd) +{ + bool valid = true; + if(((u_char*)orca + sizeof(SkCcm7_1SkOpenReceiveChannelAckStruct)) > packetEnd) + { + valid = false; + } + else if (orca->endpointTcpPort > 65535) + { + valid = false; + } + return valid; +} + bool SkinnyValidateLineStat(SkLineStatStruct* lineStat, u_char* packetEnd) { bool valid = true; diff --git a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h index 99de0b5..fbc547e 100644 --- a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h +++ b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h @@ -135,6 +135,21 @@ typedef struct bool SkinnyValidateStartMediaTransmission(SkStartMediaTransmissionStruct *, u_char* packetEnd); +typedef struct +{ + SkinnyHeaderStruct header; + unsigned int conferenceId; + unsigned int passThruPartyId; + unsigned int stuff1; + struct in_addr remoteIpAddr; + unsigned int stuff2; + unsigned int stuff3; + unsigned int stuff4; + unsigned int remoteTcpPort; + // Other stuff +} SkCcm7_1StartMediaTransmissionStruct; + +bool SkinnyValidateCcm7_1StartMediaTransmission(SkCcm7_1StartMediaTransmissionStruct *, u_char* packetEnd); typedef struct { @@ -211,6 +226,20 @@ bool SkinnyValidateOpenReceiveChannelAck(SkOpenReceiveChannelAckStruct *, u_char typedef struct { SkinnyHeaderStruct header; + unsigned int openReceiveChannelStatus; + unsigned int stuff1; + struct in_addr endpointIpAddr; + unsigned int passThruPartyId; + unsigned int stuff2; + unsigned int stuff3; + unsigned int endpointTcpPort; +} SkCcm7_1SkOpenReceiveChannelAckStruct; + +bool SkinnyValidateCcm7_1SkOpenReceiveChannelAckStruct(SkCcm7_1SkOpenReceiveChannelAckStruct *orca, u_char* packetEnd); + +typedef struct +{ + SkinnyHeaderStruct header; unsigned int softKeyEvent; unsigned int lineInstance; unsigned int callIdentifier; diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp index 2ca681c..6640590 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp @@ -2385,9 +2385,11 @@ void HandleSkinnyMessage(SkinnyHeaderStruct* skinnyHeader, IpHeaderStruct* ipHea CStdString logMsg; SkStartMediaTransmissionStruct* startMedia; + SkStartMediaTransmissionStruct smtmp; SkStopMediaTransmissionStruct* stopMedia; SkCallInfoStruct* callInfo; SkOpenReceiveChannelAckStruct* openReceiveAck; + SkOpenReceiveChannelAckStruct orcatmp; SkLineStatStruct* lineStat; SkCcm5CallInfoStruct* ccm5CallInfo; SkSoftKeyEventMessageStruct* softKeyEvent; @@ -2395,24 +2397,61 @@ void HandleSkinnyMessage(SkinnyHeaderStruct* skinnyHeader, IpHeaderStruct* ipHea char szEndpointIp[16]; struct in_addr endpointIp = ipHeader->ip_dest; // most of the interesting skinny messages are CCM -> phone + memset(&smtmp, 0, sizeof(smtmp)); + memset(&orcatmp, 0, sizeof(orcatmp)); + switch(skinnyHeader->messageType) { case SkStartMediaTransmission: - startMedia = (SkStartMediaTransmissionStruct*)skinnyHeader; - if(SkinnyValidateStartMediaTransmission(startMedia, packetEnd)) + if(DLLCONFIG.m_cucm7_1Mode == true) { - if(s_skinnyPacketLog->isInfoEnabled()) + SkCcm7_1StartMediaTransmissionStruct *ccm7_1sm; + + ccm7_1sm = (SkCcm7_1StartMediaTransmissionStruct*)skinnyHeader; + if(SkinnyValidateCcm7_1StartMediaTransmission(ccm7_1sm, packetEnd)) + { + startMedia = &smtmp; + + memcpy(&startMedia->header, &ccm7_1sm->header, sizeof(startMedia->header)); + startMedia->conferenceId = ccm7_1sm->conferenceId; + startMedia->passThruPartyId = ccm7_1sm->passThruPartyId; + memcpy(&startMedia->remoteIpAddr, &ccm7_1sm->remoteIpAddr, sizeof(startMedia->remoteIpAddr)); + startMedia->remoteTcpPort = ccm7_1sm->remoteTcpPort; + + if(s_skinnyPacketLog->isInfoEnabled()) + { + char szRemoteIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&startMedia->remoteIpAddr, szRemoteIp, sizeof(szRemoteIp)); + logMsg.Format(" (CCM 7.1) CallId:%u PassThru:%u media address:%s,%u", startMedia->conferenceId, startMedia->passThruPartyId, szRemoteIp, startMedia->remoteTcpPort); + } + + RtpSessionsSingleton::instance()->ReportSkinnyStartMediaTransmission(startMedia, ipHeader); + } + else { - char szRemoteIp[16]; - ACE_OS::inet_ntop(AF_INET, (void*)&startMedia->remoteIpAddr, szRemoteIp, sizeof(szRemoteIp)); - logMsg.Format(" CallId:%u PassThru:%u media address:%s,%u", startMedia->conferenceId, startMedia->passThruPartyId, szRemoteIp, startMedia->remoteTcpPort); + useful = false; + LOG4CXX_WARN(s_skinnyPacketLog, "Invalid CCM 7.1 StartMediaTransmission."); } - RtpSessionsSingleton::instance()->ReportSkinnyStartMediaTransmission(startMedia, ipHeader); } else { - useful = false; - LOG4CXX_WARN(s_skinnyPacketLog, "Invalid StartMediaTransmission."); + startMedia = (SkStartMediaTransmissionStruct*)skinnyHeader; + + if(SkinnyValidateStartMediaTransmission(startMedia, packetEnd)) + { + if(s_skinnyPacketLog->isInfoEnabled()) + { + char szRemoteIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&startMedia->remoteIpAddr, szRemoteIp, sizeof(szRemoteIp)); + logMsg.Format(" CallId:%u PassThru:%u media address:%s,%u", startMedia->conferenceId, startMedia->passThruPartyId, szRemoteIp, startMedia->remoteTcpPort); + } + RtpSessionsSingleton::instance()->ReportSkinnyStartMediaTransmission(startMedia, ipHeader); + } + else + { + useful = false; + LOG4CXX_WARN(s_skinnyPacketLog, "Invalid StartMediaTransmission."); + } } break; case SkStopMediaTransmission: @@ -2494,11 +2533,23 @@ void HandleSkinnyMessage(SkinnyHeaderStruct* skinnyHeader, IpHeaderStruct* ipHea case 2: calledParty = party; break; + case 3: + if(DLLCONFIG.m_cucm7_1Mode == true) + { + // In CCM 7.1, it appears that each party is + // named twice + calledParty = party; + } + break; case 5: - // Token 5 is the calling extension, use this if outbound for callingParty instead of general number - if(party.size()>0 && ccm5CallInfo->callType == SKINNY_CALL_TYPE_OUTBOUND) + if(DLLCONFIG.m_cucm7_1Mode == false) { - callingParty = party; + // Token 5 is the calling extension, use this if outbound for callingParty instead of general number + // With CCM 7.1, this appears not to be the case + if(party.size()>0 && ccm5CallInfo->callType == SKINNY_CALL_TYPE_OUTBOUND) + { + callingParty = party; + } } break; case 6: @@ -2547,22 +2598,56 @@ void HandleSkinnyMessage(SkinnyHeaderStruct* skinnyHeader, IpHeaderStruct* ipHea } break; case SkOpenReceiveChannelAck: - openReceiveAck = (SkOpenReceiveChannelAckStruct*)skinnyHeader; - if(SkinnyValidateOpenReceiveChannelAck(openReceiveAck, packetEnd)) + if(DLLCONFIG.m_cucm7_1Mode == true) { - if(s_skinnyPacketLog->isInfoEnabled()) + SkCcm7_1SkOpenReceiveChannelAckStruct *orca; + + orca = (SkCcm7_1SkOpenReceiveChannelAckStruct*)skinnyHeader; + if(SkinnyValidateCcm7_1SkOpenReceiveChannelAckStruct(orca, packetEnd)) { - char szMediaIp[16]; - ACE_OS::inet_ntop(AF_INET, (void*)&openReceiveAck->endpointIpAddr, szMediaIp, sizeof(szMediaIp)); - logMsg.Format(" PassThru:%u media address:%s,%u", openReceiveAck->passThruPartyId, szMediaIp, openReceiveAck->endpointTcpPort); + openReceiveAck = &orcatmp; + + memcpy(&openReceiveAck->header, &orca->header, sizeof(openReceiveAck->header)); + openReceiveAck->openReceiveChannelStatus = orca->openReceiveChannelStatus; + memcpy(&openReceiveAck->endpointIpAddr, &orca->endpointIpAddr, sizeof(openReceiveAck->endpointIpAddr)); + openReceiveAck->endpointTcpPort = orca->endpointTcpPort; + openReceiveAck->passThruPartyId = orca->passThruPartyId; + + if(s_skinnyPacketLog->isInfoEnabled()) + { + char szMediaIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&openReceiveAck->endpointIpAddr, szMediaIp, sizeof(szMediaIp)); + logMsg.Format(" (CCM 7.1) PassThru:%u media address:%s,%u", openReceiveAck->passThruPartyId, szMediaIp, openReceiveAck->endpointTcpPort); + } + endpointIp = ipHeader->ip_src; // this skinny message is phone -> CCM + RtpSessionsSingleton::instance()->ReportSkinnyOpenReceiveChannelAck(openReceiveAck); + } + else + { + useful = false; + LOG4CXX_WARN(s_skinnyPacketLog, "Invalid CCM 7.1 OpenReceiveChannelAck."); } - endpointIp = ipHeader->ip_src; // this skinny message is phone -> CCM - RtpSessionsSingleton::instance()->ReportSkinnyOpenReceiveChannelAck(openReceiveAck); } else { - useful = false; - LOG4CXX_WARN(s_skinnyPacketLog, "Invalid OpenReceiveChannelAck."); + openReceiveAck = (SkOpenReceiveChannelAckStruct*)skinnyHeader; + + if(SkinnyValidateOpenReceiveChannelAck(openReceiveAck, packetEnd)) + { + if(s_skinnyPacketLog->isInfoEnabled()) + { + char szMediaIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&openReceiveAck->endpointIpAddr, szMediaIp, sizeof(szMediaIp)); + logMsg.Format(" PassThru:%u media address:%s,%u", openReceiveAck->passThruPartyId, szMediaIp, openReceiveAck->endpointTcpPort); + } + endpointIp = ipHeader->ip_src; // this skinny message is phone -> CCM + RtpSessionsSingleton::instance()->ReportSkinnyOpenReceiveChannelAck(openReceiveAck); + } + else + { + useful = false; + LOG4CXX_WARN(s_skinnyPacketLog, "Invalid OpenReceiveChannelAck."); + } } break; case SkLineStatMessage: diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp index 5453498..1071303 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp @@ -67,6 +67,7 @@ VoIpConfig::VoIpConfig() m_skinnyAllowLateCallInfo = false; m_skinnyNameAsLocalParty = false; m_skinnyCallInfoStopsPrevious = false; + m_cucm7_1Mode = false; m_sangomaEnable = false; m_sangomaRxTcpPortStart = 0; @@ -143,6 +144,7 @@ void VoIpConfig::Define(Serializer* s) s->BoolValue("SkinnyNameAsLocalParty", m_skinnyNameAsLocalParty); s->BoolValue("SkinnyCallInfoStopsPrevious", m_skinnyCallInfoStopsPrevious); s->CsvValue("SkinnyReportTags", m_skinnyReportTags); + s->BoolValue("Cucm7-1Mode", m_cucm7_1Mode); s->IntValue("SangomaRxTcpPortStart", m_sangomaRxTcpPortStart); s->IntValue("SangomaTxTcpPortStart", m_sangomaTxTcpPortStart); diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h index 77db63a..7dace48 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h @@ -104,6 +104,7 @@ public: bool m_skinnyAllowLateCallInfo; bool m_skinnyNameAsLocalParty; bool m_skinnyCallInfoStopsPrevious; + bool m_cucm7_1Mode; std::list<CStdString> m_skinnyReportTags; std::list<CStdString> m_dnisNumbers; |