📄 main.cxx
字号:
/*
* 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 + -