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

📄 h323.cxx

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 CXX
📖 第 1 页 / 共 5 页
字号:
 * Fixed H245 connect on receiving call. * * Revision 1.10  1999/06/09 06:18:00  robertj * GCC compatibiltiy. * * Revision 1.9  1999/06/09 05:26:19  robertj * Major restructuring of classes. * * Revision 1.8  1999/06/07 00:37:05  robertj * Allowed for reuseaddr on listen when in debug version * * Revision 1.7  1999/06/06 06:06:36  robertj * Changes for new ASN compiler and v2 protocol ASN files. * * Revision 1.6  1999/04/26 06:20:22  robertj * Fixed bugs in protocol * * Revision 1.5  1999/04/26 06:14:46  craigs * Initial implementation for RTP decoding and lots of stuff * As a whole, these changes are called "First Noise" * * Revision 1.4  1999/02/23 11:04:28  robertj * Added capability to make outgoing call. * * Revision 1.3  1999/01/16 01:31:33  robertj * Major implementation. * * Revision 1.2  1999/01/02 04:00:56  robertj * Added higher level protocol negotiations. * * Revision 1.1  1998/12/14 09:13:09  robertj * Initial revision * */#include <ptlib.h>#include "h323.h"#include "h323neg.h"#include "channels.h"#include "h323rtp.h"#define new PNEW#if !PTRACING // Stuff to remove unised parameters warning#define PTRACE_pdu#endif/////////////////////////////////////////////////////////////////////////////#if PTRACINGconst char * const H323Connection::CallEndReasonNames[NumCallEndReasons] = {  "EndedByLocalUser",         /// Local endpoint application cleared call  "EndedByNoAccept",          /// Local endpoint did not accept call OnIncomingCall()=FALSE  "EndedByAnswerDenied",      /// Local endpoint declined to answer call  "EndedByRemoteUser",        /// Remote endpoint application cleared call  "EndedByRefusal",           /// Remote endpoint refused call  "EndedByNoAnswer",          /// Remote endpoint did not answer in required time  "EndedByCallerAbort",       /// Remote endpoint stopped calling  "EndedByTransportFail",     /// Transport error cleared call  "EndedByConnectFail",       /// Transport connection failed to establish call  "EndedByGatekeeper",        /// Gatekeeper has cleared call  "EndedByNoUser",            /// Call failed as could not find user (in GK)  "EndedByNoBandwidth",       /// Call failed as could not get enough bandwidth  "EndedByCallForwarded",     /// Call was forwarded using FACILITY message  "EndedByCapabilityExchange" /// Could not find common capabilities};const char * const H323Connection::ConnectionStatesNames[NumConnectionStates] = {  "NoConnectionActive",  "AwaitingGatekeeperAdmission",  "AwaitingTransportConnect",  "AwaitingSignalConnect",  "HasExecutedSignalConnect",  "EstablishedConnection",  "ShuttingDownConnection"};const char * const H323Connection::FastStartStateNames[NumFastStartStates] = {  "FastStartDisabled", "FastStartInitiate", "FastStartResponse"};const char * const H323Connection::AnswerCallResponseNames[NumAnswerCallResponses] = {  "AnswerCallNow",  "AnswerCallDenied",  "AnswerCallPending",  "AnswerCallDeferred"};#endifH323Connection::H323Connection(H323EndPoint & ep, unsigned ref)  : endpoint(ep),    localPartyName(ep.GetLocalUserName()),    localCapabilities(ep.GetCapabilities()){  callAnswered = FALSE;  distinctiveRing = 0;  callReference = ref;  signallingChannel = NULL;  controlChannel = NULL;  h245Tunneling = TRUE;  h245TunnelPDU = NULL;  connectionState = NoConnectionActive;  callEndReason = NumCallEndReasons;  answerResponse = NumAnswerCallResponses;  bandwidthAvailable = endpoint.GetInitialBandwidth();  fastStartState = FastStartDisabled;  remoteMaxAudioDelayJitter = 0;  masterSlaveDeterminationProcedure = new H245NegMasterSlaveDetermination(endpoint, *this);  capabilityExchangeProcedure = new H245NegTerminalCapabilitySet(endpoint, *this);  logicalChannels = new H245NegLogicalChannels(endpoint, *this);  requestModeProcedure = new H245NegRequestMode(endpoint, *this);  roundTripDelayProcedure = new H245NegRoundTripDelay(endpoint, *this);}H323Connection::~H323Connection(){  delete masterSlaveDeterminationProcedure;  delete capabilityExchangeProcedure;  delete logicalChannels;  delete requestModeProcedure;  delete roundTripDelayProcedure;  delete signallingChannel;  delete controlChannel;  PTRACE(3, "H323\tConnection " << callToken << " deleted.");}void H323Connection::SetCallEndReason(CallEndReason reason){  // Only set reason if not already set to something  if (callEndReason == NumCallEndReasons)    callEndReason = reason;}BOOL H323Connection::ClearCall(H323Connection::CallEndReason reason){  return endpoint.ClearCall(callToken, reason);}void H323Connection::CleanUpOnCallEnd(){  PTRACE(3, "H323\tConnection " << callToken << " closing: connectionState=" << connectionState);  // Special case of aborting while waiting for a transport connect (in  // particular a TCP socket connect) which must be aborted before the Lock()  if (connectionState == AwaitingTransportConnect)    signallingChannel->CleanUpOnTermination();  // Make sure no one is stll using this object before we go to town on it  Lock();  connectionState = ShuttingDownConnection;  // Clean up any fast start "pending" channels we may have running.  PINDEX i;  for (i = 0; i < fastStartChannels.GetSize(); i++)    fastStartChannels[i].CleanUpOnTermination();  fastStartChannels.RemoveAll();  // Dispose of all the logical channels  for (i = 0; i < logicalChannels->GetSize(); i++) {    H323Channel * channel = logicalChannels->GetChannelAt(i);    if (channel != NULL)      channel->CleanUpOnTermination();  }  logicalChannels->RemoveAll();  if (callEndReason == EndedByLocalUser) {    // Send an H.245 end session to the remote endpoint.    H323ControlPDU pdu;    pdu.BuildEndSessionCommand(H245_EndSessionCommand::e_disconnect);    WriteControlPDU(pdu);  }  /* If we have a signalling channel, then we should send a release complete.     This may actually be redundent if we a terminating via the remote end     sending release complete or if there is a transport failure, but it does     not hurt to try and send it anyway.   */  if (signallingChannel != NULL) {    if (signallingChannel->IsOpen()) {      PTRACE(2, "H225\tSending release complete PDU: callRef=" << callReference);      H323SignalPDU replyPDU;      replyPDU.BuildReleaseComplete(*this);      replyPDU.Write(*signallingChannel);    }    signallingChannel->CleanUpOnTermination();  }  // Wait for control channel to be cleaned up (thread ended).  if (controlChannel != NULL)    controlChannel->CleanUpOnTermination();  // Check for gatekeeper and do disengage if have one  if (callEndReason != EndedByGatekeeper) {    H323Gatekeeper * gatekeeper = endpoint.GetGatekeeper();    if (gatekeeper != NULL)      gatekeeper->DisengageRequest(*this, H225_DisengageReason::e_normalDrop);  }  PTRACE(1, "H323\tConnection " << callToken << " terminated.");}void H323Connection::AttachSignalChannel(H323Transport * channel){  if (signallingChannel != NULL && signallingChannel->IsOpen()) {    PAssertAlways(PLogicError);    return;  }  delete signallingChannel;  signallingChannel = channel;}BOOL H323Connection::WriteSignalPDU(H323SignalPDU & pdu){  PAssert(signallingChannel != NULL, PLogicError);  if (signallingChannel == NULL)    return FALSE;  if (!signallingChannel->IsOpen())    return FALSE;  pdu.m_h323_uu_pdu.m_h245Tunneling = h245Tunneling;  return pdu.Write(*signallingChannel);}void H323Connection::HandleSignallingChannel(){  PAssert(signallingChannel != NULL, PLogicError);  PTRACE(2, "H225\tReading PDUs: callRef=" << callReference);  H323SignalPDU pdu;  while (signallingChannel->IsOpen()) {    if (pdu.Read(*signallingChannel)) {      if (!HandleSignalPDU(pdu)) {        ClearCall(EndedByTransportFail);        break;      }    }    else if (connectionState != EstablishedConnection ||             signallingChannel->GetErrorCode() != PChannel::Timeout) {      if (controlChannel == NULL || !controlChannel->IsOpen())        ClearCall(signallingChannel->GetErrorCode() != PChannel::Timeout                                  ? EndedByTransportFail : EndedByNoAnswer);      signallingChannel->Close();      break;    }    if (controlChannel == NULL)      StartRoundTripDelay();  }  PTRACE(2, "H225\tSignal channel closed.");}BOOL H323Connection::HandleSignalPDU(H323SignalPDU & pdu){  const Q931 & q931 = pdu.GetQ931();  PTRACE(3, "H225\tHandling PDU: " << q931.GetMessageTypeName()                    << " callRef=" << q931.GetCallReference());  // If remote does not do tunneling, so we don't either. Note that if it  // gets turned off once, it stays off for good.  if (h245Tunneling && !pdu.m_h323_uu_pdu.m_h245Tunneling) {    masterSlaveDeterminationProcedure->Stop();    capabilityExchangeProcedure->Stop();    h245Tunneling = FALSE;  }  switch (q931.GetMessageType()) {    case Q931::SetupMsg :      if (!OnReceivedSignalSetup(pdu))        return FALSE;      break;    case Q931::CallProceedingMsg :      if (!OnReceivedCallProceeding(pdu))        return FALSE;      break;    case Q931::AlertingMsg :      if (!OnReceivedAlerting(pdu))        return FALSE;      break;    case Q931::ConnectMsg :      if (!OnReceivedSignalConnect(pdu))        return FALSE;      break;    case Q931::FacilityMsg :      if (!OnReceivedFacility(pdu))        return FALSE;      break;    case Q931::StatusEnquiryMsg :      if (!OnReceivedStatusEnquiry(pdu))        return FALSE;      break;    case Q931::ReleaseCompleteMsg :      if (connectionState == EstablishedConnection)        ClearCall(EndedByRemoteUser);      else if (answerResponse == AnswerCallDeferred)        ClearCall(EndedByCallerAbort);      else        ClearCall(EndedByRefusal);      return FALSE;    default :      if (!OnUnknownSignalPDU(pdu))        return FALSE;  }  // Process tunnelled H245 PDU, if present.  HandleTunnelPDU(pdu, NULL);  return TRUE;}void H323Connection::HandleTunnelPDU(const H323SignalPDU & pdu, H323SignalPDU * reply){  if (!h245Tunneling)    return;  h245TunnelPDU = reply;  for (PINDEX i = 0; i < pdu.m_h323_uu_pdu.m_h245Control.GetSize(); i++) {    PPER_Stream strm = pdu.m_h323_uu_pdu.m_h245Control[i].GetValue();    HandleControlData(strm);  }  h245TunnelPDU = NULL;  // Make sure does not get repeated, break const and clear tunnelled H.245 PDU's  ((H323SignalPDU &)pdu).m_h323_uu_pdu.m_h245Control.SetSize(0);}static BOOL BuildFastStartList(const H323Channel & channel,                               H225_ArrayOf_PASN_OctetString & array,                               H323Channel::Directions reverseDirection){  H245_OpenLogicalChannel open;  const H323Capability & capability = channel.GetCapability();  if (channel.GetDirection() != reverseDirection) {    if (!capability.OnSendingPDU(open.m_forwardLogicalChannelParameters.m_dataType))      return FALSE;  }  else {    if (!capability.OnSendingPDU(open.m_reverseLogicalChannelParameters.m_dataType))      return FALSE;    open.m_forwardLogicalChannelParameters.m_multiplexParameters.SetTag(                H245_OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters::e_none);    open.m_forwardLogicalChannelParameters.m_dataType.SetTag(H245_DataType::e_nullData);    open.IncludeOptionalField(H245_OpenLogicalChannel::e_reverseLogicalChannelParameters);  }  if (!channel.OnSendingPDU(open))    return FALSE;  PTRACE(4, "H225\tBuild fastStart:\n  " << setprecision(2) << open);  PPER_Stream strm;  open.Encode(strm);

⌨️ 快捷键说明

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