ast_h323.cxx

来自「asterisk 是一个很有知名度开源软件」· CXX 代码 · 共 2,064 行 · 第 1/5 页

CXX
2,064
字号
}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[0];//				on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)dtmfCodec[0]);#ifdef PTRACING				if (h323debug) {					cout << "\t-- Receiving RFC2833 on payload " <<						atec.m_dynamicRTPPayloadType << endl;				}#endif			}		}	}}void MyH323Connection::OnSetLocalCapabilities(){	if (on_setcapabilities)		on_setcapabilities(GetCallReference(), (const char *)callToken);}BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCaps,							const H245_MultiplexCapability * muxCap,							H245_TerminalCapabilitySetReject & reject){	struct __codec__ {		unsigned int asterisk_codec;		unsigned int h245_cap;		const char *oid;		const char *formatName;	};	static const struct __codec__ codecs[] = {		{ AST_FORMAT_G723_1, H245_AudioCapability::e_g7231 },		{ AST_FORMAT_GSM, H245_AudioCapability::e_gsmFullRate },		{ AST_FORMAT_ULAW, H245_AudioCapability::e_g711Ulaw64k },		{ AST_FORMAT_ALAW, H245_AudioCapability::e_g711Alaw64k },		{ AST_FORMAT_G729A, H245_AudioCapability::e_g729AnnexA },		{ AST_FORMAT_G729A, H245_AudioCapability::e_g729 },		{ AST_FORMAT_G726_AAL2, H245_AudioCapability::e_nonStandard, NULL, CISCO_G726r32 },#ifdef AST_FORMAT_MODEM		{ AST_FORMAT_MODEM, H245_DataApplicationCapability_application::e_t38fax },#endif		{ 0 }	};#if 0	static const struct __codec__ vcodecs[] = {#ifdef HAVE_H261		{ AST_FORMAT_H261, H245_VideoCapability::e_h261VideoCapability },#endif#ifdef HAVE_H263		{ AST_FORMAT_H263, H245_VideoCapability::e_h263VideoCapability },#endif#ifdef HAVE_H264		{ AST_FORMAT_H264, H245_VideoCapability::e_genericVideoCapability, "0.0.8.241.0.0.1" },#endif		{ 0 }	};#endif	struct ast_codec_pref prefs;	RTP_DataFrame::PayloadTypes pt;	if (!H323Connection::OnReceivedCapabilitySet(remoteCaps, muxCap, reject)) {		return FALSE;	}	memset(&prefs, 0, sizeof(prefs));	int peer_capabilities = 0;	for (int i = 0; i < remoteCapabilities.GetSize(); ++i) {		unsigned int subType = remoteCapabilities[i].GetSubType();		if (h323debug) {			cout << "Peer capability is " << remoteCapabilities[i] << endl;		}		switch(remoteCapabilities[i].GetMainType()) {		case H323Capability::e_Audio:			for (int x = 0; codecs[x].asterisk_codec > 0; ++x) {				if ((subType == codecs[x].h245_cap) && (!codecs[x].formatName || (!strcmp(codecs[x].formatName, (const char *)remoteCapabilities[i].GetFormatName())))) {					int ast_codec = codecs[x].asterisk_codec;					int ms = 0;					if (!(peer_capabilities & ast_codec)) {						struct ast_format_list format;						ast_codec_pref_append(&prefs, ast_codec);						format = ast_codec_pref_getsize(&prefs, ast_codec);						if ((ast_codec == AST_FORMAT_ALAW) || (ast_codec == AST_FORMAT_ULAW)) {							ms = remoteCapabilities[i].GetTxFramesInPacket();							if (ms > 60)								ms = format.cur_ms;						} else							ms = remoteCapabilities[i].GetTxFramesInPacket() * format.inc_ms;						ast_codec_pref_setsize(&prefs, ast_codec, ms);					}					if (h323debug) {						cout << "Found peer capability " << remoteCapabilities[i] << ", Asterisk code is " << ast_codec << ", frame size (in ms) is " << ms << endl;					}					peer_capabilities |= ast_codec;				}			}			break;		case H323Capability::e_Data:			if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), CISCO_DTMF_RELAY)) {				pt = remoteCapabilities[i].GetPayloadType();				if ((dtmfMode & H323_DTMF_CISCO) != 0) {					on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 1);//					if (sendUserInputMode == SendUserInputAsTone)//						sendUserInputMode = SendUserInputAsInlineRFC2833;				}#ifdef PTRACING				if (h323debug) {					cout << "\t-- Outbound Cisco RTP DTMF on payload " << pt << endl;				}#endif			}			break;		case H323Capability::e_UserInput:			if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), H323_UserInputCapability::SubTypeNames[H323_UserInputCapability::SignalToneRFC2833])) {				pt = remoteCapabilities[i].GetPayloadType();				if ((dtmfMode & H323_DTMF_RFC2833) != 0) {					on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 0);//					if (sendUserInputMode == SendUserInputAsTone)//						sendUserInputMode = SendUserInputAsInlineRFC2833;				}#ifdef PTRACING				if (h323debug) {					cout << "\t-- Outbound RFC2833 on payload " << pt << endl;				}#endif			}			break;#if 0		case H323Capability::e_Video:			for (int x = 0; vcodecs[x].asterisk_codec > 0; ++x) {				if (subType == vcodecs[x].h245_cap) {					H245_CapabilityIdentifier *cap = NULL;					H245_GenericCapability y;					if (vcodecs[x].oid) {						cap = new H245_CapabilityIdentifier(H245_CapabilityIdentifier::e_standard);						PASN_ObjectId &object_id = *cap;						object_id = vcodecs[x].oid;						y.m_capabilityIdentifier = *cap;					}					if ((subType != H245_VideoCapability::e_genericVideoCapability) ||							(vcodecs[x].oid && ((const H323GenericVideoCapability &)remoteCapabilities[i]).IsGenericMatch((const H245_GenericCapability)y))) {						if (h323debug) {							cout << "Found peer video capability " << remoteCapabilities[i] << ", Asterisk code is " << vcodecs[x].asterisk_codec << endl;						}						peer_capabilities |= vcodecs[x].asterisk_codec;					}					if (cap)						delete(cap);				}			}			break;#endif		default:			break;		}	}	if (h323debug) {		char caps_str[1024], caps2_str[1024];		ast_codec_pref_string(&prefs, caps2_str, sizeof(caps2_str));		cout << "Peer capabilities = " << ast_getformatname_multiple(caps_str, sizeof(caps_str), peer_capabilities)				<< ", ordered list is " << caps2_str << endl;	}#if 0	redir_capabilities &= peer_capabilities;#endif	if (on_setpeercapabilities)		on_setpeercapabilities(GetCallReference(), (const char *)callToken, peer_capabilities, &prefs);	return TRUE;}H323Channel * MyH323Connection::CreateRealTimeLogicalChannel(const H323Capability & capability,									H323Channel::Directions dir,									unsigned sessionID,									const H245_H2250LogicalChannelParameters * /*param*/,									RTP_QOS * /*param*/ ){	/* Do not open tx channel when transmitter has been paused by empty TCS */	if ((dir == H323Channel::IsTransmitter) && transmitterSidePaused)		return NULL;	return new MyH323_ExternalRTPChannel(*this, capability, dir, sessionID);}/** This callback function is invoked once upon creation of each  * channel for an H323 session  */BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel){	/* Increase the count of channels we have open */	channelsOpen++;	if (h323debug) {		cout << "\t-- Started logical channel: "				<< ((channel.GetDirection() == H323Channel::IsTransmitter) ? "sending " : ((channel.GetDirection() == H323Channel::IsReceiver) ? "receiving " : " "))				<< (const char *)(channel.GetCapability()).GetFormatName() << endl;		cout << "\t\t-- channelsOpen = " << channelsOpen << endl;	}	return connectionState != ShuttingDownConnection;}void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, int pref_codec){	PINDEX lastcap = -1; /* last common capability index */	int alreadysent = 0;	int codec;	int x, y;	char caps_str[1024];	struct ast_codec_pref *prefs = (struct ast_codec_pref *)_prefs;	struct ast_format_list format;	int frames_per_packet;	int max_frames_per_packet;	H323Capability *cap;	localCapabilities.RemoveAll();	if (h323debug) {		cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), caps) << endl;		ast_codec_pref_string(prefs, caps_str, sizeof(caps_str));		cout << "Capabilities in preference order is " << caps_str << endl;	}	/* Add audio codecs in preference order first, then	   audio codecs without preference as allowed by mask */	for (y = 0, x = -1; x < 32 + 32; ++x) {		if (x < 0)			codec = pref_codec;		else if (y || (!(codec = ast_codec_pref_index(prefs, x)))) {			if (!y)				y = 1;			else				y <<= 1;			codec = y;		}		if (!(caps & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK))			continue;		alreadysent |= codec;		format = ast_codec_pref_getsize(prefs, codec);		frames_per_packet = (format.inc_ms ? format.cur_ms / format.inc_ms : format.cur_ms);		max_frames_per_packet = (format.inc_ms ? format.max_ms / format.inc_ms : 0);		switch(codec) {#if 0		case AST_FORMAT_SPEEX:			/* Not real sure if Asterisk acutally supports all			   of the various different bit rates so add them			   all and figure it out later*/			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow2AudioCapability());			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow3AudioCapability());			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow4AudioCapability());			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow5AudioCapability());			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow6AudioCapability());			break;#endif		case AST_FORMAT_G729A:			AST_G729ACapability *g729aCap;			AST_G729Capability *g729Cap;			lastcap = localCapabilities.SetCapability(0, 0, g729aCap = new AST_G729ACapability(frames_per_packet));			lastcap = localCapabilities.SetCapability(0, 0, g729Cap = new AST_G729Capability(frames_per_packet));			if (max_frames_per_packet) {				g729aCap->SetTxFramesInPacket(max_frames_per_packet);				g729Cap->SetTxFramesInPacket(max_frames_per_packet);			}			break;		case AST_FORMAT_G723_1:			AST_G7231Capability *g7231Cap;			lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, TRUE));			if (max_frames_per_packet)				g7231Cap->SetTxFramesInPacket(max_frames_per_packet);			lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, FALSE));			if (max_frames_per_packet)				g7231Cap->SetTxFramesInPacket(max_frames_per_packet);			break;		case AST_FORMAT_GSM:			AST_GSM0610Capability *gsmCap;			lastcap = localCapabilities.SetCapability(0, 0, gsmCap = new AST_GSM0610Capability(frames_per_packet));			if (max_frames_per_packet)				gsmCap->SetTxFramesInPacket(max_frames_per_packet);			break;		case AST_FORMAT_ULAW:			AST_G711Capability *g711uCap;			lastcap = localCapabilities.SetCapability(0, 0, g711uCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::muLaw));			if (format.max_ms)				g711uCap->SetTxFramesInPacket(format.max_ms);			break;		case AST_FORMAT_ALAW:			AST_G711Capability *g711aCap;			lastcap = localCapabilities.SetCapability(0, 0, g711aCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::ALaw));			if (format.max_ms)				g711aCap->SetTxFramesInPacket(format.max_ms);			break;		case AST_FORMAT_G726_AAL2:			AST_CiscoG726Capability *g726Cap;			lastcap = localCapabilities.SetCapability(0, 0, g726Cap = new AST_CiscoG726Capability(frames_per_packet));			if (max_frames_per_packet)				g726Cap->SetTxFramesInPacket(max_frames_per_packet);			break;		default:			alreadysent &= ~codec;			break;		}	}	cap = new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245);	if (cap && cap->IsUsable(*this)) {		lastcap++;		lastcap = localCapabilities.SetCapability(0, lastcap, cap);	} else if (cap)		delete cap;				/* Capability is not usable */	dtmfMode = dtmf_mode;	if (h323debug) {		cout << "DTMF mode is " << (int)dtmfMode << endl;	}	if (dtmfMode) {		lastcap++;		if (dtmfMode == H323_DTMF_INBAND) {			cap = new H323_UserInputCapability(H323_UserInputCapability::BasicString);			if (cap && cap->IsUsable(*this)) {				lastcap = localCapabilities.SetCapability(0, lastcap, cap);			} else if (cap)				delete cap;		/* Capability is not usable */			sendUserInputMode = SendUserInputAsString;		} else {			if ((dtmfMode & H323_DTMF_RFC2833) != 0) {				cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833);				if (cap && cap->IsUsable(*this))					lastcap = localCapabilities.SetCapability(0, lastcap, cap);				else {					dtmfMode |= H323_DTMF_SIGNAL;					if (cap)						delete cap;	/* Capability is not usable */				}			}			if ((dtmfMode & H323_DTMF_CISCO) != 0) {				/* Try Cisco's RTP DTMF relay too, but prefer RFC2833 or h245-signal */				cap = new AST_CiscoDtmfCapability();				if (cap && cap->IsUsable(*this)) {					lastcap = localCapabilities.SetCapability(0, lastcap, cap);					/* We cannot send Cisco RTP DTMFs, use h245-signal instead */					dtmfMode |= H323_DTMF_SIGNAL;				} else {					dtmfMode |= H323_DTMF_SIGNAL;					if (cap)						delete cap;	/* Capability is not usable */				}			}			if ((dtmfMode & H323_DTMF_SIGNAL) != 0) {				/* Cisco usually sends DTMF correctly only through h245-alphanumeric or h245-signal */				cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245);				if (cap && cap->IsUsable(*this))					lastcap = localCapabilities.SetCapability(0, lastcap, cap);				else if (cap)					delete cap;	/* Capability is not usable */			}			sendUserInputMode = SendUserInputAsTone;	/* RFC2833 transmission handled at Asterisk level */		}	}	if (h323debug) {		cout << "Allowed Codecs for " << GetCallToken() << " (" << GetSignallingChannel()->GetLocalAddress() << "):\n\t" << setprecision(2) << localCapabilities << endl;	}}BOOL MyH323Connection::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#if P_HAS_IPV6		&& h245Address.GetTag() != H225_TransportAddress::e_ip6Address#endif	) {		PTRACE(1, "H225\tConnect of H245 failed: Unsupported transport");		return FALSE;	}	// Already have the H245 channel up.	if (controlChannel != NULL)		return TRUE;	PIPSocket::Address addr;	WORD port;	GetSignallingChannel()->GetLocalAddress().GetIpAndPort(addr, port);	if (addr) {		if (h323debug)			cout << "Using " << addr << " for outbound H.245 transport" << endl;		controlChannel = new MyH323TransportTCP(endpoint, addr);	} else		controlChannel = new H323TransportTCP(endpoint);	if (!controlChannel->Se

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?