📄 main.cxx
字号:
/*
* main.cxx
*
* A simple H.323 "net telephone" application.
*
* Copyright (c) 2000 Equivalence Pty. Ltd.
*
* 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.
*
* Contributor(s): ______________________________________.
*
* $Log: main.cxx,v $
* Revision 1.3 2006/05/16 18:49:58 shorne
* Added more ReleaseComplete notifications
*
* Revision 1.2 2006/05/16 16:07:41 shorne
* removed old revision information
*
* Revision 1.1 2006/05/16 16:03:38 shorne
* Initial commit
*
*
*/
#include <ptlib.h>
#ifdef __GNUC__
#define H323_STATIC_LIB
#endif
#include "main.h"
#include "version.h"
#include <h323pdu.h>
#include <h460.h>
#define new PNEW
PCREATE_PROCESS(MyH323Process);
///////////////////////////////////////////////////////////////
MyH323Process::MyH323Process()
: PProcess("OpenH323 Project", "MyH323",
MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER)
{
endpoint = NULL;
}
MyH323Process::~MyH323Process()
{
delete endpoint;
}
void MyH323Process::Main()
{
cout << GetName()
<< " Version " << GetVersion(TRUE)
<< " by " << GetManufacturer()
<< " on " << GetOSClass() << ' ' << GetOSName()
<< " (" << GetOSVersion() << '-' << GetOSHardware() << ")\n\n";
// Get and parse all of the command line arguments.
PArgList & args = GetArguments();
args.Parse(
"a-auto-answer."
"b-bandwidth:"
"B-forward-busy:"
"D-disable:"
"e-silence."
"f-fast-disable."
"g-gatekeeper:"
"h-help."
"i-interface:"
"j-jitter:"
"l-listen."
"n-no-gatekeeper."
#if PTRACING
"o-output:"
#endif
#ifdef H323_TRANSNEXUS_OSP
"-osp:"
"-ospdir:"
#endif
"-osptoken."
"P-prefer:"
"p-password:"
"r-require-gatekeeper."
"s-sound:"
"-sound-in:"
"-sound-out:"
"T-h245tunneldisable."
#if PTRACING
"t-trace."
#endif
"u-user:"
, FALSE);
if (args.HasOption('h') || (!args.HasOption('l') && args.GetCount() == 0)) {
cout << "Usage : " << GetName() << " [options] -l\n"
" : " << GetName() << " [options] [alias@]hostname (no gatekeeper)\n"
" : " << GetName() << " [options] alias[@hostname] (with gatekeeper)\n"
"Options:\n"
" -l --listen : Listen for incoming calls.\n"
" -g --gatekeeper host : Specify gatekeeper host.\n"
" -n --no-gatekeeper : Disable gatekeeper discovery.\n"
" -r --require-gatekeeper : Exit if gatekeeper discovery fails.\n"
" -a --auto-answer : Automatically answer incoming calls.\n"
" -u --user name : Set local alias name(s) (defaults to login name).\n"
" -p --password pwd : Set the H.235 password to use for calls.\n"
" -b --bandwidth bps : Limit bandwidth usage to bps bits/second.\n"
" -j --jitter [min-]max : Set minimum (optional) and maximum jitter buffer (in milliseconds).\n"
" -D --disable codec : Disable the specified codec (may be used multiple times)\n"
" -P --prefer codec : Prefer the specified codec (may be used multiple times)\n"
" -i --interface ipnum : Select interface to bind to.\n"
" -B --forward-busy party : Forward to remote party if busy.\n"
" -e --silence : Disable transmitter silence detection.\n"
" -f --fast-disable : Disable fast start.\n"
" -T --h245tunneldisable : Disable H245 tunnelling.\n"
" -s --sound device : Select sound input/output device.\n"
" --sound-in device : Select sound input device.\n"
" --sound-out device : Select sound output device.\n"
#ifdef H323_TRANSNEXUS_OSP
" --osp server : Use OSP server for number resolution (disable GK if selected).\n"
" --ospdir dir : Directory in which OSP certs are stored\n"
#endif
" --osptoken : Copy OSP tokens (if present) from ACF to SETUP\n"
#if PTRACING
" -t --trace : Enable trace, use multiple times for more detail.\n"
" -o --output : File for trace output, default is stderr.\n"
#endif
" -h --help : This help message.\n"
<< endl;
return;
}
#if PTRACING
PTrace::Initialise(args.GetOptionCount('t'),
args.HasOption('o') ? (const char *)args.GetOptionString('o') : NULL);
#endif
// Create the H.323 endpoint and initialise it
endpoint = new MyH323EndPoint;
if (!endpoint->Initialise(args))
return;
// See if making a call or just listening.
if (args.HasOption('l'))
cout << "Waiting for incoming calls for \"" << endpoint->GetLocalUserName() << "\"\n";
else {
cout << "Initiating call to \"" << args[0] << "\"\n";
endpoint->MakeCall(args[0], endpoint->currentCallToken);
}
cout << "Press X to exit." << endl;
// Simplest possible user interface
for (;;) {
cout << "H323> " << flush;
PCaselessString cmd;
cin >> cmd;
if (cmd == "X")
break;
// if (cmd.FindOneOf("HYN0123456789ABCD") != P_MAX_INDEX) {
MyH323Connection * connection = (MyH323Connection *)endpoint->FindConnectionWithLock(endpoint->currentCallToken);
if (connection != NULL) {
if (cmd == "H")
connection->ClearCall();
else if (cmd == "Y")
connection->AnsweringCall(H323Connection::AnswerCallNow);
else if (cmd == "N")
connection->AnsweringCall(H323Connection::AnswerCallDenied);
else if (cmd == "T")
if (!connection->IMsession)
endpoint->IMOpenSession(endpoint->currentCallToken);
else
endpoint->IMCloseSession(endpoint->currentCallToken);
else if (connection->IMsession)
endpoint->SendIM(endpoint->currentCallToken, cmd);
else
connection->SendUserInput(cmd);
connection->Unlock();
}
else if ((cmd.GetLength() > 1) &&
((cmd.Left(1) == "c") || (cmd.Left(1) == "t"))) {
PStringArray Cmd = cmd.Tokenise("'",FALSE);
if (cmd.Left(1) == "t") {
endpoint->IMCall = TRUE; // Is an IM Call
if (Cmd.GetSize() > 1)
endpoint->IMmsg = Cmd[1]; // Message to send and disconnect
else
endpoint->IMsession = TRUE; // Start an IM Session
}
PString number = Cmd[0].Right(Cmd[0].GetLength()-2).Trim();
endpoint->MakeCall(number,endpoint->currentCallToken);
}
else
cout << "Oops something is wrong!" << endl;
// }
}
cout << "Exiting " << GetName() << endl;
}
///////////////////////////////////////////////////////////////
MyH323EndPoint::MyH323EndPoint()
{
currentCallToken = PString();
IMsession = FALSE;
IMCall = FALSE;
IMmsg = PString();
}
MyH323EndPoint::~MyH323EndPoint()
{
}
BOOL MyH323EndPoint::Initialise(PArgList & args)
{
// Get local username, multiple uses of -u indicates additional aliases
if (args.HasOption('u')) {
PStringArray aliases = args.GetOptionString('u').Lines();
SetLocalUserName(aliases[0]);
for (PINDEX i = 1; i < aliases.GetSize(); i++)
AddAliasName(aliases[i]);
}
// Set the various options
SetSilenceDetectionMode(args.HasOption('e') ? H323AudioCodec::NoSilenceDetection
: H323AudioCodec::AdaptiveSilenceDetection);
DisableFastStart(args.HasOption('f'));
DisableH245Tunneling(args.HasOption('T'));
autoAnswer = args.HasOption('a');
busyForwardParty = args.GetOptionString('B');
if (args.HasOption('b')) {
initialBandwidth = args.GetOptionString('b').AsUnsigned()*100;
if (initialBandwidth == 0) {
cerr << "Illegal bandwidth specified." << endl;
return FALSE;
}
}
if (args.HasOption('j')) {
unsigned minJitter;
unsigned maxJitter;
PStringArray delays = args.GetOptionString('j').Tokenise(",-");
if (delays.GetSize() < 2) {
maxJitter = delays[0].AsUnsigned();
minJitter = PMIN(GetMinAudioJitterDelay(), maxJitter);
}
else {
minJitter = delays[0].AsUnsigned();
maxJitter = delays[1].AsUnsigned();
}
if (minJitter >= 20 && minJitter <= maxJitter && maxJitter <= 1000)
SetAudioJitterDelay(minJitter, maxJitter);
else {
cerr << "Jitter should be between 20 and 1000 milliseconds." << endl;
return FALSE;
}
}
if (!SetSoundDevice(args, "sound", PSoundChannel::Recorder))
return FALSE;
if (!SetSoundDevice(args, "sound", PSoundChannel::Player))
return FALSE;
if (!SetSoundDevice(args, "sound-in", PSoundChannel::Recorder))
return FALSE;
if (!SetSoundDevice(args, "sound-out", PSoundChannel::Player))
return FALSE;
// Set the default codecs available on sound cards.
AddAllCapabilities(0, 0, "*");
AddAllUserInputCapabilities(0, 1);
RemoveCapabilities(args.GetOptionString('D').Lines());
ReorderCapabilities(args.GetOptionString('P').Lines());
cout << "Local username: " << GetLocalUserName() << "\n"
<< "Silence compression is " << (GetSilenceDetectionMode() == H323AudioCodec::NoSilenceDetection ? "Dis" : "En") << "abled\n"
<< "Auto answer is " << autoAnswer << "\n"
<< "FastConnect is " << (IsFastStartDisabled() ? "Dis" : "En") << "abled\n"
<< "H245Tunnelling is " << (IsH245TunnelingDisabled() ? "Dis" : "En") << "abled\n"
<< "Jitter buffer: " << GetMinAudioJitterDelay() << '-' << GetMaxAudioJitterDelay() << " ms\n"
<< "Sound output device: \"" << GetSoundChannelPlayDevice() << "\"\n"
"Sound input device: \"" << GetSoundChannelRecordDevice() << "\"\n"
<< "Codecs (in preference order):\n" << setprecision(2) << GetCapabilities() << endl;
/////////////////////////////////////////
// List all the available Features
PStringList features = H460_Feature::GetFeatureNames();
cout << "Available Features: " << endl;
for (PINDEX i = 0; i < features.GetSize(); i++) {
PStringList names = H460_Feature::GetFeatureFriendlyNames(features[i]);
for (PINDEX j = 0; j < names.GetSize(); j++)
cout << features[i] <<" " << names[j] << endl;
}
cout << endl;
/////////////////////////////////////////
// Start the listener thread for incoming calls.
H323TransportAddress iface = args.GetOptionString('i');
if (iface.IsEmpty())
iface = "*";
if (!StartListener(iface)) {
cerr << "Could not open H.323 listener port on \"" << iface << '"' << endl;
return FALSE;
}
// Initialise the security info
if (args.HasOption('p')) {
SetGatekeeperPassword(args.GetOptionString('p'));
cout << "Enabling H.235 security access to gatekeeper." << endl;
}
#ifdef H323_TRANSNEXUS_OSP
if (args.HasOption("osp")) {
PDirectory ospDir;
if (args.HasOption("ospdir"))
ospDir = args.GetOptionString("ospdir");
SetOSPProvider(args.GetOptionString("osp"));
}
else
#endif
// Establish link with gatekeeper if required.
if (args.HasOption('g') || !args.HasOption('n')) {
H323TransportUDP * rasChannel;
if (args.GetOptionString('i').IsEmpty())
rasChannel = new H323TransportUDP(*this);
else {
PIPSocket::Address interfaceAddress(args.GetOptionString('i'));
rasChannel = new H323TransportUDP(*this, interfaceAddress);
}
if (args.HasOption('g')) {
PString gkName = args.GetOptionString('g');
if (SetGatekeeper(gkName, rasChannel))
cout << "Gatekeeper set: " << *gatekeeper << endl;
else {
cerr << "Error registering with gatekeeper at \"" << gkName << '"' << endl;
return FALSE;
}
}
else {
cout << "Searching for gatekeeper..." << flush;
if (DiscoverGatekeeper(rasChannel))
cout << "\nGatekeeper found: " << *gatekeeper << endl;
else {
cerr << "\nNo gatekeeper found." << endl;
if (args.HasOption('r'))
return FALSE;
}
}
}
// osptoken option only makes sense if gatekeeper is being used
if ((gatekeeper != NULL) && args.HasOption("osptoken"))
SetGkAccessTokenOID(OpalOSP::ETSIXMLTokenOID);
return TRUE;
}
BOOL MyH323EndPoint::SetSoundDevice(PArgList & args,
const char * optionName,
PSoundChannel::Directions dir)
{
if (!args.HasOption(optionName))
return TRUE;
PString dev = args.GetOptionString(optionName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -