⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ast_h323.cxx

📁 Asterisk中信道部分的源码 。。。。
💻 CXX
📖 第 1 页 / 共 5 页
字号:
				}#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;	};	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 },#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;	if (!H323Connection::OnReceivedCapabilitySet(remoteCaps, muxCap, reject)) {		return FALSE;	}	const H323Capability * cap = remoteCaps.FindCapability(H323_UserInputCapability::SubTypeNames[H323_UserInputCapability::SignalToneRFC2833]);	if (cap != NULL) {		RTP_DataFrame::PayloadTypes pt = ((H323_UserInputCapability*)cap)->GetPayloadType();		on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt);		if ((dtmfMode == H323_DTMF_RFC2833) && (sendUserInputMode == SendUserInputAsTone))			sendUserInputMode = SendUserInputAsInlineRFC2833;#ifdef PTRACING		if (h323debug) {			cout << "\t-- Inbound RFC2833 on payload " << pt << endl;		}#endif	}	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) {					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;#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 cap, 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;	localCapabilities.RemoveAll();	if (h323debug) {		cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), cap) << 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 if (y == AST_FORMAT_MAX_AUDIO)				break;			else				y <<= 1;			codec = y;		}		if (!(cap & 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;		default:			alreadysent &= ~codec;			break;		}	}	lastcap++;	lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245));	lastcap++;	dtmfMode = dtmf_mode;	if (dtmf_mode == H323_DTMF_INBAND) {		localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::BasicString));		sendUserInputMode = SendUserInputAsString;	} else {		lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833));		/* Cisco sends DTMF only through h245-alphanumeric or h245-signal, no support for RFC2833 */		lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245));		sendUserInputMode = SendUserInputAsTone;	/* RFC2833 transmission handled at Asterisk level */	}	if (h323debug) {		cout << "Allowed Codecs:\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->SetRemoteAddress(h245Address)) {		PTRACE(1, "H225\tCould not extract H245 address");		delete controlChannel;		controlChannel = NULL;		return FALSE;	}	if (!controlChannel->Connect()) {		PTRACE(1, "H225\tConnect of H245 failed: " << controlChannel->GetErrorText());		delete controlChannel;		controlChannel = NULL;		return FALSE;	}	controlChannel->StartControlChannel(*this);	return TRUE;}/* MyH323_ExternalRTPChannel */MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,							const H323Capability & capability,							Directions direction,							unsigned id)	: H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id){	struct rtp_info *info;	/* Determine the Local (A side) IP Address and port */	info = on_external_rtp_create(connection.GetCallReference(), (const char *)connection.GetCallToken());	if (!info) {		cout << "\tERROR: on_external_rtp_create failure" << endl;		return;	} else {		localIpAddr = info->addr;		localPort = info->port;		/* tell the H.323 stack */		SetExternalAddress(H323TransportAddress(localIpAddr, localPort), H323TransportAddress(localIpAddr, localPort + 1));		/* clean up allocated memory */		free(info);	}	/* Get the payload code	*/	OpalMediaFormat format(capability.GetFormatName(), FALSE);	payloadCode = format.GetPayloadType();}MyH323_ExternalRTPChannel::~MyH323_ExternalRTPChannel(){	if (h323debug) {		cout << "\tExternalRTPChannel Destroyed" << endl;	}}BOOL MyH323_ExternalRTPChannel::Start(void){	/* Call ancestor first */	if (!H323_ExternalRTPChannel::Start()) {		return FALSE;	}	if (h323debug) {		cout << "\t\tExternal RTP Session Starting" << endl;		cout << "\t\tRTP channel id " << sessionID << " parameters:" << endl;	}	/* Collect the remote information */	H323_ExternalRTPChannel::GetRemoteAddress(remoteIpAddr, remotePort);	if (h323debug) {		cout << "\t\t-- remoteIpAddress: " << remoteIpAddr << endl;		cout << "\t\t-- remotePort: " << remotePort << endl;		cout << "\t\t-- ExternalIpAddress: " << localIpAddr << endl;		cout << "\t\t-- ExternalPort: " << localPort << endl;	}	/* Notify Asterisk of remote RTP information */	on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(), remotePort,		(const char *)connection.GetCallToken(), (int)payloadCode);	return TRUE;}BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param){	if (h323debug) {		cout << "	MyH323_ExternalRTPChannel::OnReceivedAckPDU" << endl;	}	if (H323_ExternalRTPChannel::OnReceivedAckPDU(param)) {		GetRemoteAddress(remoteIpAddr, remotePort);		if (h323debug) {			cout << "		-- remoteIpAddress: " << remoteIpAddr << endl;			cout << "		-- remotePort: " << remotePort << endl;		}		on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(),				remotePort, (const char *)connection.GetCallToken(), (int)payloadCode);		return TRUE;	}	return FALSE;}/** IMPLEMENTATION O

⌨️ 快捷键说明

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