/** * 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 tmp = m_receiver; m_recvMutex.unlock(); return tmp && tmp->receivedPacket(packet); } bool SignallingInterface::notify(Notification event) { m_recvMutex.lock(); RefPointer 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 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 tmp = m_interface; m_ifaceMutex.unlock(); return tmp && tmp->transmitPacket(packet,repeat,type); } /* vi: set ts=8 sw=4 sts=4 noet: */