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

📄 main.cxx

📁 openmcu 是开源的H.323会议服务器,需要pwlib 和 openh323的编译库文件支持。
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/*
 * main.cxx
 *
 * A simple H.323 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 this code were written by Post Increment (http://www.postincrement.com) 
 * with the assistance of funding from Citron Networks (http://www.citron.com.tw)
 *
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
 * All Rights Reserved.
 *
 * Contributor(s): Derek J Smithies (derek@indranet.co.nz)
 *                 Craig Southeren (craig@postincrement.com)

 * $Log: main.cxx,v $
 * Revision 2.12  2004/05/26 06:54:31  csoutheren
 * Changed to be a PHTTPServiceProcess
 * Added ability to play WAV files on member entry and exit
 * Added additional documentation on all classes
 * Preparation for re-introducing video
 *
 * Revision 2.11  2004/05/10 13:07:19  rjongbloed
 * Changed G.726 and MS-ADPCM to plug in codecs.
 *
 * Revision 2.10  2004/05/04 12:21:16  rjongbloed
 * Converted LPC-10 codec to plug in.
 *
 * Revision 2.9  2004/05/03 13:25:47  rjongbloed
 * Converted everything to be codec plug in freindly
 * Removed GSM and G.729 as now plug ins are "the way"!
 *
 * Revision 2.8  2004/05/02 01:35:01  csoutheren
 * Move --disable-menu to outside video #ifdef
 *
 * Revision 2.7  2004/04/06 11:27:50  rjongbloed
 * Changes to support native C++ Run Time Type Information
 * Changes for codec plug ins
 *
 * Revision 2.6  2004/04/02 01:10:52  csoutheren
 * Fixed unitialised variable
 *
 * Revision 2.5  2004/03/31 03:40:25  csoutheren
 * Added various codecs back in
 *
 * Revision 2.4  2004/03/31 03:36:38  csoutheren
 * Fixed problem with user indication messages
 * Fixed problems with room listener and unlisten
 *
 * Revision 2.3  2004/03/30 04:02:54  csoutheren
 * Fixed problem with not using incoming alias for default room name
 *
 * Revision 2.2  2004/03/23 11:40:06  csoutheren
 * Fixed problem where deleting map element in-place causes crash at end of call
 * Fixed problem where referencing map by iterator rather than ID
 * Fixed code formatting problems
 *
 * Revision 2.1  2004/03/11 20:49:44  csoutheren
 * Removed warnings
 *
 * Revision 2.0  2004/03/08 02:06:24  csoutheren
 * Totally rewritten to use new connection locking mecahnism
 * Added ability to monitor conferences
 * Added initial support for H.323 MCU messages
 * Thanks to Citron Networks for supporting this work
 */

#include <ptlib.h>

#include <ptlib/pipechan.h>

#include "version.h"
#include "main.h"

PCREATE_PROCESS(OpenMCU);

const WORD DefaultHTTPPort = 1420;

static const char LogLevelKey[]           = "Log Level";
static const char UserNameKey[]           = "Username";
static const char PasswordKey[]           = "Password";
static const char HttpPortKey[]           = "HTTP Port";
static const char LocalUserNameKey[]      = "Local User Name";
static const char GatekeeperPasswordKey[] = "Gatekeeper Password";
static const char GatekeeperModeKey[]     = "Gatekeeper Mode";
static const char GatekeeperKey[]         = "Gatekeeper";
static const char DefaultRoomKey[]        = "Default room";
static const char DisableCodecsKey[]      = "Disable codecs";

static const char CallLogFilenameKey[]    = "Call log filename";
static const char InterfaceKey[]          = "Interface";

static const char ConnectingWAVFileKey[]  = "Connecting WAV File";
static const char EnteringWAVFileKey[]    = "Entering WAV File";
static const char LeavingWAVFileKey[]     = "Leaving WAV File";

#if P_SSL
static const char HTTPCertificateFileKey[]  = "HTTP Certificate";
#endif

static const char DefaultCallLogFilename[] = "mcu_log.txt"; 
static const char DefaultRoom[]            = "room101";

static const char DefaultConnectingWAVFile[] = "connecting.wav";
static const char DefaultEnteringWAVFile[]   = "entering.wav";
static const char DefaultLeavingWAVFile[]    = "leaving.wav";

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


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

class MainStatusPage : public PServiceHTTPString
{
  PCLASSINFO(MainStatusPage, PServiceHTTPString);

  public:
    MainStatusPage(OpenMCU & app, PHTTPAuthority & auth);
    
    virtual BOOL Post(
      PHTTPRequest & request,
      const PStringToString &,
      PHTML & msg
    );
  
  private:
    OpenMCU & app;
};

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

OpenMCU::OpenMCU()
  : OpenMCUProcessAncestor(ProductInfo)
{
  endpoint = NULL;
}

void OpenMCU::Main()
{
  Suspend();
}

BOOL OpenMCU::OnStart()
{
  // change to the default directory to the one containing the executable
  PDirectory exeDir = GetFile().GetDirectory();

#if defined(_WIN32) && defined(_DEBUG)
  // Special check to aid in using DevStudio for debugging.
  if (exeDir.Find("\\Debug\\") != P_MAX_INDEX)
    exeDir = exeDir.GetParent();
#endif
  exeDir.Change();

  httpNameSpace.AddResource(new PHTTPDirectory("data", "data"));
  httpNameSpace.AddResource(new PServiceHTTPDirectory("html", "html"));

  endpoint = new MyH323EndPoint();

  return PHTTPServiceProcess::OnStart();
}

void OpenMCU::OnStop()
{
  delete endpoint;
  endpoint = NULL;

  PHTTPServiceProcess::OnStop();
}

void OpenMCU::OnControl()
{
  // This function get called when the Control menu item is selected in the
  // tray icon mode of the service.
  PStringStream url;
  url << "http://";

  PString host = PIPSocket::GetHostName();
  PIPSocket::Address addr;
  if (PIPSocket::GetHostAddress(host, addr))
    url << host;
  else
    url << "localhost";

  url << ':' << DefaultHTTPPort;

  PURL::OpenBrowser(url);
}

BOOL OpenMCU::Initialise(const char * initMsg)
{
  PConfig cfg("Parameters");

  // Set log level as early as possible
  SetLogLevel((PSystemLog::Level)cfg.GetInteger(LogLevelKey, GetLogLevel()));
#if PTRACING
  if (GetLogLevel() >= PSystemLog::Warning)
    PTrace::SetLevel(GetLogLevel()-PSystemLog::Warning);
  else
    PTrace::SetLevel(0);
  PTrace::ClearOptions(PTrace::Timestamp);
  PTrace::SetOptions(PTrace::DateAndTime);
#endif

  // Get the HTTP basic authentication info
  PString adminUserName = cfg.GetString(UserNameKey);
  PString adminPassword = PHTTPPasswordField::Decrypt(cfg.GetString(PasswordKey));

  PHTTPSimpleAuth authority(GetName(), adminUserName, adminPassword);

  // Create the parameters URL page, and start adding fields to it
  PConfigPage * rsrc = new PConfigPage(*this, "Parameters", "Parameters", authority);

  // HTTP authentication username/password
  rsrc->Add(new PHTTPStringField(UserNameKey, 25, adminUserName));
  rsrc->Add(new PHTTPPasswordField(PasswordKey, 25, adminPassword));

  // Log level for messages
  rsrc->Add(new PHTTPIntegerField(LogLevelKey,
                                  PSystemLog::Fatal, PSystemLog::NumLogLevels-1,
                                  GetLogLevel(),
                                  "1=Fatal only, 2=Errors, 3=Warnings, 4=Info, 5=Debug"));

#if P_SSL
  // SSL certificate file.
  PString certificateFile = cfg.GetString(HTTPCertificateFileKey, "server.pem");
  rsrc->Add(new PHTTPStringField(HTTPCertificateFileKey, 25, certificateFile));
  if (!SetServerCertificate(certificateFile, TRUE)) {
    PSYSTEMLOG(Fatal, "BMAC\tCould not load certificate \"" << certificateFile << '"');
    return FALSE;
  }
#endif

  // HTTP Port number to use.
  WORD httpPort = (WORD)cfg.GetInteger(HttpPortKey, DefaultHTTPPort);
  rsrc->Add(new PHTTPIntegerField(HttpPortKey, 1, 32767, httpPort));

  endpoint->Initialise(cfg, rsrc);

  // get default "room" (conference) name
  defaultRoomName = cfg.GetString(DefaultRoomKey, DefaultRoom);
  rsrc->Add(new PHTTPStringField(DefaultRoomKey, 25, defaultRoomName));

  // get WAV file played to a user when they enter a conference
  connectingWAVFile = cfg.GetString(ConnectingWAVFileKey, DefaultConnectingWAVFile);
  rsrc->Add(new PHTTPStringField(ConnectingWAVFileKey, 50, connectingWAVFile));

  // get WAV file played to a conference when a new user enters
  enteringWAVFile = cfg.GetString(EnteringWAVFileKey, DefaultEnteringWAVFile);
  rsrc->Add(new PHTTPStringField(EnteringWAVFileKey, 50, enteringWAVFile));

  // get WAV file played to a conference when a new user enters
  leavingWAVFile = cfg.GetString(LeavingWAVFileKey, DefaultLeavingWAVFile);
  rsrc->Add(new PHTTPStringField(LeavingWAVFileKey, 50, leavingWAVFile));

  // default log file name
  logFilename = cfg.GetString(CallLogFilenameKey, DefaultCallLogFilename);
  rsrc->Add(new PHTTPStringField(CallLogFilenameKey, 50, logFilename));

  // see if audio loopback is required
  //audioLoopbackRoom = args.GetOptionString("audio-loopback");

  // get singleStream flag
  //endpoint.singleStream = args.HasOption("single-stream");

#ifndef NO_MCU_VIDEO
  // If videoLarge was specified
  endpoint.videoLarge = args.HasOption("videolarge");

  if (args.HasOption('v')) {
    //Add capability to allow the reception of video.

    // this is the only way I know of at present to transmit
    // CIF size video - pez
    // Do not allow CIF video if size is medium
    if (endpoint.videoLarge)
      endpoint.SetCapability(0, 1, new H323_H261Capability(0, 4, FALSE, FALSE, 6217)); // CIF
      endpoint.SetCapability(0, 1, new H323_H261Capability(2, 0, FALSE, FALSE, 6217)); // QCIF
  } 
#endif

  // Finished the resource to add, generate HTML for it and add to name space
  PServiceHTML html("System Parameters");
  rsrc->BuildHTML(html);
  httpNameSpace.AddResource(rsrc, PHTTPSpace::Overwrite);

  // Create the status page
  httpNameSpace.AddResource(new MainStatusPage(*this, authority), PHTTPSpace::Overwrite);

  // Add log file links
  if (!systemLogFileName && systemLogFileName != "-") {
    httpNameSpace.AddResource(new PHTTPFile("logfile.txt", systemLogFileName, authority));
    httpNameSpace.AddResource(new PHTTPTailFile("tail_logfile", systemLogFileName, authority));
  }

  //  create the home page
  static const char welcomeHtml[] = "welcome.html";
  if (PFile::Exists(welcomeHtml))
    httpNameSpace.AddResource(new PServiceHTTPFile(welcomeHtml, TRUE), PHTTPSpace::Overwrite);
  else {
    PHTML html;
    html << PHTML::Title("Welcome to OpenMCU")
         << PHTML::Body()
         << GetPageGraphic()
         << PHTML::Paragraph() << "<center>"

         << PHTML::HotLink("Parameters") << "Parameters" << PHTML::HotLink()
         << PHTML::Paragraph()
         << PHTML::HotLink("Status") << "Status" << PHTML::HotLink()
         << PHTML::Paragraph();

    if (!systemLogFileName && systemLogFileName != "-")
      html << PHTML::HotLink("logfile.txt") << "Full Log File" << PHTML::HotLink()
           << PHTML::BreakLine()
           << PHTML::HotLink("tail_logfile") << "Tail Log File" << PHTML::HotLink()
           << PHTML::Paragraph();
 
    html << PHTML::HRule()
         << GetCopyrightText()
         << PHTML::Body();
    httpNameSpace.AddResource(new PServiceHTTPString("welcome.html", html), PHTTPSpace::Overwrite);
  }

  // create monitoring page
  PString monitorText = "<!--#equival monitorinfo-->"
                        "Current Proxies: <!--#equival ProxyCount-->\n";
  httpNameSpace.AddResource(new PServiceHTTPString("monitor.txt", monitorText, "text/plain", authority), PHTTPSpace::Overwrite);

  // set up the HTTP port for listening & start the first HTTP thread
  if (ListenForHTTP(httpPort))
    PSYSTEMLOG(Info, "Opened master socket for HTTP: " << httpListeningSocket->GetPort());
  else {
    PSYSTEMLOG(Fatal, "Cannot run without HTTP port: " << httpListeningSocket->GetErrorText());
    return FALSE;
  }

  PSYSTEMLOG(Info, "Service " << GetName() << ' ' << initMsg);
  return TRUE;
}

void OpenMCU::OnConfigChanged()
{
}



PString OpenMCU::GetNewRoomNumber()
{
  static PAtomicInteger number = 100;
  return PString(PString::Unsigned, ++number);
}

void OpenMCU::LogMessage(const PString & str)
{
  static PMutex logMutex;
  static PTextFile logFile;

  PTime now;
  PString msg = now.AsString("dd/MM/yyyy") & str;
  logMutex.Wait();

  if (!logFile.IsOpen()) {

⌨️ 快捷键说明

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