📄 h323.cxx
字号:
<< "\n " << setprecision(2) << strm); else PTRACE(3, "H245\tSending PDU: " << pdu.GetTagName() << ' ' << ((PASN_Choice &)pdu.GetObject()).GetTagName());#endif if (!h245Tunneling) { if (controlChannel != NULL && controlChannel->IsOpen() && controlChannel->WritePDU(strm)) return TRUE; PTRACE(1, "H245\tWrite fail."); return FALSE; } // If have a pending signalling PDU, use it rather than separate write H323SignalPDU localTunnelPDU; H323SignalPDU * tunnelPDU; if (h245TunnelPDU != NULL) tunnelPDU = h245TunnelPDU; else { localTunnelPDU.BuildFacility(*this, TRUE); tunnelPDU = &localTunnelPDU; } tunnelPDU->m_h323_uu_pdu.IncludeOptionalField(H225_H323_UU_PDU::e_h245Control); PINDEX last = tunnelPDU->m_h323_uu_pdu.m_h245Control.GetSize(); tunnelPDU->m_h323_uu_pdu.m_h245Control.SetSize(last+1); tunnelPDU->m_h323_uu_pdu.m_h245Control[last] = strm; if (h245TunnelPDU != NULL) return TRUE; return WriteSignalPDU(localTunnelPDU);}BOOL H323Connection::StartControlNegotiations(){ PTRACE(2, "H245\tStarted control channel"); // Begin the capability exchange procedure if (!capabilityExchangeProcedure->HasSentCapabilities() && !capabilityExchangeProcedure->Start()) { PTRACE(1, "H245\tStart of Capability Exchange failed"); return FALSE; } // Begin the Master/Slave determination procedure if (!masterSlaveDeterminationProcedure->IsDetermined() && !masterSlaveDeterminationProcedure->Start()) { PTRACE(1, "H245\tStart of Master/Slave determination failed"); return FALSE; } return TRUE;}void H323Connection::HandleControlChannel(){ if (!StartControlNegotiations()) return; controlChannel->SetReadTimeout(endpoint.GetRoundTripDelayRate()); for (;;) { PPER_Stream strm; if (controlChannel->ReadPDU(strm)) { PTRACE(4, "H245\tReceived TPKT: " << strm); if (!HandleControlData(strm)) break; } else if (connectionState != EstablishedConnection || controlChannel->GetErrorCode() != PChannel::Timeout) { PTRACE(1, "H245\tRead error: " << controlChannel->GetErrorText()); ClearCall(EndedByTransportFail); break; } StartRoundTripDelay(); } PTRACE(2, "H245\tControl channel closed.");}BOOL H323Connection::HandleControlData(PPER_Stream & strm){ while (!strm.IsAtEnd()) { H323ControlPDU pdu; if (!pdu.Decode(strm)) { PTRACE(1, "H245\tInvalid PDU decode."); return TRUE; } if (!HandleControlPDU(pdu)) return FALSE; if (connectionState == HasExecutedSignalConnect) { PWaitAndSignal mutex(inUseFlag); if (masterSlaveDeterminationProcedure->IsDetermined() && capabilityExchangeProcedure->HasSentCapabilities() && capabilityExchangeProcedure->HasReceivedCapabilities()) { if (fastStartChannels.IsEmpty() && !OnControlChannelOpen()) return FALSE; connectionState = EstablishedConnection; } } strm.ByteAlign(); } return TRUE;}BOOL H323Connection::HandleControlPDU(const H323ControlPDU & pdu){#if PTRACING if (PTrace::CanTrace(4)) PTRACE(4, "H245\tReceived PDU (connectionState=" << connectionState << "):\n " << setprecision(2) << pdu); else PTRACE(3, "H245\tReceived PDU: " << pdu.GetTagName() << ' ' << ((PASN_Choice &)pdu.GetObject()).GetTagName());#endif switch (pdu.GetTag()) { case H245_MultimediaSystemControlMessage::e_request : return OnH245Request(pdu); case H245_MultimediaSystemControlMessage::e_response : return OnH245Response(pdu); case H245_MultimediaSystemControlMessage::e_command : return OnH245Command(pdu); case H245_MultimediaSystemControlMessage::e_indication : return OnH245Indication(pdu); } return OnUnknownControlPDU(pdu);}BOOL H323Connection::OnUnknownControlPDU(const H323ControlPDU & pdu){ PTRACE(2, "H245\tUnknown Control PDU: " << pdu); H323ControlPDU reply; reply.BuildFunctionNotUnderstood(pdu); return WriteControlPDU(reply);}BOOL H323Connection::OnH245Request(const H323ControlPDU & pdu){ const H245_RequestMessage & request = pdu; switch (request.GetTag()) { case H245_RequestMessage::e_masterSlaveDetermination : return masterSlaveDeterminationProcedure->HandleIncoming(request); case H245_RequestMessage::e_terminalCapabilitySet : return capabilityExchangeProcedure->HandleIncoming(request); case H245_RequestMessage::e_openLogicalChannel : return logicalChannels->HandleOpen(request); case H245_RequestMessage::e_closeLogicalChannel : return logicalChannels->HandleClose(request); case H245_RequestMessage::e_requestChannelClose : return logicalChannels->HandleRequestClose(request); case H245_RequestMessage::e_requestMode : return requestModeProcedure->HandleRequest(request); case H245_RequestMessage::e_roundTripDelayRequest : return roundTripDelayProcedure->HandleRequest(request); } return OnUnknownControlPDU(pdu);}BOOL H323Connection::OnH245Response(const H323ControlPDU & pdu){ const H245_ResponseMessage & response = pdu; switch (response.GetTag()) { case H245_ResponseMessage::e_masterSlaveDeterminationAck : return masterSlaveDeterminationProcedure->HandleAck(response); case H245_ResponseMessage::e_masterSlaveDeterminationReject : return masterSlaveDeterminationProcedure->HandleReject(response); case H245_ResponseMessage::e_terminalCapabilitySetAck : return capabilityExchangeProcedure->HandleAck(response); case H245_ResponseMessage::e_terminalCapabilitySetReject : return capabilityExchangeProcedure->HandleReject(response); case H245_ResponseMessage::e_openLogicalChannelAck : return logicalChannels->HandleOpenAck(response); case H245_ResponseMessage::e_openLogicalChannelReject : return logicalChannels->HandleReject(response); case H245_ResponseMessage::e_closeLogicalChannelAck : return logicalChannels->HandleCloseAck(response); case H245_ResponseMessage::e_requestChannelCloseAck : return logicalChannels->HandleRequestCloseAck(response); case H245_ResponseMessage::e_requestChannelCloseReject : return logicalChannels->HandleRequestCloseReject(response); case H245_ResponseMessage::e_requestModeAck : return requestModeProcedure->HandleAck(response); case H245_ResponseMessage::e_requestModeReject : return requestModeProcedure->HandleReject(response); case H245_ResponseMessage::e_roundTripDelayResponse : return roundTripDelayProcedure->HandleResponse(response); } return OnUnknownControlPDU(pdu);}BOOL H323Connection::OnH245Command(const H323ControlPDU & pdu){ const H245_CommandMessage & command = pdu; switch (command.GetTag()) { case H245_CommandMessage::e_sendTerminalCapabilitySet : return OnH245_SendTerminalCapabilitySet(command); case H245_CommandMessage::e_flowControlCommand : return OnH245_FlowControlCommand(command); case H245_CommandMessage::e_miscellaneousCommand : return OnH245_MiscellaneousCommand(command); case H245_CommandMessage::e_endSessionCommand : if (connectionState == EstablishedConnection) ClearCall(EndedByRemoteUser); else if (answerResponse == AnswerCallDeferred) ClearCall(EndedByCallerAbort); else ClearCall(EndedByRefusal); return FALSE; } return OnUnknownControlPDU(pdu);}BOOL H323Connection::OnH245Indication(const H323ControlPDU & pdu){ const H245_IndicationMessage & indication = pdu; switch (indication.GetTag()) { case H245_IndicationMessage::e_masterSlaveDeterminationRelease : return masterSlaveDeterminationProcedure->HandleRelease(indication); case H245_IndicationMessage::e_terminalCapabilitySetRelease : return capabilityExchangeProcedure->HandleRelease(indication); case H245_IndicationMessage::e_openLogicalChannelConfirm : return logicalChannels->HandleOpenConfirm(indication); case H245_IndicationMessage::e_requestChannelCloseRelease : return logicalChannels->HandleRequestCloseRelease(indication); case H245_IndicationMessage::e_requestModeRelease : return requestModeProcedure->HandleRelease(indication); case H245_IndicationMessage::e_miscellaneousIndication : return OnH245_MiscellaneousIndication(indication); case H245_IndicationMessage::e_jitterIndication : return OnH245_JitterIndication(indication); case H245_IndicationMessage::e_userInput : OnUserInputIndication(indication); break; } return TRUE; // Do NOT call OnUnknownControlPDU for indications}BOOL H323Connection::OnH245_SendTerminalCapabilitySet( const H245_SendTerminalCapabilitySet & pdu){ if (pdu.GetTag() == H245_SendTerminalCapabilitySet::e_genericRequest) return capabilityExchangeProcedure->Start(); PTRACE(2, "H245\tUnhandled SendTerminalCapabilitySet: " << pdu); return TRUE;}BOOL H323Connection::OnH245_FlowControlCommand( const H245_FlowControlCommand & pdu){ PTRACE(3, "H245\tFlowControlCommand: scope=" << pdu.m_scope.GetTagName()); long restriction; if (pdu.m_restriction.GetTag() == H245_FlowControlCommand_restriction::e_maximumBitRate) restriction = (const PASN_Integer &)pdu.m_restriction; else restriction = -1; // H245_FlowControlCommand_restriction::e_noRestriction switch (pdu.m_scope.GetTag()) { case H245_FlowControlCommand_scope::e_wholeMultiplex : OnLogicalChannelFlowControl(NULL, restriction); break; case H245_FlowControlCommand_scope::e_logicalChannelNumber : { H323Channel * chan = logicalChannels->FindChannel((unsigned)(const H245_LogicalChannelNumber &)pdu.m_scope, FALSE); if (chan != NULL) OnLogicalChannelFlowControl(chan, restriction); } } return TRUE;}BOOL H323Connection::OnH245_MiscellaneousCommand( const H245_MiscellaneousCommand & pdu){ H323Channel * chan = logicalChannels->FindChannel((unsigned)pdu.m_logicalChannelNumber, FALSE); if (chan != NULL) chan->OnMiscellaneousCommand(pdu.m_type); else PTRACE(3, "H245\tMiscellaneousCommand: chan=" << pdu.m_logicalChannelNumber << ", type=" << pdu.m_type.GetTagName()); return TRUE;}BOOL H323Connection::OnH245_MiscellaneousIndication( const H245_MiscellaneousIndication & pdu){ H323Channel * chan = logicalChannels->FindChannel((unsigned)pdu.m_logicalChannelNumber, TRUE); if (chan != NULL) chan->OnMiscellaneousIndication(pdu.m_type); else PTRACE(3, "H245\tMiscellaneousIndication: chan=" << pdu.m_logicalChannelNumber << ", type=" << pdu.m_type.GetTagName()); return TRUE;}BOOL H323Connection::OnH245_JitterIndication( const H245_JitterIndication & pdu){ PTRACE(3, "H245\tJitterIndication: scope=" << pdu.m_scope.GetTagName()); static const DWORD mantissas[8] = { 0, 1, 10, 100, 1000, 10000, 100000, 1000000 }; static const DWORD exponents[8] = { 10, 25, 50, 75 }; DWORD jitter = mantissas[pdu.m_estimatedReceivedJitterMantissa]* exponents[pdu.m_estimatedReceivedJitterExponent]/10; int skippedFrameCount = -1; if (pdu.HasOptionalField(H245_JitterIndication::e_skippedFrameCount)) skippedFrameCount = pdu.m_skippedFrameCount; int additionalBuffer = -1; if (pdu.HasOptionalField(H245_JitterIndication::e_additionalDecoderBuffer)) additionalBuffer = pdu.m_additionalDecoderBuffer; switch (pdu.m_scope.GetTag()) { case H245_JitterIndication_scope::e_wholeMultiplex : OnLogicalChannelJitter(NULL, jitter, skippedFrameCount, additionalBuffer); break; case H245_JitterIndication_scope::e_logicalChannelNu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -