ast_h323.cpp
来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C++ 代码 · 共 1,533 行 · 第 1/3 页
CPP
1,533 行
#define _GNU_SOURCE/* * 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.cpp 7221 2005-11-29 18:24:39Z kpfleming $ */#include <arpa/inet.h>#include <list>#include <string>#include <algorithm>#include <ptlib.h>#include <h323.h>#include <h323pdu.h>#include <mediafmt.h>#include <lid.h>#ifdef __cplusplusextern "C" {#endif#include "asterisk/logger.h"#include "asterisk/channel.h"#ifdef __cplusplus}#endif#include "chan_h323.h"#include "ast_h323.h"/* 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 */int channelsOpen;/* DTMF Mode */int mode = H323_DTMF_RFC2833;/** * 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 */MyH323EndPoint *endPoint = NULL;/** PWLib entry point */MyProcess *localProcess = NULL;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;}#define cout (*logstream)MyProcess::MyProcess(): PProcess("The NuFone Network's", "H.323 Channel Driver for Asterisk", MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER){ /* Fix missed one in PWLib */ PX_firstTimeStart = FALSE; Resume();}void MyProcess::Main(){ cout << " == Creating H.323 Endpoint" << endl; 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); PTrace::Initialise(0, NULL, PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine); PTrace::SetStream(logstream);}void PAssertFunc(const char *msg){ ast_log(LOG_ERROR, "%s\n", msg); /* XXX: Probably we need to crash here */}H323_REGISTER_CAPABILITY(H323_G7231Capability, OPAL_G7231);H323_REGISTER_CAPABILITY(AST_G729Capability, OPAL_G729);H323_REGISTER_CAPABILITY(AST_G729ACapability, OPAL_G729A);H323_G7231Capability::H323_G7231Capability(BOOL annexA_) : H323AudioCapability(7, 4){ annexA = annexA_;}PObject::Comparison H323_G7231Capability::Compare(const PObject & obj) const{ Comparison result = H323AudioCapability::Compare(obj); if (result != EqualTo) { return result; } PINDEX otherAnnexA = ((const H323_G7231Capability &)obj).annexA; if (annexA < otherAnnexA) { return LessThan; } if (annexA > otherAnnexA) { return GreaterThan; } return EqualTo;}PObject * H323_G7231Capability::Clone() const{ return new H323_G7231Capability(*this);}PString H323_G7231Capability::GetFormatName() const{ return OPAL_G7231;}unsigned H323_G7231Capability::GetSubType() const{ return H245_AudioCapability::e_g7231;}BOOL H323_G7231Capability::OnSendingPDU(H245_AudioCapability & cap, unsigned packetSize) const{ cap.SetTag(H245_AudioCapability::e_g7231); H245_AudioCapability_g7231 & g7231 = cap; g7231.m_maxAl_sduAudioFrames = packetSize; g7231.m_silenceSuppression = annexA; return TRUE;}BOOL H323_G7231Capability::OnReceivedPDU(const H245_AudioCapability & cap, unsigned & packetSize){ if (cap.GetTag() != H245_AudioCapability::e_g7231) { return FALSE; } const H245_AudioCapability_g7231 & g7231 = cap; packetSize = g7231.m_maxAl_sduAudioFrames; annexA = g7231.m_silenceSuppression; return TRUE;}H323Codec * H323_G7231Capability::CreateCodec(H323Codec::Direction direction) const{ return NULL;}AST_G729Capability::AST_G729Capability() : H323AudioCapability(24, 2){}PObject * AST_G729Capability::Clone() const{ return new AST_G729Capability(*this);}unsigned AST_G729Capability::GetSubType() const{ return H245_AudioCapability::e_g729;}PString AST_G729Capability::GetFormatName() const{ return OPAL_G729;}H323Codec * AST_G729Capability::CreateCodec(H323Codec::Direction direction) const{ return NULL;}AST_G729ACapability::AST_G729ACapability() : H323AudioCapability(24, 6){}PObject * AST_G729ACapability::Clone() const{ return new AST_G729ACapability(*this);}unsigned AST_G729ACapability::GetSubType() const{ return H245_AudioCapability::e_g729AnnexA;}PString AST_G729ACapability::GetFormatName() const{ return OPAL_G729A;}H323Codec * AST_G729ACapability::CreateCodec(H323Codec::Direction direction) const{ return NULL;}/** MyH323EndPoint */MyH323EndPoint::MyH323EndPoint() : H323EndPoint(){ // Capabilities will be negotiated on per-connection basis capabilities.RemoveAll();}/** 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::MakeCall(const PString & dest, PString & token, unsigned int *callReference, call_options_t *opts){ PString fullAddress; MyH323Connection * connection; /* 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; } } if (!(connection = (MyH323Connection *)H323EndPoint::MakeCallLocked(fullAddress, token, opts))) { if (h323debug) { cout << "Error making call to \"" << fullAddress << '"' << endl; } return 1; } *callReference = connection->GetCallReference(); if (opts->cid_num) { connection->ast_cid_num = PString(opts->cid_num); } if (opts->cid_name) { connection->ast_cid_name = PString(opts->cid_name); connection->SetLocalPartyName(connection->ast_cid_name); } connection->dtmfCodec = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec; 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; cout << "\t-- DTMF Payload is " << connection->dtmfCodec << endl; } 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) { cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause " << reason << endl; } 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; } break; case H323Connection::EndedByRemoteUser: if (h323debug) { cout << "-- " << remoteName << " has cleared the call" << endl; } break; case H323Connection::EndedByCallerAbort: if (h323debug) { cout << "-- " << remoteName << " has stopped calling" << endl; } break; case H323Connection::EndedByRefusal: if (h323debug) { cout << "-- " << remoteName << " did not accept your call" << endl; } break; case H323Connection::EndedByRemoteBusy: if (h323debug) { cout << "-- " << remoteName << " was busy" << endl; } break; case H323Connection::EndedByRemoteCongestion: if (h323debug) { cout << "-- Congested link to " << remoteName << endl; } break; case H323Connection::EndedByNoAnswer: if (h323debug) { cout << "-- " << remoteName << " did not answer your call" << endl; } break; case H323Connection::EndedByTransportFail: if (h323debug) { cout << "-- Call with " << remoteName << " ended abnormally" << endl; } break; case H323Connection::EndedByCapabilityExchange: if (h323debug) { cout << "-- Could not find common codec with " << remoteName << endl; } break; case H323Connection::EndedByNoAccept: if (h323debug) { cout << "-- Did not accept incoming call from " << remoteName << endl; } break; case H323Connection::EndedByAnswerDenied: if (h323debug) { cout << "-- Refused incoming call from " << remoteName << endl; } break; case H323Connection::EndedByNoUser: if (h323debug) { cout << "-- Remote endpoint could not find user: " << remoteName << endl; } break; case H323Connection::EndedByNoBandwidth: if (h323debug) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?