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

📄 ast_h323.cxx

📁 asterisk 是一个很有知名度开源软件
💻 CXX
📖 第 1 页 / 共 5 页
字号:
#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif/* * ast_h323.cpp * * OpenH323 Channel Driver for ASTERISK PBX. *			By  Jeremy McNamara *			For The NuFone Network * * chan_h323 has been derived from code created by *               Michael Manousos and Mark Spencer * * This file is part of the chan_h323 driver for Asterisk * * chan_h323 is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * chan_h323 is distributed WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Version Info: $Id: ast_h323.cxx 129046 2008-07-08 16:41:31Z bbryant $ */#include <arpa/inet.h>#include <list>#include <string>#include <algorithm>#include <ptlib.h>#include <h323.h>#include <h323pdu.h>#include <h323neg.h>#include <mediafmt.h>#include <lid.h>#ifdef H323_H450#include "h4501.h"#include "h4504.h"#include "h45011.h"#include "h450pdu.h"#endif#ifdef __cplusplusextern "C" {#endif#include "asterisk/compat.h"#include "asterisk/logger.h"#include "asterisk/channel.h"#include "asterisk/astobj.h"#ifdef __cplusplus}#endif#include "chan_h323.h"#include "ast_h323.h"#include "cisco-h225.h"#include "caps_h323.h"#include <ptbuildopts.h>#if PWLIB_MAJOR * 10000 + PWLIB_MINOR * 100 + PWLIB_BUILD >= 1 * 10000 + 12 * 100 + 0#define SKIP_PWLIB_PIPE_BUG_WORKAROUND 1#endif/* PWlib Required Components  */#define MAJOR_VERSION 1#define MINOR_VERSION 0#define BUILD_TYPE    ReleaseCode#define BUILD_NUMBER  0/** Counter for the number of connections */static int channelsOpen;/** * We assume that only one endPoint should exist. * The application cannot run the h323_end_point_create() more than once * FIXME: Singleton this, for safety */static MyH323EndPoint *endPoint = NULL;/** PWLib entry point */static MyProcess *localProcess = NULL;#ifndef SKIP_PWLIB_PIPE_BUG_WORKAROUNDstatic int _timerChangePipe[2];#endifstatic unsigned traceOptions = PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine;class PAsteriskLog : public PObject, public iostream {	PCLASSINFO(PAsteriskLog, PObject);	public:	PAsteriskLog() : iostream(cout.rdbuf()) { init(&buffer); }	~PAsteriskLog() { flush(); }	private:	PAsteriskLog(const PAsteriskLog &) : iostream(cout.rdbuf()) { }	PAsteriskLog & operator=(const PAsteriskLog &) { return *this; }	class Buffer : public streambuf {		public:		virtual int overflow(int=EOF);		virtual int underflow();		virtual int sync();		PString string;	} buffer;	friend class Buffer;};static PAsteriskLog *logstream = NULL;int PAsteriskLog::Buffer::overflow(int c){	if (pptr() >= epptr()) {		int ppos = pptr() - pbase();		char *newptr = string.GetPointer(string.GetSize() + 2000);		setp(newptr, newptr + string.GetSize() - 1);		pbump(ppos);	}	if (c != EOF) {		*pptr() = (char)c;		pbump(1);	}	return 0;}int PAsteriskLog::Buffer::underflow(){	return EOF;}int PAsteriskLog::Buffer::sync(){	char *str = strdup(string);	char *s, *s1;	char c;	/* Pass each line with different ast_verbose() call */	for (s = str; s && *s; s = s1) {		s1 = strchr(s, '\n');		if (!s1)			s1 = s + strlen(s);		else			s1++;		c = *s1;		*s1 = '\0';		ast_verbose("%s", s);		*s1 = c;	}	free(str);	string = PString();	char *base = string.GetPointer(2000);	setp(base, base + string.GetSize() - 1);	return 0;}static ostream &my_endl(ostream &os){	if (logstream) {		PTrace::SetOptions(traceOptions);		return PTrace::End(os);	}	return endl(os);}#define cout \	(logstream ? (PTrace::ClearOptions((unsigned)-1), PTrace::Begin(0, __FILE__, __LINE__)) : std::cout)#define endl my_endl/* Special class designed to call cleanup code on module destruction */class MyH323_Shutdown {	public:	MyH323_Shutdown() { };	~MyH323_Shutdown()	{		h323_end_process();	};};MyProcess::MyProcess(): PProcess("The NuFone Networks",			"H.323 Channel Driver for Asterisk",			MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER){	/* Call shutdown when module being unload or asterisk has been stopped */	static MyH323_Shutdown x;	/* Fix missed one in PWLib */	PX_firstTimeStart = FALSE;	Resume();}MyProcess::~MyProcess(){#ifndef SKIP_PWLIB_PIPE_BUG_WORKAROUND	_timerChangePipe[0] = timerChangePipe[0];	_timerChangePipe[1] = timerChangePipe[1];#endif}void MyProcess::Main(){	PTrace::Initialise(PTrace::GetLevel(), NULL, traceOptions);	PTrace::SetStream(logstream);	cout << "  == Creating H.323 Endpoint" << endl;	if (endPoint) {		cout << "  == ENDPOINT ALREADY CREATED" << endl;		return;	}	endPoint = new MyH323EndPoint();	/* Due to a bug in the H.323 recomendation/stack we should request a sane	   amount of bandwidth from the GK - this function is ignored if not using a GK	   We are requesting 128 (64k in each direction), which is the worst case codec. */	endPoint->SetInitialBandwidth(1280);}void PAssertFunc(const char *msg){	ast_log(LOG_ERROR, "%s\n", msg);	/* XXX: Probably we need to crash here */}/** MyH323EndPoint  */MyH323EndPoint::MyH323EndPoint()		: H323EndPoint(){	/* Capabilities will be negotiated on per-connection basis */	capabilities.RemoveAll();	/* Reset call setup timeout to some more reasonable value than 1 minute */	signallingChannelCallTimeout = PTimeInterval(0, 0, 10);	/* 10 minutes */}/** The fullAddress parameter is used directly in the MakeCall method so  * the General form for the fullAddress argument is :  * [alias@][transport$]host[:port]  * default values:	alias = the same value as host.  *					transport = ip.  *					port = 1720.  */int MyH323EndPoint::MyMakeCall(const PString & dest, PString & token, void *_callReference, void *_opts){	PString fullAddress;	MyH323Connection * connection;	H323Transport *transport = NULL;	unsigned int *callReference = (unsigned int *)_callReference;	call_options_t *opts = (call_options_t *)_opts;	/* Determine whether we are using a gatekeeper or not. */	if (GetGatekeeper()) {		fullAddress = dest;		if (h323debug) {			cout << " -- Making call to " << fullAddress << " using gatekeeper." << endl;		}	} else {		fullAddress = dest;		if (h323debug) {			cout << " -- Making call to " << fullAddress << " without gatekeeper." << endl;		}		/* Use bindaddr for outgoing calls too if we don't use gatekeeper */		if (listeners.GetSize() > 0) {			H323TransportAddress taddr = listeners[0].GetTransportAddress();			PIPSocket::Address addr;			WORD port;			if (taddr.GetIpAndPort(addr, port)) {				/* Create own transport for specific addresses only */				if (addr) {					if (h323debug)						cout << "Using " << addr << " for outbound call" << endl;					transport = new MyH323TransportTCP(*this, addr);					if (!transport)						cout << "Unable to create transport for outgoing call" << endl;				}			} else				cout << "Unable to get address and port" << endl;		}	}	if (!(connection = (MyH323Connection *)H323EndPoint::MakeCallLocked(fullAddress, token, opts, transport))) {		if (h323debug) {			cout << "Error making call to \"" << fullAddress << '"' << endl;		}		return 1;	}	*callReference = connection->GetCallReference();	if (h323debug) {		cout << "\t-- " << GetLocalUserName() << " is calling host " << fullAddress << endl;		cout << "\t-- Call token is " << (const char *)token << endl;		cout << "\t-- Call reference is " << *callReference << endl;#ifdef PTRACING		cout << "\t-- DTMF Payload is " << connection->dtmfCodec << endl;#endif	}	connection->Unlock();	return 0;}void MyH323EndPoint::SetEndpointTypeInfo( H225_EndpointType & info ) const{	H323EndPoint::SetEndpointTypeInfo(info);	if (terminalType == e_GatewayOnly){		info.RemoveOptionalField(H225_EndpointType::e_terminal);		info.IncludeOptionalField(H225_EndpointType::e_gateway);	}	info.m_gateway.IncludeOptionalField(H225_GatewayInfo::e_protocol);	info.m_gateway.m_protocol.SetSize(1);	H225_SupportedProtocols &protocol=info.m_gateway.m_protocol[0];	protocol.SetTag(H225_SupportedProtocols::e_voice);	PINDEX as=SupportedPrefixes.GetSize();	((H225_VoiceCaps &)protocol).m_supportedPrefixes.SetSize(as);	for (PINDEX p=0; p<as; p++) {		H323SetAliasAddress(SupportedPrefixes[p], ((H225_VoiceCaps &)protocol).m_supportedPrefixes[p].m_prefix, H225_AliasAddress::e_dialedDigits);	}}void MyH323EndPoint::SetGateway(void){	terminalType = e_GatewayOnly;}BOOL MyH323EndPoint::ClearCall(const PString & token, H323Connection::CallEndReason reason){	if (h323debug) {#ifdef PTRACING		cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause " << reason << endl;#else		cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause [" << (int)reason << "]" << endl;#endif	}	return H323EndPoint::ClearCall(token, reason);}BOOL MyH323EndPoint::ClearCall(const PString & token){	if (h323debug) {		cout << "\t-- ClearCall: Request to clear call with token " << token << endl;	}	return H323EndPoint::ClearCall(token, H323Connection::EndedByLocalUser);}void MyH323EndPoint::SendUserTone(const PString &token, char tone){	H323Connection *connection = NULL;	connection = FindConnectionWithLock(token);	if (connection != NULL) {		connection->SendUserInputTone(tone, 500);		connection->Unlock();	}}void MyH323EndPoint::OnClosedLogicalChannel(H323Connection & connection, const H323Channel & channel){	channelsOpen--;	if (h323debug) {		cout << "\t\tchannelsOpen = " << channelsOpen << endl;	}	H323EndPoint::OnClosedLogicalChannel(connection, channel);}BOOL MyH323EndPoint::OnConnectionForwarded(H323Connection & connection,		const PString & forwardParty,		const H323SignalPDU & pdu){	if (h323debug) {		cout << "\t-- Call Forwarded to " << forwardParty << endl;	}	return FALSE;}BOOL MyH323EndPoint::ForwardConnection(H323Connection & connection,		const PString & forwardParty,		const H323SignalPDU & pdu){	if (h323debug) {		cout << "\t-- Forwarding call to " << forwardParty << endl;	}	return H323EndPoint::ForwardConnection(connection, forwardParty, pdu);}void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken){	if (h323debug) {		cout << "\t=-= In OnConnectionEstablished for call " << connection.GetCallReference() << endl;		cout << "\t\t-- Connection Established with \"" << connection.GetRemotePartyName() << "\"" << endl;	}	on_connection_established(connection.GetCallReference(), (const char *)connection.GetCallToken());}/** OnConnectionCleared callback function is called upon the dropping of an established  * H323 connection.  */void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PString & clearedCallToken){	PString remoteName = connection.GetRemotePartyName();	switch (connection.GetCallEndReason()) {		case H323Connection::EndedByCallForwarded:			if (h323debug) {				cout << "-- " << remoteName << " has forwarded the call" << endl;

⌨️ 快捷键说明

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