📄 main.cxx
字号:
// Allow for [ipaddr]:port form, especially for IPv6
PINDEX pos = interfaceStr.Find(']');
if (pos == P_MAX_INDEX)
pos = 0;
pos = interfaceStr.Find(':', pos);
if (pos != P_MAX_INDEX) {
interfacePort = (WORD)interfaceStr.Mid(pos+1).AsInteger();
interfaceStr = interfaceStr.Left(pos);
}
interfacePrintable &= interfaceStr + ":" + PString(PString::Unsigned, interfacePort);
PIPSocket::Address interfaceAddress(interfaceStr);
H323ListenerTCP * listener = new H323ListenerTCP(*this, interfaceAddress, interfacePort);
if (!StartListener(listener)) {
cout << "Could not open H.323 listener port on "
<< interfaceAddress << ":" << interfacePort << endl;
delete listener;
return FALSE;
}
}
}
if (verbose >= 3)
cout << "Listening interfaces : " << interfacePrintable << endl;
if (args.HasOption("translate")) {
masqAddressPtr = new PIPSocket::Address(args.GetOptionString("translate"));
behind_masq = TRUE;
cout << "Masquerading as address " << *(masqAddressPtr) << endl;
} else {
behind_masq = FALSE;
}
if (args.HasOption("stun")) {
PString stunServer = args.GetOptionString("stun");
SetSTUNServer(stunServer);
}
// Initialise the security info
if (args.HasOption("password")) {
SetGatekeeperPassword(args.GetOptionString("password"));
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"), ospDir);
}
else
#endif
SetSendGRQ(!args.HasOption("disable-grq"));
if (args.HasOption('g')) {
PString gkName = args.GetOptionString('g');
H323TransportUDP * rasChannel;
if (args.GetOptionString('i').IsEmpty())
rasChannel = new H323TransportUDP(*this);
else {
PIPSocket::Address interfaceAddress(args.GetOptionString('i'));
rasChannel = new H323TransportUDP(*this, interfaceAddress);
}
if (SetGatekeeper(gkName, rasChannel)) {
if (verbose >= 3)
cout << "Gatekeeper set: " << *gatekeeper << endl;
} else {
cout << "Error registering with gatekeeper at \"" << gkName << '"' << endl;
return FALSE;
}
}
else if (args.HasOption('G')) {
PString gkIdentifier = args.GetOptionString('G');
if (verbose >= 2)
cout << "Searching for gatekeeper with id \"" << gkIdentifier << "\" ..." << flush;
if (LocateGatekeeper(gkIdentifier)) {
if (verbose >= 3)
cout << "Gatekeeper set: " << *gatekeeper << endl;
} else {
cout << "Error registering with gatekeeper at \"" << gkIdentifier << '"' << endl;
return FALSE;
}
}
else if (!args.HasOption('n') || args.HasOption('r')) {
if (verbose >= 2)
cout << "Searching for gatekeeper..." << flush;
if (DiscoverGatekeeper(new H323TransportUDP(*this))) {
if (verbose >= 2)
cout << "\nGatekeeper found: " << *gatekeeper << endl;
} else {
if (verbose >= 2)
cout << "\nNo gatekeeper found." << endl;
if (args.HasOption("require-gatekeeper"))
return FALSE;
}
}
// osptoken option only makes sense if gatekeeper is being used
if ((gatekeeper != NULL) && args.HasOption("osptoken"))
SetGkAccessTokenOID(OpalOSP::ETSIXMLTokenOID);
ringThread = NULL;
if (!args.HasOption("autodisconnect"))
autoDisconnect = 0;
else {
autoDisconnect = args.GetOptionString("autodisconnect").AsInteger();
if (autoDisconnect < 0) {
cout << "autodisconnect must be > 0" << endl;
return FALSE;
}
}
return TRUE;
}
#ifdef HAS_OSS
BOOL MyH323EndPoint::InitialiseMixer(PConfigArgs & args, int _verbose)
{
mixerDev = -1;
// make sure mixer isn't disabled
if (args.HasOption("no-sound-mixer"))
return TRUE;
PString mixerDeviceName = DEFAULT_MIXER;
if (args.HasOption("sound-mixer"))
mixerDeviceName = args.GetOptionString("sound-mixer");
mixerDev = ::open(mixerDeviceName, O_RDWR);
if (mixerDev < 0) {
cout << "warning: Cannot open mixer device " << mixerDeviceName
<< ": " << ::strerror(errno) << endl;
return TRUE;
}
char * mixerChanNames[] = SOUND_DEVICE_NAMES;
int numMixerChans = SOUND_MIXER_NRDEVICES;
// get the current record channel setting, and save it
if (::ioctl(mixerDev, SOUND_MIXER_READ_RECSRC, &savedMixerRecChan) < 0) {
cout << "warning: cannot get current mixer record channels" << endl;
savedMixerRecChan = -1;
}
// if the user specified a record channel, then find it
// otherwise, find the currently select record channel
if (args.HasOption("sound-recchan")) {
PCaselessString mixerRecChanName = args.GetOptionString("sound-recchan");
int i;
for (i = 0; i < numMixerChans; i++)
if (mixerRecChanName *= mixerChanNames[i])
break;
if (i == numMixerChans) {
cout << "error: Cannot find record mixer channel " << mixerDeviceName << endl;
return FALSE;
}
mixerRecChan = i;
} else {
int i;
for (i = 0; i < numMixerChans; i++)
if (savedMixerRecChan & (1 << i))
break;
if (i == numMixerChans)
mixerRecChan = SOUND_MIXER_MIC;
else
mixerRecChan = i;
}
PString volStr;
if (args.HasOption("sound-recvol"))
volStr = args.GetOptionString("sound-recvol");
else if (args.HasOption("recvol"))
volStr = args.GetOptionString("recvol");
if (volStr.IsEmpty()) {
::ioctl(mixerDev, MIXER_READ(mixerRecChan), &ossRecVol);
ossRecVol &= 0xff;
} else {
ossRecVol = (unsigned)volStr.AsReal();
int volVal = ossRecVol | (ossRecVol << 8);
::ioctl(mixerDev, MIXER_WRITE(mixerRecChan), &volVal);
}
if (args.HasOption("sound-playvol"))
volStr = args.GetOptionString("sound-playvol");
else if (args.HasOption("playvol"))
volStr = args.GetOptionString("playvol");
if (volStr.IsEmpty()) {
::ioctl(mixerDev, SOUND_MIXER_READ_VOLUME, &ossPlayVol);
ossPlayVol &= 0xff;
} else {
ossPlayVol = (unsigned)volStr.AsReal();
int volVal = ossPlayVol | (ossPlayVol << 8);
::ioctl(mixerDev, SOUND_MIXER_WRITE_PCM, &volVal);
}
if (verbose >= 3) {
cout << "Recording using mixer channel " << mixerChanNames[mixerRecChan] << endl;
cout << "Record volume is " << ossRecVol << endl;
cout << "Play volume is " << ossPlayVol << endl;
}
return TRUE;
}
#endif
BOOL MyH323EndPoint::SetSoundDevice(PConfigArgs & args,
const char * deviceOptName,
const char * driverOptName,
PSoundChannel::Directions dir,
BOOL force)
{
if (!force && !args.HasOption(deviceOptName) && !args.HasOption(driverOptName))
return FALSE;
PStringList driverNames = PSoundChannel::GetDriverNames();
PString driverName = args.GetOptionString(driverOptName);
if (driverNames.IsEmpty()) {
cout << "No sound drivers available!" << endl;
return FALSE;
}
if (driverName.IsEmpty())
driverName = args.GetOptionString("sound-driver");
if (!driverName.IsEmpty() && driverNames.GetStringsIndex(driverName) == P_MAX_INDEX) {
cout << "Sound driver must be one of\n"
<< setfill('\n') << driverNames << setfill(' ')
<< endl;
return FALSE;
}
PStringList deviceNames = driverName.IsEmpty() ? PSoundChannel::GetDeviceNames(dir)
: PSoundChannel::GetDriversDeviceNames(driverName, dir);
if (deviceNames.IsEmpty()) {
cout << "No sound devices available!" << endl;
return FALSE;
}
PString deviceName = args.GetOptionString(deviceOptName);
if (deviceName.IsEmpty())
deviceName = deviceNames[0];
if (!driverName.IsEmpty())
driverName += PDevicePluginServiceDescriptor::SeparatorChar;
if (dir == PSoundChannel::Player) {
if (SetSoundChannelPlayDevice(driverName+deviceName))
return TRUE;
}
else {
if (SetSoundChannelRecordDevice(driverName+deviceName))
return TRUE;
}
cout << "Argument to " << deviceOptName << " must be one of\n"
<< setfill('\n') << deviceNames << setfill(' ') << endl;
return FALSE;
}
H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference)
{
unsigned options = 0;
if (currentCallOptions.noFastStart)
options |= H323Connection::FastStartOptionDisable;
if (currentCallOptions.noH245Tunnelling)
options |= H323Connection::H245TunnelingOptionDisable;
if (currentCallOptions.noH245InSetup)
options |= H323Connection::H245inSetupOptionDisable;
return new MyH323Connection(*this, callReference,
options,
currentCallOptions.minJitter,
currentCallOptions.maxJitter,
verbose);
}
BOOL MyH323EndPoint::OnIncomingCall(H323Connection & connection,
const H323SignalPDU & setupPDU,
H323SignalPDU &)
{
// get the default call options
currentCallOptions = defaultCallOptions;
// get remote address so we can call back later
PString lastCallingParty = connection.GetSignallingChannel()->GetRemoteAddress().GetHostName();
PConfig config("Callers");
int index = config.GetInteger("index");
PString lastLastCallingParty = config.GetString(PString(PString::Unsigned, index));
index = (index + 1) % LAST_CALL_COUNT;
PTime now;
PString indexStr = PString(PString::Unsigned, index);
config.SetString(indexStr, lastCallingParty);
config.SetString(indexStr + "_Time", now.AsString());
config.SetString("index", indexStr);
// Check for setup parameter
if (setupPDU.m_h323_uu_pdu.HasOptionalField(H225_H323_UU_PDU::e_nonStandardData)) {
PString param = setupPDU.m_h323_uu_pdu.m_nonStandardData.m_data.AsString();
if (!param)
cout << "Received non-standard parameter data in Setup PDU: \"" << param << "\"." << endl;
}
if (!alwaysForwardParty.IsEmpty()) {
cout << "Forwarding call to \"" << alwaysForwardParty << "\"." << endl;
return !connection.ForwardCall(alwaysForwardParty);
}
// incoming call is accepted if no call in progress
// unless the xJack is open and phone is off onhook
if (!currentCallToken.IsEmpty())
cout << "WARNING: current call token not empty" << endl;
if (currentCallToken.IsEmpty()
#if defined(HAS_LIDDEVICE)
&& !((lidDevice != NULL) && lidDevice->IsOpen() && (!autoHook && lidDevice->IsLineOffHook(POTS_LINE)))
#endif
) {
// get the current call token
currentCallToken = connection.GetCallToken();
return TRUE;
}
if (busyForwardParty.IsEmpty()) {
PTime
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -