📄 h323.cxx
字号:
strm.CompleteEncoding(); PINDEX last = array.GetSize(); array.SetSize(last+1); array[last] = strm; PTRACE(3, "H225\tBuilt fastStart for " << capability); return TRUE;}BOOL H323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU){ PINDEX i; const H225_Setup_UUIE & setup = setupPDU.m_h323_uu_pdu.m_h323_message_body; // Indicate the direction of call. callAnswered = TRUE; Q931::SignalInfo ringPattern = setupPDU.GetQ931().GetSignalInfo(); if (ringPattern >= Q931::SignalAlertingPattern0 && ringPattern <= Q931::SignalAlertingPattern7) distinctiveRing = ringPattern - Q931::SignalAlertingPattern0; else distinctiveRing = 0; // Set our call token for identification in endpoint dictionary callToken = H323EndPoint::BuildConnectionToken(*signallingChannel, callReference, TRUE); // Save the identifiers sent by caller if (setup.HasOptionalField(H225_Setup_UUIE::e_callIdentifier)) callIdentifier = setup.m_callIdentifier.m_guid; conferenceIdentifier = setup.m_conferenceID; SetRemoteApplication(setup.m_sourceInfo); // Determine the remote parties name/number/address as best we can setupPDU.GetQ931().GetCallingPartyNumber(remotePartyNumber); PString remoteHostName = signallingChannel->GetRemoteAddress().GetHostName(); PString displayName = setupPDU.GetQ931().GetDisplayName(); PStringStream newAliases; if (displayName != remoteHostName) newAliases << displayName; if (setup.m_sourceAddress.GetSize() > 0) { BOOL needParen = !newAliases.IsEmpty(); BOOL needComma = FALSE; for (i = 0; i < setup.m_sourceAddress.GetSize(); i++) { PString alias = H323GetAliasAddressString(setup.m_sourceAddress[i]); if (i == 0) remotePartyAddress = alias + '@' + remoteHostName; if (alias != displayName && alias != remoteHostName) { if (needComma) newAliases << ", "; else if (needParen) newAliases << " ("; newAliases << alias; needComma = TRUE; } } if (needParen && needComma) newAliases << ')'; if (remotePartyNumber.IsEmpty()) { for (i = 0; i < setup.m_sourceAddress.GetSize(); i++) { if (setup.m_sourceAddress[i].GetTag() == H225_AliasAddress::e_e164) { PASN_IA5String & ia5 = setup.m_sourceAddress[i]; remotePartyNumber = ia5; break; } } } } if (newAliases.IsEmpty()) remotePartyName = remotePartyAddress = remoteHostName; else { newAliases << " [" << remoteHostName << ']'; remotePartyName = newAliases; } // Send back a H323 Call Proceeding PDU in case OnIncomingCall() takes a while PTRACE(3, "H225\tSending call proceeding PDU"); H323SignalPDU callProceedingPDU; callProceedingPDU.BuildCallProceeding(*this); if (!WriteSignalPDU(callProceedingPDU)) return FALSE; // See if remote endpoint wants to start fast if (setup.HasOptionalField(H225_Setup_UUIE::e_fastStart)) { remoteCapabilities.RemoveAll(); PTRACE(3, "H225\tFast start detected"); // Extract capabilities from the fast start OpenLogicalChannel structures for (i = 0; i < setup.m_fastStart.GetSize(); i++) { H245_OpenLogicalChannel open; PPER_Stream strm = (PBYTEArray)setup.m_fastStart[i]; if (open.Decode(strm)) { PTRACE(4, "H225\tFast start open:\n " << setprecision(2) << open); unsigned error; H323Channel * channel = CreateLogicalChannel(open, TRUE, error); if (channel != NULL) { if (channel->GetDirection() == H323Channel::IsTransmitter) channel->SetNumber(logicalChannels->GetNextChannelNumber()); fastStartChannels.Append(channel); } } } PTRACE(3, "H225\tOpened " << fastStartChannels.GetSize() << " fast start channels"); // If we are incapable of ANY of the fast start channels, don't do fast start if (!fastStartChannels.IsEmpty()) fastStartState = FastStartResponse; } // Check for gatekeeper and do admission check if have one H323Gatekeeper * gatekeeper = endpoint.GetGatekeeper(); if (gatekeeper != NULL) { if (!gatekeeper->AdmissionRequest(*this)) { unsigned reason = gatekeeper->GetRejectReason(); PTRACE(1, "H225\tGatekeeper refused admission: " << H225_AdmissionRejectReason(reason).GetTagName()); switch (reason) { case H225_AdmissionRejectReason::e_calledPartyNotRegistered : ClearCall(EndedByNoUser); case H225_AdmissionRejectReason::e_requestDenied : ClearCall(EndedByNoBandwidth); default : ClearCall(EndedByGatekeeper); } return FALSE; } } // if the application indicates not to contine, then send a Q931 Release Complete PDU H323SignalPDU alertingPDU; alertingPDU.BuildAlerting(*this); if (!OnIncomingCall(setupPDU, alertingPDU)) { ClearCall(EndedByNoAccept); PTRACE(1, "H225\tApplication not accepting calls"); return FALSE; } // send Q931 Alerting PDU PTRACE(3, "H225\tIncoming call accepted"); // Build the reply with the channels we are actually using H323SignalPDU connectPDU; H225_Connect_UUIE & connect = connectPDU.BuildConnect(*this); // call the application callback to determine if to answer the call or not answerResponse = OnAnswerCall(remotePartyName, setupPDU, connectPDU); PTRACE(3, "H225\tAnswer call response: " << answerResponse); // If pending response wait while ((answerResponse == AnswerCallPending) || (answerResponse == AnswerCallDeferred)) { // send alerting PDU if required if (answerResponse == AnswerCallPending) { answerResponse = AnswerCallDeferred; // send Q931 Alerting PDU PTRACE(3, "H225\tSending Alerting PDU"); HandleTunnelPDU(setupPDU, &alertingPDU); if (!WriteSignalPDU(alertingPDU)) return FALSE; } // Wait for answer from application, but check for call being cleared in // the mean time. if (!answerWaitFlag.Wait(500)) { PTimeInterval oldTimeout = signallingChannel->GetReadTimeout(); signallingChannel->SetReadTimeout(0); H323SignalPDU pdu; if (pdu.Read(*signallingChannel)) { if (!HandleSignalPDU(pdu)) return FALSE; } else { if (signallingChannel->GetErrorCode() != PChannel::Timeout) return FALSE; } if (connectionState == ShuttingDownConnection) return FALSE; signallingChannel->SetReadTimeout(oldTimeout); } } // If response is denied, abort the call if (answerResponse == AnswerCallDenied) { PTRACE(1, "H225\tApplication has declined to answer incoming call"); ClearCall(EndedByAnswerDenied); return FALSE; } // Now ask the application to select which channels to start if (fastStartState == FastStartResponse) OnSelectLogicalChannels(); // Remove any channels that were not started by OnSelectLogicalChannels(), // 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(); // Set flag that we are up to CONNECT stage if (connectionState == ShuttingDownConnection) return FALSE; connectionState = HasExecutedSignalConnect; // No channels selected (or never provided) so do traditional H245 start if (fastStartChannels.IsEmpty()) { fastStartState = FastStartDisabled; if (h245Tunneling) { // Piggy back H245 on this reply h245TunnelPDU = &connectPDU; capabilityExchangeProcedure->Start(); HandleTunnelPDU(setupPDU, &connectPDU); return WriteSignalPDU(connectPDU); // Send H323 Connect PDU } return signallingChannel->CreateControlChannel(*this, controlChannel); } PTRACE(3, "H225\tAccepting fastStart for " << fastStartChannels.GetSize() << " channels"); connect.IncludeOptionalField(H225_Connect_UUIE::e_fastStart); for (i = 0; i < fastStartChannels.GetSize(); i++) BuildFastStartList(fastStartChannels[i], connect.m_fastStart, H323Channel::IsTransmitter); // Have moved open channels to logicalChannels structure, remove all others. fastStartChannels.RemoveAll(); // If have some acceptable channels, do the fast start if (connect.m_fastStart.GetSize() > 0) { connectionState = EstablishedConnection; connectionStartTime = PTime(); endpoint.OnConnectionEstablished(*this, callToken); return WriteSignalPDU(connectPDU); // Send H323 Connect PDU } // Otherwise something really odd just happened, abort call PTRACE(1, "H225\tFast start error!"); return FALSE;}void H323Connection::SetRemotePartyInfo(const H323SignalPDU & pdu){ PString newNumber; if (pdu.GetQ931().GetCalledPartyNumber(newNumber)) remotePartyNumber = newNumber; PString remoteHostName = signallingChannel->GetRemoteAddress().GetHostName(); PString newRemotePartyName = pdu.GetQ931().GetDisplayName(); if (newRemotePartyName.IsEmpty() || newRemotePartyName == remoteHostName) remotePartyName = remoteHostName; else remotePartyName = newRemotePartyName + " [" + remoteHostName + ']';}void H323Connection::SetRemoteApplication(const H225_EndpointType & pdu){ PStringStream str; if (pdu.HasOptionalField(H225_EndpointType::e_vendor)) str << pdu.m_vendor.m_productId.AsString() << '\t' << pdu.m_vendor.m_versionId.AsString() << '\t' << pdu.m_vendor.m_vendor.m_t35CountryCode << ':' << pdu.m_vendor.m_vendor.m_t35Extension << ':' << pdu.m_vendor.m_vendor.m_manufacturerCode; remoteApplication = str; PTRACE(2, "H225\tSet remote application name: \"" << remoteApplication << '"'); // Hack to fix Altigen problem. They do stupid things if there is an // receiveUserInputCapability entry in the capabilityTable! if (remoteApplication.Find("AltiServ-ITG") != P_MAX_INDEX) { H323Capability * cap; while ((cap = localCapabilities.FindCapability(H323Capability::e_UserInput, UINT_MAX)) != NULL) localCapabilities.Remove(cap); }}BOOL H323Connection::OnReceivedCallProceeding(const H323SignalPDU & pdu){ const H225_CallProceeding_UUIE & call = pdu.m_h323_uu_pdu.m_h323_message_body; SetRemotePartyInfo(pdu); SetRemoteApplication(call.m_destinationInfo); // Check for fastStart data and start fast if (call.HasOptionalField(H225_CallProceeding_UUIE::e_fastStart)) HandleFastStartAcknowledge(call.m_fastStart); // Check that it has the H.245 channel connection info if (call.HasOptionalField(H225_CallProceeding_UUIE::e_h245Address)) return StartControlChannel(call.m_h245Address); return TRUE;}BOOL H323Connection::OnReceivedAlerting(const H323SignalPDU & pdu){ const H225_Alerting_UUIE & alert = pdu.m_h323_uu_pdu.m_h323_message_body; SetRemotePartyInfo(pdu); SetRemoteApplication(alert.m_destinationInfo); // Check for fastStart data and start fast if (alert.HasOptionalField(H225_Alerting_UUIE::e_fastStart)) HandleFastStartAcknowledge(alert.m_fastStart); // Check that it has the H.245 channel connection info if (alert.HasOptionalField(H225_Alerting_UUIE::e_h245Address)) if (!StartControlChannel(alert.m_h245Address)) return FALSE; return OnAlerting(pdu, remotePartyName);}BOOL H323Connection::OnReceivedSignalConnect(const H323SignalPDU & pdu){ if (connectionState == ShuttingDownConnection) return FALSE; connectionState = HasExecutedSignalConnect; const H225_Connect_UUIE & connect = pdu.m_h323_uu_pdu.m_h323_message_body; SetRemotePartyInfo(pdu); SetRemoteApplication(connect.m_destinationInfo); if (!OnOutgoingCall(pdu)) { ClearCall(EndedByNoAccept); return FALSE; } // have answer, so set timeout to interval for pinging remote signallingChannel->SetReadTimeout(endpoint.GetRoundTripDelayRate()); // Check for fastStart data and start fast if (connect.HasOptionalField(H225_Connect_UUIE::e_fastStart)) HandleFastStartAcknowledge(connect.m_fastStart); // Check that it has the H.245 channel connection info if (connect.HasOptionalField(H225_Connect_UUIE::e_h245Address)) if (!StartControlChannel(connect.m_h245Address)) if (fastStartState != FastStartAcknowledged) return FALSE; // Fast started some channels, so we are connected straight away if (fastStartState == FastStartAcknowledged) { fastStartState = FastStartDisabled; connectionState = EstablishedConnection; connectionStartTime = PTime(); endpoint.OnConnectionEstablished(*this, callToken); return TRUE; } // Abandon fast start, if were attempting to do it though we need // to do capabilty exchange later fastStartState = FastStartDisabled; BOOL needsCapabilityExchange = fastStartChannels.GetSize() > 0; fastStartChannels.RemoveAll(); if (!h245Tunneling && controlChannel == NULL) { PTRACE(2, "H225\tNo H245 address in remote PDU"); return FALSE; } // Tried to do fast start and was refused. But are using h245 tunnelling // so need to initiate a capability exchange which we hadn't before as we
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -