📄 manager.cxx
字号:
inUseFlag.Signal();
}
void OpalManager::DetachEndPoint(OpalEndPoint * endpoint)
{
if (PAssertNULL(endpoint) == NULL)
return;
inUseFlag.Wait();
endpoints.Remove(endpoint);
inUseFlag.Signal();
}
OpalEndPoint * OpalManager::FindEndPoint(const PString & prefix)
{
PWaitAndSignal mutex(inUseFlag);
for (PINDEX i = 0; i < endpoints.GetSize(); i++) {
if (endpoints[i].GetPrefixName() *= prefix)
return &endpoints[i];
}
return NULL;
}
BOOL OpalManager::SetUpCall(const PString & partyA,
const PString & partyB,
PString & token,
void * userData)
{
PTRACE(3, "OpalMan\tSet up call from " << partyA << " to " << partyB);
OpalCall * call = CreateCall();
token = call->GetToken();
call->SetPartyB(partyB);
if (MakeConnection(*call, partyA, userData)) {
PTRACE(1, "SetUpCall succeeded");
return TRUE;
}
call->Clear();
if (!activeCalls.RemoveAt(token)) {
PTRACE(1, "SetUpCall could not remove call from active call list");
}
return FALSE;
}
void OpalManager::OnEstablishedCall(OpalCall & /*call*/)
{
}
BOOL OpalManager::IsCallEstablished(const PString & token)
{
PSafePtr<OpalCall> call = activeCalls.FindWithLock(token, PSafeReadOnly);
if (call == NULL)
return FALSE;
return call->IsEstablished();
}
BOOL OpalManager::ClearCall(const PString & token,
OpalConnection::CallEndReason reason,
PSyncPoint * sync)
{
/*The hugely multi-threaded nature of the OpalCall objects means that
to avoid many forms of race condition, a call is cleared by moving it from
the "active" call dictionary to a list of calls to be cleared that will be
processed by a background thread specifically for the purpose of cleaning
up cleared calls. So that is all that this function actually does.
The real work is done in the OpalGarbageCollector thread.
*/
{
// Find the call by token, callid or conferenceid
PSafePtr<OpalCall> call = activeCalls.FindWithLock(token);
if (call == NULL)
return FALSE;
call->Clear(reason, sync);
}
if (sync != NULL)
sync->Wait();
return TRUE;
}
BOOL OpalManager::ClearCallSynchronous(const PString & token,
OpalConnection::CallEndReason reason)
{
PSyncPoint wait;
return ClearCall(token, reason, &wait);
}
void OpalManager::ClearAllCalls(OpalConnection::CallEndReason reason, BOOL wait)
{
// Remove all calls from the active list first
for (PSafePtr<OpalCall> call = activeCalls; call != NULL; ++call) {
call->Clear(reason);
}
if (wait) {
clearingAllCalls = TRUE;
allCallsCleared.Wait();
clearingAllCalls = FALSE;
}
}
void OpalManager::OnClearedCall(OpalCall & PTRACE_PARAM(call))
{
PTRACE(3, "OpalMan\tOnClearedCall \"" << call.GetPartyA() << "\" to \"" << call.GetPartyB() << '"');
}
OpalCall * OpalManager::CreateCall()
{
return CreateCall(NULL);
}
OpalCall * OpalManager::CreateCall(void * /*userData*/)
{
return new OpalCall(*this);
}
void OpalManager::DestroyCall(OpalCall * call)
{
delete call;
}
PString OpalManager::GetNextCallToken()
{
PString token;
inUseFlag.Wait();
token.sprintf("%u", lastCallTokenID++);
inUseFlag.Signal();
return token;
}
BOOL OpalManager::MakeConnection(OpalCall & call, const PString & remoteParty)
{
return MakeConnection(call, remoteParty, NULL);
}
BOOL OpalManager::MakeConnection(OpalCall & call, const PString & remoteParty, void * userData)
{
PTRACE(3, "OpalMan\tSet up connection to \"" << remoteParty << '"');
if (endpoints.IsEmpty())
return FALSE;
PCaselessString epname = remoteParty.Left(remoteParty.Find(':'));
PWaitAndSignal mutex(inUseFlag);
if (epname.IsEmpty())
epname = endpoints[0].GetPrefixName();
for (PINDEX i = 0; i < endpoints.GetSize(); i++) {
if (epname == endpoints[i].GetPrefixName()) {
if (endpoints[i].MakeConnection(call, remoteParty, userData))
return TRUE;
}
}
PTRACE(1, "OpalMan\tCould not find endpoint to handle protocol \"" << epname << '"');
return FALSE;
}
BOOL OpalManager::OnIncomingConnection(OpalConnection & connection)
{
PTRACE(3, "OpalMan\tOn incoming connection " << connection);
OpalCall & call = connection.GetCall();
call.SetSessionIdentifier( connection.GetSessionIdentifier() );
if (call.GetOtherPartyConnection(connection) != NULL)
return TRUE;
// See if have pre-allocated B party address, otherwise use routing algorithm
PString destinationAddress = call.GetPartyB();
if (destinationAddress.IsEmpty())
destinationAddress = OnRouteConnection(connection);
// Nowhere to go
if (destinationAddress.IsEmpty())
return FALSE;
return MakeConnection(call, destinationAddress);
}
PString OpalManager::OnRouteConnection(OpalConnection & connection)
{
PString addr = connection.GetDestinationAddress();
// No address, fail call
if (addr.IsEmpty())
return PString::Empty();
// Have explicit protocol defined, so use that
PINDEX colon = addr.Find(':');
if (colon != P_MAX_INDEX && FindEndPoint(addr.Left(colon)) != NULL)
return addr;
// No routes specified, just return what we've got so far
if (routeTable.IsEmpty())
return addr;
return ApplyRouteTable(connection.GetEndPoint().GetPrefixName(), addr);
}
void OpalManager::OnAlerting(OpalConnection & connection)
{
PTRACE(3, "OpalMan\tOnAlerting " << connection);
connection.GetCall().OnAlerting(connection);
}
OpalConnection::AnswerCallResponse
OpalManager::OnAnswerCall(OpalConnection & connection,
const PString & caller)
{
return connection.GetCall().OnAnswerCall(connection, caller);
}
void OpalManager::OnConnected(OpalConnection & connection)
{
PTRACE(3, "OpalMan\tOnConnected " << connection);
connection.GetCall().OnConnected(connection);
}
void OpalManager::OnProgress(OpalConnection & connection)
{
PTRACE(3, "OpalMan\tOnConnected " << connection);
connection.GetCall().OnProgress(connection);
}
void OpalManager::OnEstablished(OpalConnection & connection)
{
PTRACE(3, "OpalMan\tOnEstablished " << connection);
connection.GetCall().OnEstablished(connection);
}
void OpalManager::OnReleased(OpalConnection & connection)
{
PTRACE(3, "OpalMan\tOnReleased " << connection);
connection.GetCall().OnReleased(connection);
}
void OpalManager::OnHold(OpalConnection & PTRACE_PARAM(connection))
{
PTRACE(3, "OpalMan\tOnHold " << connection);
}
BOOL OpalManager::OnForwarded(OpalConnection & PTRACE_PARAM(connection),
const PString & /*forwardParty*/)
{
PTRACE(4, "OpalEP\tOnForwarded " << connection);
return TRUE;
}
void OpalManager::AdjustMediaFormats(const OpalConnection & /*connection*/,
OpalMediaFormatList & mediaFormats) const
{
mediaFormats.Remove(mediaFormatMask);
mediaFormats.Reorder(mediaFormatOrder);
}
BOOL OpalManager::IsMediaBypassPossible(const OpalConnection & source,
const OpalConnection & destination,
unsigned sessionID) const
{
PTRACE(3, "OpalMan\tIsMediaBypassPossible: session " << sessionID);
return source.IsMediaBypassPossible(sessionID) &&
destination.IsMediaBypassPossible(sessionID);
}
BOOL OpalManager::OnOpenMediaStream(OpalConnection & connection,
OpalMediaStream & stream)
{
PTRACE(3, "OpalMan\tOnOpenMediaStream " << connection << ',' << stream);
if (stream.IsSource())
return connection.GetCall().PatchMediaStreams(connection, stream);
return TRUE;
}
void OpalManager::OnClosedMediaStream(const OpalMediaStream & /*channel*/)
{
}
void OpalManager::AddVideoMediaFormats(OpalMediaFormatList & mediaFormats,
const OpalConnection * /*connection*/) const
{
if (videoInputDevice.deviceName.IsEmpty())
return;
mediaFormats += OpalYUV420P;
mediaFormats += OpalRGB32;
mediaFormats += OpalRGB24;
}
BOOL OpalManager::CreateVideoInputDevice(const OpalConnection & /*connection*/,
const OpalMediaFormat & mediaFormat,
PVideoInputDevice * & device,
BOOL & autoDelete)
{
autoDelete = TRUE;
device = PVideoInputDevice::CreateDeviceByName(videoInputDevice.deviceName);
if (device != NULL) {
videoInputDevice.width = mediaFormat.GetOptionInteger(OpalVideoFormat::FrameWidthOption, 176);
videoInputDevice.height = mediaFormat.GetOptionInteger(OpalVideoFormat::FrameHeightOption, 144);
if (device->OpenFull(videoInputDevice, FALSE))
return TRUE;
delete device;
}
return FALSE;
}
BOOL OpalManager::CreateVideoOutputDevice(const OpalConnection & /*connection*/,
const OpalMediaFormat & mediaFormat,
BOOL preview,
PVideoOutputDevice * & device,
BOOL & autoDelete)
{
const PVideoDevice::OpenArgs & args = preview ? videoPreviewDevice : videoOutputDevice;
autoDelete = TRUE;
device = PVideoOutputDevice::CreateDeviceByName(args.deviceName);
if (device != NULL) {
videoOutputDevice.width = mediaFormat.GetOptionInteger(OpalVideoFormat::FrameWidthOption, 176);
videoOutputDevice.height = mediaFormat.GetOptionInteger(OpalVideoFormat::FrameHeightOption, 144);
if (device->OpenFull(args, FALSE))
return TRUE;
delete device;
}
return FALSE;
}
OpalMediaPatch * OpalManager::CreateMediaPatch(OpalMediaStream & source)
{
return new OpalMediaPatch(source);
}
void OpalManager::DestroyMediaPatch(OpalMediaPatch * patch)
{
delete patch;
}
BOOL OpalManager::OnStartMediaPatch(const OpalMediaPatch & /*patch*/)
{
return TRUE;
}
void OpalManager::OnUserInputString(OpalConnection & connection,
const PString & value)
{
connection.GetCall().OnUserInputString(connection, value);
}
void OpalManager::OnUserInputTone(OpalConnection & connection,
char tone,
int duration)
{
connection.GetCall().OnUserInputTone(connection, tone, duration);
}
OpalT120Protocol * OpalManager::CreateT120ProtocolHandler(const OpalConnection & ) const
{
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -