📄 h323.cxx
字号:
// were fast starting. if (h245Tunneling && needsCapabilityExchange) { capabilityExchangeProcedure->Start(); return TRUE; } // Check for if all the 245 conditions are met so can call // OnControlChannelOpen() to start up logical channels and complete the // connection establishment. PWaitAndSignal mutex(inUseFlag); if (connectionState == HasExecutedSignalConnect && masterSlaveDeterminationProcedure->IsDetermined() && capabilityExchangeProcedure->HasSentCapabilities() && capabilityExchangeProcedure->HasReceivedCapabilities()) { if (!OnControlChannelOpen()) return FALSE; connectionState = EstablishedConnection; } return TRUE;}BOOL H323Connection::OnReceivedFacility(const H323SignalPDU & pdu){ if (pdu.m_h323_uu_pdu.m_h323_message_body.GetTag() == H225_H323_UU_PDU_h323_message_body::e_empty) return TRUE; const H225_Facility_UUIE & fac = pdu.m_h323_uu_pdu.m_h323_message_body; // Check for fastStart data and start fast if (fac.HasOptionalField(H225_Facility_UUIE::e_fastStart)) HandleFastStartAcknowledge(fac.m_fastStart); // Check that it has the H.245 channel connection info if (fac.HasOptionalField(H225_Facility_UUIE::e_h245Address)) return StartControlChannel(fac.m_h245Address); if (fac.m_reason.GetTag() != H225_FacilityReason::e_callForwarded) return TRUE; PString address; if (fac.HasOptionalField(H225_Facility_UUIE::e_alternativeAliasAddress) && fac.m_alternativeAliasAddress.GetSize() > 0) address = H323GetAliasAddressString(fac.m_alternativeAliasAddress[0]); if (fac.HasOptionalField(H225_Facility_UUIE::e_alternativeAddress)) { if (!address) address += '@'; address += H323TransportAddress(fac.m_alternativeAddress); } if (endpoint.OnConnectionForwarded(*this, address, pdu)) { ClearCall(EndedByCallForwarded); return FALSE; } return TRUE;}BOOL H323Connection::OnReceivedStatusEnquiry(const H323SignalPDU & pdu){ H323SignalPDU reply; reply.BuildStatus(callReference, !pdu.GetQ931().IsFromDestination()); return reply.Write(*signallingChannel);}BOOL H323Connection::OnIncomingCall(const H323SignalPDU & setupPDU, H323SignalPDU & alertingPDU){ return endpoint.OnIncomingCall(*this, setupPDU, alertingPDU);}BOOL H323Connection::ForwardCall(const PString & forwardParty){ if (forwardParty.IsEmpty()) return FALSE; PString alias; H323TransportAddress address; endpoint.ParsePartyName(forwardParty, alias, address); H323SignalPDU redirectPDU; H225_Facility_UUIE * fac = redirectPDU.BuildFacility(*this, FALSE); fac->m_reason.SetTag(H225_FacilityReason::e_callForwarded); if (!address) { fac->IncludeOptionalField(H225_Facility_UUIE::e_alternativeAddress); address.SetPDU(fac->m_alternativeAddress); } if (!alias) { fac->IncludeOptionalField(H225_Facility_UUIE::e_alternativeAliasAddress); fac->m_alternativeAliasAddress.SetSize(1); H323SetAliasAddress(alias, fac->m_alternativeAliasAddress[0]); } if (WriteSignalPDU(redirectPDU)) ClearCall(EndedByCallForwarded); return TRUE;}H323Connection::AnswerCallResponse H323Connection::OnAnswerCall(const PString & caller, const H323SignalPDU & setupPDU, H323SignalPDU & connectPDU){ return endpoint.OnAnswerCall(*this, caller, setupPDU, connectPDU);}void H323Connection::AnsweringCall(AnswerCallResponse response){ if (response == AnswerCallDeferred) return; answerResponse = response; answerWaitFlag.Signal();}H323Connection::CallEndReason H323Connection::SendSignalSetup(const PString & alias, const H323TransportAddress & address){ PWaitAndSignal lockConnection(inUseFlag); connectionState = AwaitingGatekeeperAdmission; // Indicate the direction of call. callAnswered = FALSE; if (alias.IsEmpty()) remotePartyName = remotePartyAddress = address; else { remotePartyName = alias; remotePartyAddress = alias + '@' + address; } // Start building the setup PDU to get various ID's H323SignalPDU setupPDU; H225_Setup_UUIE & setup = setupPDU.BuildSetup(*this); // Save the identifiers generated by BuildSetup callToken = H323EndPoint::BuildConnectionToken(*signallingChannel, callReference, FALSE); callIdentifier = setup.m_callIdentifier.m_guid; conferenceIdentifier = setup.m_conferenceID; setupPDU.GetQ931().GetCalledPartyNumber(remotePartyNumber); H323TransportAddress gatekeeperRoute = address; // Check for gatekeeper and do admission check if have one H323Gatekeeper * gatekeeper = endpoint.GetGatekeeper(); if (gatekeeper != NULL) { if (!gatekeeper->AdmissionRequest(*this, gatekeeperRoute)) { unsigned reason = gatekeeper->GetRejectReason(); PTRACE(1, "H225\tGatekeeper refused admission: " << H225_AdmissionRejectReason(reason).GetTagName()); switch (reason) { case H225_AdmissionRejectReason::e_calledPartyNotRegistered : return EndedByNoUser; case H225_AdmissionRejectReason::e_requestDenied : return EndedByNoBandwidth; } return EndedByGatekeeper; } } if (!signallingChannel->SetRemoteAddress(gatekeeperRoute)) { PTRACE(1, "H225\tInvalid " << (gatekeeperRoute != address ? "gatekeeper" : "user") << " supplied address: \"" << gatekeeperRoute << '"'); connectionState = AwaitingTransportConnect; return EndedByConnectFail; } // Do the transport connect connectionState = AwaitingTransportConnect; if (!signallingChannel->Connect()) { connectionState = NoConnectionActive; return EndedByConnectFail; } PTRACE(3, "H225\tSending Setup PDU"); connectionState = AwaitingSignalConnect; // Put in all the signalling addresses for link setup.IncludeOptionalField(H225_Setup_UUIE::e_sourceCallSignalAddress); signallingChannel->SetUpTransportPDU(setup.m_sourceCallSignalAddress, TRUE); setup.IncludeOptionalField(H225_Setup_UUIE::e_destCallSignalAddress); signallingChannel->SetUpTransportPDU(setup.m_destCallSignalAddress, FALSE); // Ask the application what channels to open PTRACE(3, "H225\tCheck for Fast start by local endpoint"); fastStartState = FastStartInitiate; fastStartChannels.RemoveAll(); OnSelectLogicalChannels(); // If application called OpenLogicalChannel, put in the fastStart field if (!fastStartChannels.IsEmpty()) { PTRACE(3, "H225\tFast start begun by local endpoint"); for (PINDEX i = 0; i < fastStartChannels.GetSize(); i++) BuildFastStartList(fastStartChannels[i], setup.m_fastStart, H323Channel::IsReceiver); if (setup.m_fastStart.GetSize() > 0) setup.IncludeOptionalField(H225_Setup_UUIE::e_fastStart); } if (!OnSendSignalSetup(setupPDU)) return EndedByNoAccept; // Do this again (was done when PDU was constructed) in case // OnSendSignalSetup() changed something. setupPDU.SetQ931Fields(*this); fastStartState = FastStartDisabled; if (h245Tunneling) { h245TunnelPDU = &setupPDU; // Cannot do capability exchange if if fast starting though. if (fastStartChannels.IsEmpty()) { // Try and start the master/slave and capability exchange through the tunnel masterSlaveDeterminationProcedure->Start(); capabilityExchangeProcedure->Start(); } h245TunnelPDU = NULL; } // Send the initial PDU if (!WriteSignalPDU(setupPDU)) return EndedByTransportFail; // Set timeout for remote party to answer the call signallingChannel->SetReadTimeout(endpoint.GetSignallingChannelCallTimeout()); return NumCallEndReasons;}BOOL H323Connection::OnSendSignalSetup(H323SignalPDU & /*setupPDU*/){ return TRUE;}BOOL H323Connection::OnAlerting(const H323SignalPDU & alertingPDU, const PString & username){ return endpoint.OnAlerting(*this, alertingPDU, username);}BOOL H323Connection::OnOutgoingCall(const H323SignalPDU & /*connectPDU*/){ PTRACE(1, "H225\tReceived connect PDU."); return TRUE;}BOOL H323Connection::HandleFastStartAcknowledge(const H225_ArrayOf_PASN_OctetString & array){ if (fastStartChannels.IsEmpty()) { PTRACE(3, "H225\tFast start response with no channels to open"); return FALSE; } PTRACE(3, "H225\tFast start accepted by remote endpoint"); PINDEX i; // Go through provided list of structures, if can decode it and match it up // with a channel we requested AND it has all the information needed in the // m_multiplexParameters, then we can start the channel. for (i = 0; i < array.GetSize(); i++) { H245_OpenLogicalChannel open; PPER_Stream strm = (PBYTEArray)array[i]; if (open.Decode(strm)) { PTRACE(4, "H225\tFast start open:\n " << setprecision(2) << open); BOOL reverse = open.HasOptionalField(H245_OpenLogicalChannel::e_reverseLogicalChannelParameters); const H245_DataType & dataType = reverse ? open.m_reverseLogicalChannelParameters.m_dataType : open.m_forwardLogicalChannelParameters.m_dataType; H323Capability * replyCapability = localCapabilities.FindCapability(dataType); if (replyCapability != NULL) { for (PINDEX ch = 0; ch < fastStartChannels.GetSize(); ch++) { H323Channel & channelToStart = fastStartChannels[ch]; if ((channelToStart.GetDirection() == H323Channel::IsReceiver) == reverse) { H323Capability & channelsCapability = (H323Capability &)channelToStart.GetCapability(); if (channelsCapability == *replyCapability) { H323Capability * remoteCapability = replyCapability; unsigned error = 1000; if (channelsCapability.OnReceivedPDU(dataType, channelToStart.GetDirection() == H323Channel::IsReceiver)) { // For transmitter, need to fake a capability into the remote table if (channelToStart.GetDirection() == H323Channel::IsTransmitter) { remoteCapability = remoteCapabilities.Copy(*replyCapability); remoteCapabilities.SetCapability(0, replyCapability->GetDefaultSessionID()-1, remoteCapability); } if (OnCreateLogicalChannel(*remoteCapability, channelToStart.GetDirection(), error) && channelToStart.OnReceivedPDU(open, error)) { if (channelToStart.SetInitialBandwidth()) { channelToStart.Start(); break; } else PTRACE(2, "H225\tFast start channel open fail: insufficent bandwidth"); } else PTRACE(2, "H225\tFast start channel open error: " << error); } else PTRACE(2, "H225\tFast start capability error: " << error); } } } } } } // Remove any channels that were not started by above, those that were // started are put into the logical channel dictionary for (i = 0; i < fastStartChannels.GetSize(); i++) { if (fastStartChannels[i].IsRunning()) logicalChannels->Add(fastStartChannels[i]); else fastStartChannels.RemoveAt(i--); } // The channels we just transferred to the logical channels dictionary // should not be deleted via this structure now. fastStartChannels.DisallowDeleteObjects(); PTRACE(2, "H225\tFast starting " << fastStartChannels.GetSize() << " channels"); if (fastStartChannels.IsEmpty()) return FALSE; // Have moved open channels to logicalChannels structure, remove them now. fastStartChannels.RemoveAll(); fastStartState = FastStartAcknowledged; return TRUE;}BOOL H323Connection::StartControlChannel(const H225_TransportAddress & h245Address){ // Check that it is an IP address, all we support at the moment if (h245Address.GetTag() != H225_TransportAddress::e_ipAddress) { PTRACE(1, "H225\tConnect of H245 failed: Unsupported transport"); return FALSE; } // Already have the H245 channel up. if (controlChannel != NULL) return TRUE; controlChannel = new H323TransportTCP(endpoint); if (controlChannel->SetRemoteAddress(h245Address) && controlChannel->ConnectControlChannel(*this)) return TRUE; PTRACE(1, "H225\tConnect of H245 failed: " << controlChannel->GetErrorText()); delete controlChannel; controlChannel = NULL; return FALSE;}BOOL H323Connection::OnUnknownSignalPDU(const H323SignalPDU & PTRACE_pdu){ PTRACE(2, "H225\tUnknown signalling PDU: " << PTRACE_pdu); return TRUE;}BOOL H323Connection::WriteControlPDU(const H323ControlPDU & pdu){ PPER_Stream strm; pdu.Encode(strm); strm.CompleteEncoding();#if PTRACING if (PTrace::CanTrace(4)) PTRACE(4, "H245\tSending PDU\n " << setprecision(2) << pdu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -