diff options
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp | 33 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h | 12 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIp.cpp | 29 |
3 files changed, 71 insertions, 3 deletions
diff --git a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp index d0fa8a4..123282e 100644 --- a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp +++ b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.cpp @@ -27,6 +27,10 @@ int SkinnyMessageToEnum(CStdString& msg) { msgEnum = SkLineStatMessage; } + else if (msg.CompareNoCase(SKINNY_MSG_CCM5_CALL_INFO_MESSAGE) == 0) + { + msgEnum = SkCcm5CallInfoMessage; + } return msgEnum; } @@ -53,6 +57,9 @@ CStdString SkinnyMessageToString(int msgEnum) case SkLineStatMessage: msgString = SKINNY_MSG_LINE_STAT_MESSAGE; break; + case SkCcm5CallInfoMessage: + msgString = SKINNY_MSG_CCM5_CALL_INFO_MESSAGE; + break; default: msgString = SKINNY_MSG_UNKN; } @@ -119,6 +126,32 @@ bool SkinnyValidateCallInfo(SkCallInfoStruct* sci) return valid; } + +bool SkinnyValidateCcm5CallInfo(SkCcm5CallInfoStruct *sci) +{ + bool valid = true; + if (sci->callType > SKINNY_CALL_TYPE_FORWARD) + { + valid = false; + } + if(valid) + { + valid = checkPartyString(sci->parties, SKINNY_CCM5_PARTIES_BLOCK_SIZE); + } + if(valid) + { + // Find the first null char separating the calling and called parties (at this point, we know there's one) + char* nullChar = (char*)&sci->parties; + while(*nullChar != '\0') + { + nullChar++; + } + valid = checkPartyString(nullChar+1, SKINNY_CCM5_PARTIES_BLOCK_SIZE); + } + return valid; +} + + bool SkinnyValidateOpenReceiveChannelAck(SkOpenReceiveChannelAckStruct* orca) { bool valid = true; diff --git a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h index c861f66..efa959a 100644 --- a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h +++ b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h @@ -146,14 +146,18 @@ typedef struct bool SkinnyValidateCallInfo(SkCallInfoStruct *); +#define SKINNY_CCM5_PARTIES_BLOCK_SIZE 76 typedef struct { SkinnyHeaderStruct header; unsigned long unknown1; unsigned long callId; - char unknown2[24]; - char parties[76]; -} SkNewCallInfoStruct; + unsigned long callType; + char unknown2[20]; + char parties[SKINNY_CCM5_PARTIES_BLOCK_SIZE]; +} SkCcm5CallInfoStruct; + +bool SkinnyValidateCcm5CallInfo(SkCcm5CallInfoStruct *); #define SKINNY_LINE_DIR_NUMBER_SIZE 24 #define SKINNY_DISPLAY_NAME_SIZE 40 @@ -191,6 +195,7 @@ bool SkinnyValidateOpenReceiveChannelAck(SkOpenReceiveChannelAckStruct *); #define SKINNY_MSG_CALL_INFO_MESSAGE "CallInfoMessage" #define SKINNY_MSG_OPEN_RECEIVE_CHANNEL_ACK "OpenReceiveChannelAck" #define SKINNY_MSG_LINE_STAT_MESSAGE "LineStatMessage" +#define SKINNY_MSG_CCM5_CALL_INFO_MESSAGE "Ccm5CallInfoMessage" #define SKINNY_CALL_TYPE_INBOUND 1 #define SKINNY_CALL_TYPE_OUTBOUND 2 @@ -204,6 +209,7 @@ typedef enum SkCallInfoMessage = 0x008F, SkLineStatMessage = 0x0092, SkCloseReceiveChannel = 0x0106, + SkCcm5CallInfoMessage = 0x14A, SkUnkn = 0x0 } SkinnyMessageEnum; int SkinnyMessageToEnum(CStdString& msg); diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp index 77a9dc6..802aa04 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp @@ -117,6 +117,7 @@ char* memFindEOL(char* start, char* limit) return start; } +// Grabs a string in memory until encountering null char, a space a CR or LF chars void GrabToken(char* in, CStdString& out) { for(char* c = in; *c != '\0' && *c != 0x20 && *c != 0x0D && *c != 0x0A; c = c+1) @@ -367,6 +368,7 @@ void HandleSkinnyMessage(SkinnyHeaderStruct* skinnyHeader, IpHeaderStruct* ipHea SkCallInfoStruct* callInfo; SkOpenReceiveChannelAckStruct* openReceiveAck; SkLineStatStruct* lineStat; + SkCcm5CallInfoStruct* ccm5CallInfo; char szEndpointIp[16]; struct in_addr endpointIp = ipHeader->ip_dest; // most of the interesting skinny messages are CCM -> phone @@ -417,6 +419,33 @@ void HandleSkinnyMessage(SkinnyHeaderStruct* skinnyHeader, IpHeaderStruct* ipHea LOG4CXX_WARN(s_skinnyPacketLog, "Invalid CallInfoMessage."); } break; + case SkCcm5CallInfoMessage: + ccm5CallInfo = (SkCcm5CallInfoStruct*)skinnyHeader; + if(SkinnyValidateCcm5CallInfo(ccm5CallInfo)) + { + // Extract Calling and Called number. + CStdString callingParty; + char* parties = (char*)(&ccm5CallInfo->parties); + GrabToken(parties, callingParty); + CStdString calledParty; + GrabToken(parties+callingParty.size()+1, calledParty); + + // Emulate a regular CCM CallInfo message + SkCallInfoStruct callInfo; + strcpy(callInfo.calledParty, (PCSTR)calledParty); + strcpy(callInfo.callingParty, (PCSTR)callingParty); + callInfo.callId = ccm5CallInfo->callId; + callInfo.callType = ccm5CallInfo->callType; + callInfo.lineInstance = 0; + callInfo.calledPartyName[0] = '\0'; + callInfo.callingPartyName[0] = '\0'; + if(s_skinnyPacketLog->isInfoEnabled()) + { + logMsg.Format(" CallId:%u calling:%s called:%s", callInfo.callId, callInfo.callingParty, callInfo.calledParty); + } + RtpSessionsSingleton::instance()->ReportSkinnyCallInfo(&callInfo, ipHeader); + } + break; case SkOpenReceiveChannelAck: openReceiveAck = (SkOpenReceiveChannelAckStruct*)skinnyHeader; if(SkinnyValidateOpenReceiveChannelAck(openReceiveAck)) |