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

📄 h323.cxx

📁 这是一个OPENH323中的MCU程序
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/*
 * h323.cxx
 *
 * H.323 routines for a simple MCU
 *
 * Copyright (C) 2000 Equivalence Pty. Ltd.
 * Copyright (C) 2004 Post Increment
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions of ths code were written by by Post Increment (http://www.postincrement.com) 
 * with the assistance of funding from Stonevoice, slc. http://www.stonevoice.com
 *
 * Portions of this code were written by Post Increment (http://www.postincrement.com) 
 * with the assistance of funding from Citron Networks (http://www.citron.com.tw)
 *
 * Contributor(s): Derek J Smithies (derek@indranet.co.nz)
 *                 Craig Southeren (craig@postincrement.com)
 *
 * $Log: h323.cxx,v $
 * Revision 1.2  2007/11/07 04:03:25  willamowius
 * fix compile on gcc
 *
 * Revision 1.1  2007/10/17 19:44:30  shorne
 * Initial Commit
 *
 * Revision 2.7.2.2  2007/08/16 20:29:01  shorne
 * Better Gatekeeper anf Gateway prefix support
 *
 * Revision 2.7.2.1  2007/02/06 11:41:26  shorne
 * Updates for OpenH323 Video Plugins
 *
 * Revision 2.7  2006/08/07 06:18:22  csoutheren
 * Fix detection of MCU members
 * Add auto-removal of conferences only containing MCU members
 *
 * Revision 2.6  2006/08/02 06:24:53  csoutheren
 * Add provision for recording input audio
 *
 * Revision 2.5  2006/07/21 08:01:40  csoutheren
 * Fixed conference member detect
 * Re-factored video mixer code slightly
 *
 * Revision 2.4  2006/07/21 05:52:51  csoutheren
 * Add flag to indicate if remote endpoint is an MCU
 *
 * Revision 2.3  2006/07/21 05:08:03  csoutheren
 * Stability fixes and more inline documentation
 * Thanks to Paolo Amadini of Stonevoice
 *
 * Revision 2.2  2006/06/21 06:11:36  csoutheren
 * Fixes for latest pwlib
 *
 * Revision 2.1  2006/06/09 04:39:59  csoutheren
 * Migrated VideoBranch to main trunk
 *
 * Revision 1.1.2.8  2006/06/06 08:24:16  csoutheren
 * Added support for echo test room
 * Fix problem with using high frame rates
 *
 * Revision 1.1.2.7  2006/05/31 08:48:02  csoutheren
 * Fixed crash on second call when entry/exit files do not exist
 * Fix crash when Cisco HOLD used. Thanks to Christian Bongiovanni of Stonevoice
 *
 * Revision 1.1.2.6  2006/04/26 13:09:08  csoutheren
 * Fix problem when connecting file not available
 * Add optional time limit for rooms
 *
 * Revision 1.1.2.5  2006/04/18 03:05:09  csoutheren
 * Fix video mix problem with > 3 members
 * Add test room
 *
 * Revision 1.1.2.4  2006/04/06 08:20:29  csoutheren
 * Retyped conference member identifier to epxlicit type
 * Added support for H.245 terminal added and terminal left
 *
 * Revision 1.1.2.3  2006/04/06 01:11:16  csoutheren
 * Latest sources include
 *   - premedia blanking and optional image display
 *   - ablity to defer conference join for authentication if required
 *   - more bulletproofing on conference join
 *   - new video copy/fill functions
 *
 * Revision 1.1.2.2  2006/04/06 00:50:30  csoutheren
 * Latest changes (more to come)
 *
 * Revision 1.1.2.1  2006/03/28 05:13:38  csoutheren
 * Normalised file headers
 * Fixed problem with QCIF video
 * Seperated H.323 and MCU process functions into seperate files
 *
 */

#include <ptlib.h>
#include <ptlib/video.h>

#include "version.h"
#include "mcu.h"
#include "h323.h"

#include <h323pdu.h>

#if OPENMCU_VIDEO

const unsigned int DefaultVideoFrameRate = 10;
const unsigned int DefaultVideoQuality   = 10;
static const char EnableVideoKey[]       = "Enable video";
static const char VideoFrameRateKey[]    = "Video frame rate";
static const char VideoQualityKey[]      = "Video quality";

#endif  // OPENMCU_VIDEO

static const char InterfaceKey[]          = "Interface";
static const char LocalUserNameKey[]      = "Local User Name";
static const char GatekeeperUserNameKey[] = "Gatekeeper Username";
static const char GatekeeperAliasKey[]    = "Gatekeeper Room Names";
static const char GatekeeperPasswordKey[] = "Gatekeeper Password";
static const char GatekeeperPrefixesKey[] = "Gatekeeper Prefixes";
static const char GatekeeperModeKey[]     = "Gatekeeper Mode";
static const char GatekeeperKey[]         = "Gatekeeper";
static const char DisableCodecsKey[]      = "Disable codecs";

static const char * GKModeLabels[] = { 
   "No gatekeeper", 
   "Find gatekeeper", 
   "Use gatekeeper", 
};

enum {
  Gatekeeper_None,
  Gatekeeper_Find,
  Gatekeeper_Explicit
};

#define GKMODE_LABEL_COUNT   (sizeof(GKModeLabels)/sizeof(char *))

#define new PNEW


///////////////////////////////////////////////////////////////

void SpliceMacro(PString & text, const PString & token, const PString & value)
{
  PRegularExpression RegEx("<?!--#status[ \t\r\n]+" + token + "[ \t\r\n]*-->?",
                           PRegularExpression::Extended|PRegularExpression::IgnoreCase);
  PINDEX pos, len;
  while (text.FindRegEx(RegEx, pos, len))
    text.Splice(value, pos, len);
}

///////////////////////////////////////////////////////////////

OpenMCUH323EndPoint::OpenMCUH323EndPoint(ConferenceManager & _conferenceManager)
  : conferenceManager(_conferenceManager)
{
#if OPENMCU_VIDEO
	terminalType = e_MCUWithAVMP;
  enableVideo  = TRUE;
  videoRate    = DefaultVideoFrameRate;
#else
	terminalType = e_MCUWithAudioMP;
#endif

   gkAlias = PString();

}

void OpenMCUH323EndPoint::Initialise(PConfig & cfg, PConfigPage * rsrc)
{

#ifdef HAS_AEC
  SetAECEnabled(FALSE);
#endif

///////////////////////////////////////////
// Listeners
  PString defaultInterface = "*:1720";
  H323TransportAddressArray interfaces;
  PINDEX arraySize = cfg.GetInteger(PString(InterfaceKey) + " Array Size");
  if (arraySize == 0)
    StartListener(defaultInterface);
  else {
    for (int i = 0; i < arraySize; i++)
      interfaces.Append(new H323TransportAddress(cfg.GetString(psprintf("%s %u", InterfaceKey, i+1), "")));
    StartListeners(interfaces);
  }
  rsrc->Add(new PHTTPFieldArray(new PHTTPStringField(cfg.GetDefaultSection() + "\\" + InterfaceKey, InterfaceKey, 20, defaultInterface), FALSE));

  if (listeners.IsEmpty()) {
    PSYSTEMLOG(Fatal, "Main\tCould not open H.323 Listener");
  }

  AliasList.RemoveAll();
  localAliasNames.RemoveAll();

//////////////////////////////////////////////////////
// Gatekeeper mode
  PStringArray labels(GKMODE_LABEL_COUNT, GKModeLabels); 
  PINDEX idx = labels.GetStringsIndex(cfg.GetString(GatekeeperModeKey, labels[0]));  
  PINDEX gkMode = (idx == P_MAX_INDEX) ? 0 : idx;
  rsrc->Add(new PHTTPRadioField(GatekeeperModeKey, labels, gkMode));

  // Gatekeeper 
  PString gkName = cfg.GetString(GatekeeperKey);
  rsrc->Add(new PHTTPStringField(GatekeeperKey, 25, gkName));

  // Gatekeeper UserName
  PString gkUserName = cfg.GetString(GatekeeperUserNameKey,"MCU");
  if (gkMode == Gatekeeper_None ) {
    // Local alias name for H.323 endpoint
    SetLocalUserName(cfg.GetString(LocalUserNameKey, OpenMCU::Current().GetName() + " v" + OpenMCU::Current().GetVersion()));
  } else {
    SetLocalUserName(gkUserName);
  }
  rsrc->Add(new PHTTPStringField(GatekeeperUserNameKey, 25, gkUserName));
  AliasList.AppendString(gkUserName);

  // Gatekeeper password
  PString gkPassword = PHTTPPasswordField::Decrypt(cfg.GetString(GatekeeperPasswordKey));
  SetGatekeeperPassword(gkPassword);
  rsrc->Add(new PHTTPPasswordField(GatekeeperPasswordKey, 25, gkPassword));

  // Gatekeeper Alias
  gkAlias = cfg.GetString(GatekeeperAliasKey,"MCU*");
  rsrc->Add(new PHTTPStringField(GatekeeperAliasKey, 25, gkAlias));

  for (PINDEX k=0; k< OpenMCU::defaultRoomCount; k++) {
	  PString alias = gkAlias;
	  alias.Replace("*",k);
	  AddAliasName(alias);   // Add the alias to the endpoint aliaslist
      AliasList.AppendString(alias);  
  }

  // Gatekeeper prefixes
  PINDEX prefixSize = cfg.GetInteger(PString(GatekeeperPrefixesKey) + " Array Size");
  if (prefixSize > 0) {
	  for (int j = 0; j < prefixSize; j++) {
	     PString prefix = cfg.GetString(psprintf("%s %u", GatekeeperPrefixesKey, j+1));
         PrefixList.AppendString(prefix);

		for (PINDEX k=0; k< OpenMCU::defaultRoomCount; k++) {
			PString alias = prefix + PString(k);
			AliasList.AppendString(alias);  
		}
	  }
  }
  rsrc->Add(new PHTTPFieldArray(new PHTTPStringField(cfg.GetDefaultSection() + "\\" + GatekeeperPrefixesKey, 
	                                                                    GatekeeperPrefixesKey, 20, ""), FALSE));

#if OPENMCU_VIDEO
  enableVideo = cfg.GetBoolean(EnableVideoKey, TRUE);
  rsrc->Add(new PHTTPBooleanField(EnableVideoKey, enableVideo));

  videoRate = cfg.GetInteger(VideoFrameRateKey, DefaultVideoFrameRate);
  rsrc->Add(new PHTTPIntegerField(VideoFrameRateKey, 1, 30, videoRate));

  videoTxQuality = cfg.GetInteger(VideoQualityKey, DefaultVideoQuality);
  rsrc->Add(new PHTTPIntegerField(VideoQualityKey, 1, 30, videoTxQuality));
#endif

  /*
  if (args.GetOptionString('q').IsEmpty()) {
    endpoint.behind_masq = FALSE;
  } else {
    endpoint.masqAddressPtr = new PIPSocket::Address(args.GetOptionString('q'));
    endpoint.behind_masq = TRUE;
    cout << "Masquerading as address " << *(endpoint.masqAddressPtr) << endl;
  } */

  capabilities.RemoveAll();
 
  AddAllCapabilities(0, 0, "*");

  // disable codecs as required
  PString disableCodecs = cfg.GetString(DisableCodecsKey);
  rsrc->Add(new PHTTPStringField(DisableCodecsKey, 50, disableCodecs));
  if (!disableCodecs.IsEmpty()) {
    PStringArray toRemove = disableCodecs.Tokenise(',', FALSE);
    capabilities.Remove(toRemove);
  }

#if 0 //  old MCU options
  int videoTxQual = 10;
  if (args.HasOption("videotxquality")) 
      videoTxQual = args.GetOptionString("videotxquality").AsInteger();
  endpoint.videoTxQuality = PMAX(1, PMIN(31, videoTxQual));

  int videoF = 2;
  if (args.HasOption("videofill")) 
    videoF = args.GetOptionString("videofill").AsInteger();
  endpoint.videoFill = PMAX(1, PMIN(99, videoF));

  int videoFPS = 10;
  if (args.HasOption("videotxfps")) 
    videoFPS = args.GetOptionString("videotxfps").AsInteger();
  endpoint.videoFramesPS = PMAX(1,PMIN(30,videoFPS));

  int videoBitRate = 0; //disable setting videoBitRate.
  if (args.HasOption("videobitrate")) {
    videoBitRate = args.GetOptionString("videobitrate").AsInteger();
    videoBitRate = 1024 * PMAX(16, PMIN(2048, videoBitRate));
  }
  endpoint.videoBitRate = videoBitRate;
#endif

  AddAllUserInputCapabilities(0, 2);

  switch (gkMode) {
    default:
    case Gatekeeper_None:
      break;

    case Gatekeeper_Find:
      if (!DiscoverGatekeeper(new H323TransportUDP(*this)))
        PSYSTEMLOG(Error, "No gatekeeper found");
	  else
		PSYSTEMLOG(Info, "Found Gatekeeper: " << gatekeeper);
      break;

    case Gatekeeper_Explicit:
      if (!SetGatekeeper(gkName, new H323TransportUDP(*this)))
        PSYSTEMLOG(Error, "Error registering with gatekeeper at \"" << gkName << '"');
	  else
		PSYSTEMLOG(Info, "Registered with Gatekeeper: " << gkName);
  }

  PTRACE(2, "MCU\tCodecs (in preference order):\n" << setprecision(2) << GetCapabilities());;
}

H323Connection * OpenMCUH323EndPoint::CreateConnection(
      unsigned callReference,
      void * userData,
      H323Transport *,
      H323SignalPDU *)

{
  return new OpenMCUH323Connection(*this, callReference, userData);
}

void OpenMCUH323EndPoint::TranslateTCPAddress(PIPSocket::Address &localAddr, const PIPSocket::Address &remoteAddr)
{

//  if (this->behind_masq && 
//      (remoteAddr.Byte1() != 192)) {
//    localAddr = *(this->masqAddressPtr);
//  }
  return;
}

PString OpenMCUH323EndPoint::GetRoomStatus(const PString & block)
{
  PString substitution;
  PWaitAndSignal m(conferenceManager.GetConferenceListMutex());
  ConferenceListType & conferenceList = conferenceManager.GetConferenceList();

  ConferenceListType::iterator r;
  for (r = conferenceList.begin(); r != conferenceList.end(); ++r) {

    // make a copy of the repeating html chunk
    PString insert = block;
    PStringStream members;
    members << "<table border=1>"
               "<tr>"
                 "<th>"
                 "&nbsp;Name&nbsp;"
                 "</th><th>"
                 "&nbsp;Duration&nbsp;"
                 "</th><th>"
                 "&nbsp;Codec&nbsp;"
                 "</th><th>"
                 "&nbsp;RTP Packets/Bytes tx&nbsp;"
                 "</th><th>"
                 "&nbsp;RTP Packets/Bytes rx&nbsp;"
                 "</th>"
#if OPENMCU_VIDEO
                 "<th>"
                 "&nbsp;TX&nbsp;Video&nbsp;frame&nbsp;rate/RX&nbsp;Video&nbsp;frame&nbsp;rate&nbsp;"
                 "</th>"
#endif
                 "</tr>";

    Conference & conference = *(r->second);
    size_t memberListSize = 0;
    {
      PWaitAndSignal m(conference.GetMutex());
      Conference::MemberList & memberList = conference.GetMemberList();
      memberListSize = memberList.size();
      Conference::MemberList::const_iterator s;
      for (s = memberList.begin(); s != memberList.end(); ++s) {
        ConferenceMember * member = s->second;
        H323Connection_ConferenceMember * connMember = dynamic_cast<H323Connection_ConferenceMember *>(member);
        if (connMember != NULL) {
          OpenMCUH323Connection * conn = (OpenMCUH323Connection *)FindConnectionWithLock(connMember->GetH323Token());
          if (conn != NULL) {
            PTime now;
            PTime callStart = conn->GetConnectionStartTime();
            RTP_Session * session = conn->GetSession(RTP_Session::DefaultAudioSessionID);
            members << "<tr>"
                      "<td>"
                    << conn->GetRemotePartyName()
                    << (member->IsMCU() ? "<BR>(MCU)" : "")

                    << "</td><td>"   
                    << (now -callStart)
                    << "</td><td>"   
                    << conn->GetAudioTransmitCodecName() << '/' << conn->GetAudioReceiveCodecName()
#if OPENMCU_VIDEO
                    << "<BR>" << conn->GetVideoTransmitCodecName() << '/' << conn->GetVideoReceiveCodecName()
#endif
                    << "</td><td>"   
                    << session->GetPacketsSent() << '/' << session->GetOctetsSent() 
                    << "</td><td>"   
                    << session->GetPacketsReceived() << '/' << session->GetOctetsReceived()
                    << "</td>";
            conn->Unlock();
          }
        }
        members 
#if OPENMCU_VIDEO
                << "<td>"   

⌨️ 快捷键说明

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