📄 ast_h323.cxx
字号:
if (h323debug) { cout << "\t-- Call Failed" << endl; } return FALSE; } /* OpenH323 will build calling party information with default type and presentation information, so build it to be recorded by embedding routines */ setupPDU.GetQ931().SetCallingPartyNumber(sourceE164, (cid_ton >> 4) & 0x07, cid_ton & 0x0f, (cid_presentation >> 5) & 0x03, cid_presentation & 0x1f); setupPDU.GetQ931().SetDisplayName(GetDisplayName());#ifdef TUNNELLING EmbedTunneledInfo(setupPDU);#endif return H323Connection::OnSendSignalSetup(setupPDU);}static BOOL BuildFastStartList(const H323Channel & channel, H225_ArrayOf_PASN_OctetString & array, H323Channel::Directions reverseDirection){ H245_OpenLogicalChannel open; const H323Capability & capability = channel.GetCapability(); if (channel.GetDirection() != reverseDirection) { if (!capability.OnSendingPDU(open.m_forwardLogicalChannelParameters.m_dataType)) return FALSE; } else { if (!capability.OnSendingPDU(open.m_reverseLogicalChannelParameters.m_dataType)) return FALSE; open.m_forwardLogicalChannelParameters.m_multiplexParameters.SetTag( H245_OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters::e_none); open.m_forwardLogicalChannelParameters.m_dataType.SetTag(H245_DataType::e_nullData); open.IncludeOptionalField(H245_OpenLogicalChannel::e_reverseLogicalChannelParameters); } if (!channel.OnSendingPDU(open)) return FALSE; PTRACE(4, "H225\tBuild fastStart:\n " << setprecision(2) << open); PINDEX last = array.GetSize(); array.SetSize(last+1); array[last].EncodeSubType(open); PTRACE(3, "H225\tBuilt fastStart for " << capability); return TRUE;}H323Connection::CallEndReason MyH323Connection::SendSignalSetup(const PString & alias, const H323TransportAddress & address){ // Start the call, first state is asking gatekeeper connectionState = AwaitingGatekeeperAdmission; // Indicate the direction of call. 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, address);#ifdef H323_H450 h450dispatcher->AttachToSetup(setupPDU);#endif // Save the identifiers generated by BuildSetup setupPDU.GetQ931().GetCalledPartyNumber(remotePartyNumber); H323TransportAddress gatekeeperRoute = address; // Check for gatekeeper and do admission check if have one H323Gatekeeper * gatekeeper = endpoint.GetGatekeeper(); H225_ArrayOf_AliasAddress newAliasAddresses; if (gatekeeper != NULL) { H323Gatekeeper::AdmissionResponse response; response.transportAddress = &gatekeeperRoute; response.aliasAddresses = &newAliasAddresses; if (!gkAccessTokenOID) response.accessTokenData = &gkAccessTokenData; while (!gatekeeper->AdmissionRequest(*this, response, alias.IsEmpty())) { PTRACE(1, "H225\tGatekeeper refused admission: " << (response.rejectReason == UINT_MAX ? PString("Transport error") : H225_AdmissionRejectReason(response.rejectReason).GetTagName()));#ifdef H323_H450 h4502handler->onReceivedAdmissionReject(H4501_GeneralErrorList::e_notAvailable);#endif switch (response.rejectReason) { case H225_AdmissionRejectReason::e_calledPartyNotRegistered: return EndedByNoUser; case H225_AdmissionRejectReason::e_requestDenied: return EndedByNoBandwidth; case H225_AdmissionRejectReason::e_invalidPermission: case H225_AdmissionRejectReason::e_securityDenial: return EndedBySecurityDenial; case H225_AdmissionRejectReason::e_resourceUnavailable: return EndedByRemoteBusy; case H225_AdmissionRejectReason::e_incompleteAddress: if (OnInsufficientDigits()) break; // Then default case default: return EndedByGatekeeper; } PString lastRemotePartyName = remotePartyName; while (lastRemotePartyName == remotePartyName) { Unlock(); // Release the mutex as can deadlock trying to clear call during connect. digitsWaitFlag.Wait(); if (!Lock()) // Lock while checking for shutting down. return EndedByCallerAbort; } } mustSendDRQ = TRUE; if (response.gatekeeperRouted) { setup.IncludeOptionalField(H225_Setup_UUIE::e_endpointIdentifier); setup.m_endpointIdentifier = gatekeeper->GetEndpointIdentifier(); gatekeeperRouted = TRUE; } }#ifdef H323_TRANSNEXUS_OSP // check for OSP server (if not using GK) if (gatekeeper == NULL) { OpalOSP::Provider * ospProvider = endpoint.GetOSPProvider(); if (ospProvider != NULL) { OpalOSP::Transaction * transaction = new OpalOSP::Transaction(); if (transaction->Open(*ospProvider) != 0) { PTRACE(1, "H225\tCannot create OSP transaction"); return EndedByOSPRefusal; } OpalOSP::Transaction::DestinationInfo destInfo; if (!AuthoriseOSPTransaction(*transaction, destInfo)) { delete transaction; return EndedByOSPRefusal; } // save the transaction for use by the call ospTransaction = transaction; // retreive the call information gatekeeperRoute = destInfo.destinationAddress; newAliasAddresses.Append(new H225_AliasAddress(destInfo.calledNumber)); // insert the token setup.IncludeOptionalField(H225_Setup_UUIE::e_tokens); destInfo.InsertToken(setup.m_tokens); } }#endif // Update the field e_destinationAddress in the SETUP PDU to reflect the new // alias received in the ACF (m_destinationInfo). if (newAliasAddresses.GetSize() > 0) { setup.IncludeOptionalField(H225_Setup_UUIE::e_destinationAddress); setup.m_destinationAddress = newAliasAddresses; // Update the Q.931 Information Element (if is an E.164 address) PString e164 = H323GetAliasAddressE164(newAliasAddresses); if (!e164) remotePartyNumber = e164; } if (addAccessTokenToSetup && !gkAccessTokenOID && !gkAccessTokenData.IsEmpty()) { PString oid1, oid2; PINDEX comma = gkAccessTokenOID.Find(','); if (comma == P_MAX_INDEX) oid1 = oid2 = gkAccessTokenOID; else { oid1 = gkAccessTokenOID.Left(comma); oid2 = gkAccessTokenOID.Mid(comma+1); } setup.IncludeOptionalField(H225_Setup_UUIE::e_tokens); PINDEX last = setup.m_tokens.GetSize(); setup.m_tokens.SetSize(last+1); setup.m_tokens[last].m_tokenOID = oid1; setup.m_tokens[last].IncludeOptionalField(H235_ClearToken::e_nonStandard); setup.m_tokens[last].m_nonStandard.m_nonStandardIdentifier = oid2; setup.m_tokens[last].m_nonStandard.m_data = gkAccessTokenData; } 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; // Release the mutex as can deadlock trying to clear call during connect. Unlock(); signallingChannel->SetWriteTimeout(100); BOOL connectFailed = !signallingChannel->Connect(); // Lock while checking for shutting down. if (!Lock()) return EndedByCallerAbort; // See if transport connect failed, abort if so. if (connectFailed) { connectionState = NoConnectionActive; switch (signallingChannel->GetErrorNumber()) { case ENETUNREACH : return EndedByUnreachable; case ECONNREFUSED : return EndedByNoEndPoint; case ETIMEDOUT : return EndedByHostOffline; } 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); if (!setup.HasOptionalField(H225_Setup_UUIE::e_destCallSignalAddress)) { setup.IncludeOptionalField(H225_Setup_UUIE::e_destCallSignalAddress); signallingChannel->SetUpTransportPDU(setup.m_destCallSignalAddress, FALSE); } // If a standard call do Fast Start (if required) if (setup.m_conferenceGoal.GetTag() == H225_Setup_UUIE_conferenceGoal::e_create) { // Get the local capabilities before fast start is handled OnSetLocalCapabilities(); // Ask the application what channels to open PTRACE(3, "H225\tCheck for Fast start by local endpoint"); 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); } // Search the capability set and see if we have video capability for (PINDEX i = 0; i < localCapabilities.GetSize(); i++) { switch (localCapabilities[i].GetMainType()) { case H323Capability::e_Audio: case H323Capability::e_UserInput: break; default: // Is video or other data (eg T.120) setupPDU.GetQ931().SetBearerCapabilities(Q931::TransferUnrestrictedDigital, 6); i = localCapabilities.GetSize(); // Break out of the for loop break; } } } if (!OnSendSignalSetup(setupPDU)) return EndedByNoAccept; // Do this again (was done when PDU was constructed) in case // OnSendSignalSetup() changed something.// setupPDU.SetQ931Fields(*this, TRUE); setupPDU.GetQ931().GetCalledPartyNumber(remotePartyNumber); fastStartState = FastStartDisabled; BOOL set_lastPDUWasH245inSETUP = FALSE; if (h245Tunneling && doH245inSETUP) { h245TunnelTxPDU = &setupPDU; // Try and start the master/slave and capability exchange through the tunnel // Note: this used to be disallowed but is now allowed as of H323v4 BOOL ok = StartControlNegotiations(); h245TunnelTxPDU = NULL; if (!ok) return EndedByTransportFail; if (setup.m_fastStart.GetSize() > 0) { // Now if fast start as well need to put this in setup specific field // and not the generic H.245 tunneling field setup.IncludeOptionalField(H225_Setup_UUIE::e_parallelH245Control); setup.m_parallelH245Control = setupPDU.m_h323_uu_pdu.m_h245Control; setupPDU.m_h323_uu_pdu.RemoveOptionalField(H225_H323_UU_PDU::e_h245Control); set_lastPDUWasH245inSETUP = TRUE; } } // Send the initial PDU setupTime = PTime(); if (!WriteSignalPDU(setupPDU)) return EndedByTransportFail; // WriteSignalPDU always resets lastPDUWasH245inSETUP. // So set it here if required if (set_lastPDUWasH245inSETUP) lastPDUWasH245inSETUP = TRUE; // Set timeout for remote party to answer the call signallingChannel->SetReadTimeout(endpoint.GetSignallingChannelCallTimeout()); return NumCallEndReasons;}BOOL MyH323Connection::OnSendReleaseComplete(H323SignalPDU & releaseCompletePDU){ if (h323debug) { cout << "\t-- Sending RELEASE COMPLETE" << endl; } if (cause > 0) releaseCompletePDU.GetQ931().SetCause((Q931::CauseValues)cause);#ifdef TUNNELLING EmbedTunneledInfo(releaseCompletePDU);#endif return H323Connection::OnSendReleaseComplete(releaseCompletePDU);}BOOL MyH323Connection::OnReceivedFacility(const H323SignalPDU & pdu){ if (h323debug) { cout << "\t-- Received Facility message... " << endl; } return H323Connection::OnReceivedFacility(pdu);}void MyH323Connection::OnReceivedReleaseComplete(const H323SignalPDU & pdu){ if (h323debug) { cout << "\t-- Received RELEASE COMPLETE message..." << endl; } if (on_hangup) on_hangup(GetCallReference(), (const char *)GetCallToken(), pdu.GetQ931().GetCause()); return H323Connection::OnReceivedReleaseComplete(pdu);}BOOL MyH323Connection::OnClosingLogicalChannel(H323Channel & channel){ if (h323debug) { cout << "\t-- Closing logical channel..." << endl; } return H323Connection::OnClosingLogicalChannel(channel);}void MyH323Connection::SendUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp){ SendUserInputModes mode = GetRealSendUserInputMode();// That is recursive call... Why?// on_receive_digit(GetCallReference(), tone, (const char *)GetCallToken()); if ((tone != ' ') || (mode == SendUserInputAsTone) || (mode == SendUserInputAsInlineRFC2833)) { if (h323debug) { cout << "\t-- Sending user input tone (" << tone << ") to remote" << endl; } H323Connection::SendUserInputTone(tone, duration); }}void MyH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp){ if (dtmfMode == H323_DTMF_RFC2833) { if (h323debug) { cout << "\t-- Received user input tone (" << tone << ") from remote" << endl; } on_receive_digit(GetCallReference(), tone, (const char *)GetCallToken(), duration); }}void MyH323Connection::OnUserInputString(const PString &value){ if (h323debug) { cout << "\t-- Received user input string (" << value << ") from remote." << endl; } on_receive_digit(GetCallReference(), value[0], (const char *)GetCallToken(), 0);}void MyH323Connection::OnSendCapabilitySet(H245_TerminalCapabilitySet & pdu){ PINDEX i; H323Connection::OnSendCapabilitySet(pdu); H245_ArrayOf_CapabilityTableEntry & tables = pdu.m_capabilityTable; for(i = 0; i < tables.GetSize(); i++) { H245_CapabilityTableEntry & entry = tables[i]; if (entry.HasOptionalField(H245_CapabilityTableEntry::e_capability)) { H245_Capability & cap = entry.m_capability; if (cap.GetTag() == H245_Capability::e_receiveRTPAudioTelephonyEventCapability) { H245_AudioTelephonyEventCapability & atec = cap; atec.m_dynamicRTPPayloadType = dtmfCodec;// on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)dtmfCodec);#ifdef PTRACING if (h323debug) { cout << "\t-- Transmitting RFC2833 on payload " << atec.m_dynamicRTPPayloadType << endl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -