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

📄 gatekeeper.cpp

📁 语音接口~语音识别 & 从声音识别到对各种情报的查找/提供 资料请求~住所.姓名.电话号码等的识别接待 受订货业务~被定型化的受订货业务 预约业务~预约情况的向导和预约接
💻 CPP
字号:
// Copyright (C) 2005 Open Source Telecom Corp.//  // This program 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.// // This program is distributed in the hope that it will be useful,// but 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// As a special exception to the GNU General Public License, permission is// granted for additional uses of the text contained in its release// of Bayonne as noted here.//// This exception is that permission is hereby granted to link Bayonne 2// with the OpenH323 and Pwlib libraries, and distribute the combination, // without applying the requirements of the GNU GPL to the OpenH323// and pwd libraries as long as you do follow the requirements of the // GNU GPL for all the rest of the software thus combined.//// This exception does not however invalidate any other reasons why// the resulting executable file might be covered by the GNU General// public license or invalidate the licensing requirements of any// other component or library.//// This class implements Citron's NAT technology, allowing a NAT'ed endpoint to// connect to a public GNUGK gatekeeper from behind a NAT gateway that has no// special configuration relating to H.323.//// This code comes from Chih-Wei Huang <cwhuang@citron.com.tw>, and was taken// from GnomeMeeting.#include "driver.h"namespace h323driver {using namespace ost;using namespace std;Gatekeeper::Gatekeeper(H323EndPoint &ep, H323Transport *trans) : H323Gatekeeper(ep, trans){	isMakeRequestCalled = false;	detectorThread = 0;	incomingTCP = outgoingTCP = 0;	gkport = 0;}Gatekeeper::~Gatekeeper(){	StopDetecting();}BOOL Gatekeeper::MakeRequest(Request &request){	if(request.requestPDU.GetAuthenticators().IsEmpty())		request.requestPDU.SetAuthenticators(authenticators);	if(isMakeRequestCalled)	{		isMakeRequestCalled = false;		return H225_RAS::MakeRequest(request);	}	PWaitAndSignal lock(requestMutex);	while(!H225_RAS::MakeRequest(request))	{		if(request.responseResult != Request::NoResponseReceived && request.responseResult != Request::TryAlternate)			return false;		PINDEX alt, altsize = alternates.GetSize();		if(altsize == 0)			return FALSE;		H323TransportAddress tempAddr = transport->GetRemoteAddress();		PString tempIdentifier = gatekeeperIdentifier;		StopDetecting();		PSortedList<AlternateInfo> altGKs = alternates;		for(alt = 0; alt < altsize; ++alt)		{			AlternateInfo *altInfo = &altGKs[alt];			transport->SetRemoteAddress(altInfo->rasAddress);			transport->Connect();			gatekeeperIdentifier = altInfo->gatekeeperIdentifier;			H323RasPDU pdu;			Request req(SetupGatekeeperRequest(pdu), pdu);			if(H225_RAS::MakeRequest(req))			{				endpointIdentifier = "";				isMakeRequestCalled = true;				if(!RegistrationRequest(autoReregister))					continue;				if(request.requestPDU.GetChoice().GetTag() == H323RasPDU::e_admissionRequest)				{					H225_AdmissionRequest & arq = dynamic_cast<H225_RasMessage&>						(request.requestPDU.GetChoice());					arq.m_gatekeeperIdentifier = gatekeeperIdentifier;					arq.m_endpointIdentifier = endpointIdentifier;				}				else if(request.requestPDU.GetChoice().GetTag() == H323RasPDU::e_registrationRequest)					return TRUE;				break;			}		}				if(alt >= altsize)		{			// switch failed, use primary			transport->SetRemoteAddress(tempAddr);			transport->Connect();			gatekeeperIdentifier = tempIdentifier;			return FALSE;		}	}	return TRUE;}BOOL Gatekeeper::OnReceiveRegistrationConfirm(const H225_RegistrationConfirm &rcf){	if(rcf.HasOptionalField(H225_RegistrationConfirm::e_nonStandardData))		if(rcf.m_nonStandardData.m_data.AsString().Find("NAT=") == 0)		{			PWaitAndSignal lock(threadMutex);			// Connection is NAT'ed			if(!detectorThread)			{				if(rcf.m_callSignalAddress.GetSize() > 0)				{					const H225_TransportAddress &addr = rcf.m_callSignalAddress[0];					if(addr.GetTag() == H225_TransportAddress::e_ipAddress)					{						const H225_TransportAddress_ipAddress & ip = addr;						gkip = PIPSocket::Address(ip.m_ip[0], ip.m_ip[1],							ip.m_ip[2], ip.m_ip[3]);						gkport = ip.m_port;					}				}				detectorThread = new DetectIncomingCallThread(this);			}		}	return H323Gatekeeper::OnReceiveRegistrationConfirm(rcf);}BOOL Gatekeeper::OnReceiveUnregistrationRequest(const H225_UnregistrationRequest &urq){	StopDetecting();	return H323Gatekeeper::OnReceiveUnregistrationRequest(urq);}void Gatekeeper::OnSendRegistrationRequest(H225_RegistrationRequest & rrq){	H323Gatekeeper::OnSendRegistrationRequest(rrq);}void Gatekeeper::OnSendUnregistrationRequest(H225_UnregistrationRequest &urq){	StopDetecting();	H323Gatekeeper::OnSendUnregistrationRequest(urq);}void Gatekeeper::DetectIncomingCall(){	const H323ListenerList & listeners = endpoint.GetListeners();	if(listeners.IsEmpty())		return;	H323TransportAddress localAddr = listeners[0].GetTransportAddress();	isDetecting = true;	while(isDetecting)	{		if(!gkport)		{			H323TransportAddress gksig;			if(!LocationRequest(endpoint.GetAliasNames(), gksig))			{				PProcess::Current().Sleep(60 * 1000);				continue;			}			gksig.GetIpAndPort(gkip, gkport);		}		socketMutex.Wait();		incomingTCP = new PTCPSocket(gkport);		socketMutex.Signal();		if(!incomingTCP->Connect(gkip))		{			socketMutex.Wait();			delete incomingTCP;			incomingTCP = 0;			socketMutex.Signal();			PProcess::Current().Sleep(60 * 1000);			continue;		}		while(incomingTCP->IsOpen())		{			SendInfo(Q931::CallState_IncomingCallProceeding);			PSocket::SelectList rlist;			rlist.Append(incomingTCP);			if((PSocket::Select(rlist, 86400 * 1000) == PSocket::NoError) && !rlist.IsEmpty())			{				// incoming call detected				PIPSocket::Address ip;				WORD port;				localAddr.GetIpAndPort(ip, port);				socketMutex.Wait();				outgoingTCP = new PTCPSocket(port);				socketMutex.Signal();				if(!outgoingTCP->Connect(ip))					break;				DoForwarding(incomingTCP, outgoingTCP);				break;			}		}		PWaitAndSignal socketLock(socketMutex);		delete incomingTCP;		incomingTCP = 0;		delete outgoingTCP;		outgoingTCP = 0;	}}void Gatekeeper::StopDetecting(){	PWaitAndSignal lock(threadMutex);	if(detectorThread)	{		isDetecting = false;		socketMutex.Wait();		if(incomingTCP)		{			if(outgoingTCP)				outgoingTCP->Close();			else				SendInfo(Q931::CallState_DisconnectRequest);			incomingTCP->Close();		}		socketMutex.Signal();		detectorThread->Terminate();		detectorThread->WaitForTermination();		delete detectorThread;		detectorThread = 0;	}}bool Gatekeeper::SendInfo(int state){	Q931 information;	information.BuildInformation(0, false);	PBYTEArray buf, epid(endpointIdentifier, endpointIdentifier.GetLength(), false);	information.SetIE(Q931::FacilityIE, epid);	information.SetCallState(Q931::CallStates(state));	information.Encode(buf);	return SendTPKT(incomingTCP, buf);}bool Gatekeeper::SendTPKT(PTCPSocket *sender, const PBYTEArray &buf){	WORD len = buf.GetSize();	WORD tlen = len + 4;	PBYTEArray tbuf(tlen);	BYTE *bptr = tbuf.GetPointer();	bptr[0] = 3;	bptr[1] = 0;	*(reinterpret_cast<WORD *>(bptr + 2)) = PIPSocket::Host2Net(WORD(len + 4));	memcpy(bptr + 4, buf, len);	return sender->Write(bptr, tlen);}bool Gatekeeper::ForwardMesg(PTCPSocket *receiver, PTCPSocket *sender){	BYTE tpkt[4];	int bSize;	if(!receiver->ReadBlock(tpkt, sizeof(tpkt)))		return false;	if(tpkt[0] != 3)		return true;	bSize = ((tpkt[2] << 8) | tpkt[3]) - 4;	PBYTEArray buffer(bSize);	if(!receiver->ReadBlock(buffer.GetPointer(), bSize))		return false;		return SendTPKT(sender, buffer);}void Gatekeeper::DoForwarding(PTCPSocket *incomingTCP, PTCPSocket *outgoingTCP){	while(incomingTCP->IsOpen() && outgoingTCP->IsOpen())	{		switch(PSocket::Select(*incomingTCP, *outgoingTCP))		{		case -3:			// data available on both			if(!ForwardMesg(outgoingTCP, incomingTCP))				return;		case -1:			ForwardMesg(incomingTCP, outgoingTCP);			break;		case -2:			ForwardMesg(outgoingTCP, incomingTCP);			break;		default:			break;		}	}}} // namespace

⌨️ 快捷键说明

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