[asterisk-commits] pcadach: trunk r44024 - in /trunk: ./ channels/h323/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Sep 29 12:13:26 MST 2006


Author: pcadach
Date: Fri Sep 29 14:13:26 2006
New Revision: 44024

URL: http://svn.digium.com/view/asterisk?rev=44024&view=rev
Log:
Merged revisions 44022 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r44022 | pcadach | 2006-09-30 01:06:55 +0600 (Сбт, 30 Сен 2006) | 3 lines

Properly pass TON/PRESENTATION information - original
H323Connection::SendSignalSetup() destroys Q.931 fields.

........

Modified:
    trunk/   (props changed)
    trunk/channels/h323/ast_h323.cxx
    trunk/channels/h323/ast_h323.h

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/channels/h323/ast_h323.cxx
URL: http://svn.digium.com/view/asterisk/trunk/channels/h323/ast_h323.cxx?rev=44024&r1=44023&r2=44024&view=diff
==============================================================================
--- trunk/channels/h323/ast_h323.cxx (original)
+++ trunk/channels/h323/ast_h323.cxx Fri Sep 29 14:13:26 2006
@@ -923,7 +923,7 @@
 	} codes[] = {
 		{ Q931::RedirectingNumberIE, },
 		{ Q931::FacilityIE, },
-		{ Q931::CallingPartyNumberIE, TRUE },
+//		{ Q931::CallingPartyNumberIE, TRUE },
 	};
 
 	BOOL res = FALSE;
@@ -1231,6 +1231,7 @@
 	   by embedding routines */
 	setupPDU.GetQ931().SetCallingPartyNumber(GetLocalPartyName(), (cid_ton >> 4) & 0x07,
 			cid_ton & 0x0f, (cid_presentation >> 5) & 0x03, cid_presentation & 0x1f);
+	setupPDU.GetQ931().SetDisplayName(GetDisplayName());
 
 #ifdef TUNNELLING
 	EmbedTunneledInfo(setupPDU);
@@ -1238,6 +1239,311 @@
 
 	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)
 {

Modified: trunk/channels/h323/ast_h323.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/h323/ast_h323.h?rev=44024&r1=44023&r2=44024&view=diff
==============================================================================
--- trunk/channels/h323/ast_h323.h (original)
+++ trunk/channels/h323/ast_h323.h Fri Sep 29 14:13:26 2006
@@ -90,6 +90,7 @@
 	virtual BOOL StartControlChannel(const H225_TransportAddress & h245Address);
 	void SetCallOptions(void *opts, BOOL isIncoming);
 	void SetCallDetails(void *callDetails, const H323SignalPDU &setupPDU, BOOL isIncoming);
+	virtual H323Connection::CallEndReason SendSignalSetup(const PString&, const H323TransportAddress&);
 #ifdef TUNNELLING
 	virtual BOOL HandleSignalPDU(H323SignalPDU &pdu);
 	BOOL EmbedTunneledInfo(H323SignalPDU &pdu);



More information about the asterisk-commits mailing list