yate/libs/ysig/interface.cpp

165 lines
4.5 KiB
C++

/**
* interface.cpp
* This file is part of the YATE Project http://YATE.null.ro
*
* Yet Another Signalling Stack - implements the support for SS7, ISDN and PSTN
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2004-2014 Null Team
*
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribution.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "yatesig.h"
using namespace TelEngine;
// SignallingInterface notification texts used to print debug
const TokenDict SignallingInterface::s_notifName[] = {
{"LinkUp", LinkUp},
{"LinkDown", LinkDown},
{"HWError", HardwareError},
{"TxClock", TxClockError},
{"RxClock", RxClockError},
{"Align", AlignError},
{"CRC", CksumError},
{"TxOversize", TxOversize},
{"RxOversize", RxOversize},
{"TxOverflow", TxOverflow},
{"RxOverflow", RxOverflow},
{"TxUnder", TxUnderrun},
{"RxUnder", RxUnderrun},
{0,0}
};
SignallingInterface::~SignallingInterface()
{
if (m_receiver)
Debug(this,DebugCrit,"Destroyed with receiver (%p) attached",m_receiver);
}
void SignallingInterface::attach(SignallingReceiver* receiver)
{
Lock lock(m_recvMutex);
if (m_receiver == receiver)
return;
SignallingReceiver* tmp = m_receiver;
m_receiver = receiver;
lock.drop();
if (tmp) {
const char* name = 0;
if (engine() && engine()->find(tmp)) {
name = tmp->toString().safe();
tmp->attach(0);
}
Debug(this,DebugAll,"Detached receiver (%p,'%s') [%p]",tmp,name,this);
}
if (!receiver)
return;
Debug(this,DebugAll,"Attached receiver (%p,'%s') [%p]",
receiver,receiver->toString().safe(),this);
insert(receiver);
receiver->attach(this);
}
bool SignallingInterface::control(Operation oper, NamedList* params)
{
DDebug(this,DebugInfo,"Unhandled SignallingInterface::control(%d,%p) [%p]",
oper,params,this);
return TelEngine::controlReturn(params,false);
}
bool SignallingInterface::receivedPacket(const DataBlock& packet)
{
m_recvMutex.lock();
RefPointer<SignallingReceiver> tmp = m_receiver;
m_recvMutex.unlock();
return tmp && tmp->receivedPacket(packet);
}
bool SignallingInterface::notify(Notification event)
{
m_recvMutex.lock();
RefPointer<SignallingReceiver> tmp = m_receiver;
m_recvMutex.unlock();
return tmp && tmp->notify(event);
}
SignallingReceiver::SignallingReceiver(const char* name)
: SignallingComponent(name),
m_ifaceMutex(true,"SignallingReceiver::interface"), m_interface(0)
{
}
SignallingReceiver::~SignallingReceiver()
{
if (m_interface)
Debug(this,DebugCrit,"Destroyed with interface (%p) attached",m_interface);
TelEngine::destruct(attach(0));
}
SignallingInterface* SignallingReceiver::attach(SignallingInterface* iface)
{
Lock lock(m_ifaceMutex);
if (m_interface == iface)
return 0;
SignallingInterface* tmp = m_interface;
m_interface = iface;
lock.drop();
if (tmp) {
if (tmp->receiver() == this) {
Debug(this,DebugAll,"Detaching interface (%p,'%s') [%p]",
tmp,tmp->toString().safe(),this);
tmp->attach(0);
}
else {
Debug(this,DebugNote,"Interface (%p,'%s') was not attached to us [%p]",
tmp,tmp->toString().safe(),this);
tmp = 0;
}
}
if (!iface)
return tmp;
Debug(this,DebugAll,"Attached interface (%p,'%s') [%p]",
iface,iface->toString().safe(),this);
insert(iface);
iface->attach(this);
return tmp;
}
bool SignallingReceiver::notify(SignallingInterface::Notification event)
{
DDebug(this,DebugInfo,"Unhandled SignallingReceiver::notify(%d) [%p]",event,this);
return false;
}
bool SignallingReceiver::control(SignallingInterface::Operation oper, NamedList* params)
{
m_ifaceMutex.lock();
RefPointer<SignallingInterface> tmp = m_interface;
m_ifaceMutex.unlock();
return TelEngine::controlReturn(params,tmp && tmp->control(oper,params));
}
bool SignallingReceiver::transmitPacket(const DataBlock& packet, bool repeat,
SignallingInterface::PacketType type)
{
m_ifaceMutex.lock();
RefPointer<SignallingInterface> tmp = m_interface;
m_ifaceMutex.unlock();
return tmp && tmp->transmitPacket(packet,repeat,type);
}
/* vi: set ts=8 sw=4 sts=4 noet: */