📄 manager.cxx
字号:
OpalT38Protocol * OpalManager::CreateT38ProtocolHandler(const OpalConnection & ) const
{
return NULL;
}
OpalH224Handler * OpalManager::CreateH224ProtocolHandler(OpalConnection & connection,
unsigned sessionID) const
{
#ifdef OPAL_H224
return new OpalH224Handler(connection, sessionID);
#else
return NULL;
#endif
}
OpalH281Handler * OpalManager::CreateH281ProtocolHandler(OpalH224Handler & h224Handler) const
{
#ifdef OPAL_H224
return new OpalH281Handler(h224Handler);
#else
return NULL;
#endif
}
OpalManager::RouteEntry::RouteEntry(const PString & pat, const PString & dest)
: pattern(pat),
destination(dest),
regex('^'+pat+'$')
{
}
void OpalManager::RouteEntry::PrintOn(ostream & strm) const
{
strm << pattern << '=' << destination;
}
BOOL OpalManager::AddRouteEntry(const PString & spec)
{
if (spec[0] == '#') // Comment
return FALSE;
if (spec[0] == '@') { // Load from file
PTextFile file;
if (!file.Open(spec.Mid(1), PFile::ReadOnly)) {
PTRACE(1, "OpalMan\tCould not open route file \"" << file.GetFilePath() << '"');
return FALSE;
}
PTRACE(4, "OpalMan\tAdding routes from file \"" << file.GetFilePath() << '"');
BOOL ok = FALSE;
PString line;
while (file.good()) {
file >> line;
if (AddRouteEntry(line))
ok = TRUE;
}
return ok;
}
PINDEX equal = spec.Find('=');
if (equal == P_MAX_INDEX) {
PTRACE(2, "OpalMan\tInvalid route table entry: \"" << spec << '"');
return FALSE;
}
RouteEntry * entry = new RouteEntry(spec.Left(equal).Trim(), spec.Mid(equal+1).Trim());
if (entry->regex.GetErrorCode() != PRegularExpression::NoError) {
PTRACE(1, "OpalMan\tIllegal regular expression in route table entry: \"" << spec << '"');
delete entry;
return FALSE;
}
PTRACE(4, "OpalMan\tAdded route \"" << *entry << '"');
routeTableMutex.Wait();
routeTable.Append(entry);
routeTableMutex.Signal();
return TRUE;
}
BOOL OpalManager::SetRouteTable(const PStringArray & specs)
{
BOOL ok = FALSE;
routeTableMutex.Wait();
routeTable.RemoveAll();
for (PINDEX i = 0; i < specs.GetSize(); i++) {
if (AddRouteEntry(specs[i].Trim()))
ok = TRUE;
}
routeTableMutex.Signal();
return ok;
}
void OpalManager::SetRouteTable(const RouteTable & table)
{
routeTableMutex.Wait();
routeTable = table;
routeTable.MakeUnique();
routeTableMutex.Signal();
}
PString OpalManager::ApplyRouteTable(const PString & proto, const PString & addr)
{
PWaitAndSignal mutex(routeTableMutex);
PString destination;
PString search = proto + ':' + addr;
PTRACE(4, "OpalMan\tSearching for route \"" << search << '"');
for (PINDEX i = 0; i < routeTable.GetSize(); i++) {
RouteEntry & entry = routeTable[i];
PINDEX pos;
if (entry.regex.Execute(search, pos)) {
destination = routeTable[i].destination;
break;
}
}
if (destination.IsEmpty())
return PString::Empty();
destination.Replace("<da>", addr);
PINDEX pos;
if ((pos = destination.Find("<dn>")) != P_MAX_INDEX)
destination.Splice(addr.Left(::strspn(addr, "0123456789*#")), pos, 4);
if ((pos = destination.Find("<!dn>")) != P_MAX_INDEX)
destination.Splice(addr.Mid(::strspn(addr, "0123456789*#")), pos, 5);
// Do meta character substitutions
if ((pos = destination.Find("<dn2ip>")) != P_MAX_INDEX) {
PStringStream route;
PStringArray stars = addr.Tokenise('*');
switch (stars.GetSize()) {
case 0 :
case 1 :
case 2 :
case 3 :
route << addr;
break;
case 4 :
route << stars[0] << '.' << stars[1] << '.'<< stars[2] << '.'<< stars[3];
break;
case 5 :
route << stars[0] << '@'
<< stars[1] << '.' << stars[2] << '.'<< stars[3] << '.'<< stars[4];
break;
default :
route << stars[0] << '@'
<< stars[1] << '.' << stars[2] << '.'<< stars[3] << '.'<< stars[4]
<< ':' << stars[5];
break;
}
destination.Splice(route, pos, 7);
}
return destination;
}
BOOL OpalManager::IsLocalAddress(const PIPSocket::Address & ip) const
{
/* Check if the remote address is a private IP, broadcast, or us */
return ip.IsRFC1918() || ip.IsBroadcast() || PIPSocket::IsLocalHost(ip);
}
BOOL OpalManager::TranslateIPAddress(PIPSocket::Address & localAddress,
const PIPSocket::Address & remoteAddress)
{
if (!translationAddress.IsValid())
return FALSE; // Have nothing to translate it to
if (!IsLocalAddress(localAddress))
return FALSE; // Is already translated
if (IsLocalAddress(remoteAddress))
return FALSE; // Does not need to be translated
// Tranlsate it!
localAddress = translationAddress;
return TRUE;
}
PSTUNClient * OpalManager::GetSTUN(const PIPSocket::Address & ip) const
{
if (ip.IsValid() && IsLocalAddress(ip))
return NULL;
return stun;
}
PSTUNClient::NatTypes OpalManager::SetSTUNServer(const PString & server)
{
delete stun;
if (server.IsEmpty()) {
stun = NULL;
return PSTUNClient::UnknownNat;
}
stun = new PSTUNClient(server,
GetUDPPortBase(), GetUDPPortMax(),
GetRtpIpPortBase(), GetRtpIpPortMax());
PSTUNClient::NatTypes type = stun->GetNatType();
if (type != PSTUNClient::BlockedNat)
stun->GetExternalAddress(translationAddress);
PTRACE(2, "OPAL\tSTUN server \"" << server << "\" replies " << type << ", external IP " << translationAddress);
return type;
}
void OpalManager::PortInfo::Set(unsigned newBase,
unsigned newMax,
unsigned range,
unsigned dflt)
{
if (newBase == 0) {
newBase = dflt;
newMax = dflt;
if (dflt > 0)
newMax += range;
}
else {
if (newBase < 1024)
newBase = 1024;
else if (newBase > 65500)
newBase = 65500;
if (newMax <= newBase)
newMax = newBase + range;
if (newMax > 65535)
newMax = 65535;
}
mutex.Wait();
current = base = (WORD)newBase;
max = (WORD)newMax;
mutex.Signal();
}
WORD OpalManager::PortInfo::GetNext(unsigned increment)
{
PWaitAndSignal m(mutex);
if (current < base || current >= (max-increment))
current = base;
if (current == 0)
return 0;
WORD p = current;
current = (WORD)(current + increment);
return p;
}
void OpalManager::SetTCPPorts(unsigned tcpBase, unsigned tcpMax)
{
tcpPorts.Set(tcpBase, tcpMax, 49, 0);
}
WORD OpalManager::GetNextTCPPort()
{
return tcpPorts.GetNext(1);
}
void OpalManager::SetUDPPorts(unsigned udpBase, unsigned udpMax)
{
udpPorts.Set(udpBase, udpMax, 99, 0);
if (stun != NULL)
stun->SetPortRanges(GetUDPPortBase(), GetUDPPortMax(), GetRtpIpPortBase(), GetRtpIpPortMax());
}
WORD OpalManager::GetNextUDPPort()
{
return udpPorts.GetNext(1);
}
void OpalManager::SetRtpIpPorts(unsigned rtpIpBase, unsigned rtpIpMax)
{
rtpIpPorts.Set((rtpIpBase+1)&0xfffe, rtpIpMax&0xfffe, 199, 5000);
if (stun != NULL)
stun->SetPortRanges(GetUDPPortBase(), GetUDPPortMax(), GetRtpIpPortBase(), GetRtpIpPortMax());
}
WORD OpalManager::GetRtpIpPortPair()
{
return rtpIpPorts.GetNext(2);
}
void OpalManager::SetAudioJitterDelay(unsigned minDelay, unsigned maxDelay)
{
PAssert(minDelay <= 10000 && maxDelay <= 10000, PInvalidParameter);
if (minDelay < 10)
minDelay = 10;
minAudioJitterDelay = minDelay;
if (maxDelay < minDelay)
maxDelay = minDelay;
maxAudioJitterDelay = maxDelay;
}
BOOL OpalManager::SetVideoInputDevice(const PVideoDevice::OpenArgs & args)
{
PStringList drivers = PVideoInputDevice::GetDriverNames();
for (PINDEX i = 0; i < drivers.GetSize(); i++) {
PStringList devices = PVideoInputDevice::GetDriversDeviceNames(drivers[i]);
if (args.deviceName[0] == '#') {
PINDEX id = args.deviceName.Mid(1).AsUnsigned();
if (id > 0 && id <= devices.GetSize()) {
videoInputDevice = args;
videoInputDevice.deviceName = devices[id-1];
return TRUE;
}
}
else {
if (devices.GetValuesIndex(args.deviceName) != P_MAX_INDEX) {
videoInputDevice = args;
return TRUE;
}
}
}
return FALSE;
}
BOOL OpalManager::SetVideoPreviewDevice(const PVideoDevice::OpenArgs & args)
{
videoPreviewDevice = args;
return TRUE;
}
BOOL OpalManager::SetVideoOutputDevice(const PVideoDevice::OpenArgs & args)
{
videoOutputDevice = args;
return TRUE;
}
BOOL OpalManager::SetNoMediaTimeout(const PTimeInterval & newInterval)
{
if (newInterval < 10)
return FALSE;
PWaitAndSignal mutex(inUseFlag);
noMediaTimeout = newInterval;
return TRUE;
}
void OpalManager::GarbageCollection()
{
BOOL allCleared = activeCalls.DeleteObjectsToBeRemoved();
PWaitAndSignal mutex(inUseFlag);
for (PINDEX i = 0; i < endpoints.GetSize(); i++) {
if (!endpoints[i].connectionsActive.DeleteObjectsToBeRemoved())
allCleared = FALSE;
}
if (allCleared && clearingAllCalls)
allCallsCleared.Signal();
}
void OpalManager::CallDict::DeleteObject(PObject * object) const
{
manager.DestroyCall(PDownCast(OpalCall, object));
}
void OpalManager::GarbageMain(PThread &, INT)
{
while (!garbageCollectExit.Wait(1000))
GarbageCollection();
}
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -