Implemented generic signalling component control mechanism.
Protocol data dumping capability for several L2 and L3 components. Data dumpers can be set at runtime from rmanager command with completion. git-svn-id: http://voip.null.ro/svn/yate@2210 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
ca8411d4f0
commit
c60f1b10fb
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "yatesig.h"
|
||||
#include <yatephone.h>
|
||||
|
||||
|
||||
using namespace TelEngine;
|
||||
|
@ -37,13 +38,14 @@ SignallingDumper::~SignallingDumper()
|
|||
terminate();
|
||||
}
|
||||
|
||||
void SignallingDumper::setStream(Stream* stream)
|
||||
void SignallingDumper::setStream(Stream* stream, bool writeHeader)
|
||||
{
|
||||
if (stream == m_output)
|
||||
return;
|
||||
Stream* tmp = m_output;
|
||||
m_output = stream;
|
||||
head();
|
||||
if (writeHeader)
|
||||
head();
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
|
@ -80,13 +82,21 @@ bool SignallingDumper::dump(void* buf, unsigned int len, bool sent, int link)
|
|||
u_int32_t hdr[4];
|
||||
t.toTimeval(&tv);
|
||||
DataBlock hdr2;
|
||||
if (m_type == Hdlc) {
|
||||
switch (m_type) {
|
||||
case Q931:
|
||||
case Q921:
|
||||
case Hdlc:
|
||||
{
|
||||
// add LAPD pseudoheader
|
||||
hdr2.assign(0,16);
|
||||
unsigned char* ptr2 = (unsigned char*)hdr2.data();
|
||||
ptr2[6] = sent ? 1 : 0;
|
||||
ptr2[14] = 0x00;
|
||||
ptr2[15] = 0x30;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hdr[0] = tv.tv_sec;
|
||||
hdr[1] = tv.tv_usec;
|
||||
|
@ -116,6 +126,8 @@ void SignallingDumper::head()
|
|||
hdr[3] = 0; // timestamp accuracy
|
||||
hdr[4] = 65535; // rather arbitrary snaplen
|
||||
switch (m_type) {
|
||||
case Q931:
|
||||
case Q921:
|
||||
case Hdlc:
|
||||
hdr[5] = 177; // DLT_LINUX_LAPD
|
||||
break;
|
||||
|
@ -135,23 +147,77 @@ void SignallingDumper::head()
|
|||
m_output->writeData(hdr,sizeof(hdr));
|
||||
}
|
||||
|
||||
// Create a dumper
|
||||
// Create a dumper from file
|
||||
SignallingDumper* SignallingDumper::create(DebugEnabler* dbg, const char* filename, Type type,
|
||||
bool create, bool append)
|
||||
{
|
||||
if (!filename)
|
||||
return 0;
|
||||
SignallingDumper* dumper = 0;
|
||||
File* f = new File;
|
||||
if (f->openPath(filename,true,false,create,append,true)) {
|
||||
dumper = new SignallingDumper(type);
|
||||
dumper->setStream(f);
|
||||
}
|
||||
else {
|
||||
Debug(dbg,DebugWarn,"Failed to create dumper '%s'",filename);
|
||||
delete f;
|
||||
if (f->openPath(filename,true,false,create,append,true))
|
||||
return SignallingDumper::create(f,type);
|
||||
Debug(dbg,DebugWarn,"Failed to create dumper '%s'",filename);
|
||||
delete f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create a dumper from stream
|
||||
SignallingDumper* SignallingDumper::create(Stream* stream, Type type, bool writeHeader)
|
||||
{
|
||||
if (!stream)
|
||||
return 0;
|
||||
if (!stream->valid()) {
|
||||
delete stream;
|
||||
return 0;
|
||||
}
|
||||
SignallingDumper* dumper = new SignallingDumper(type);
|
||||
dumper->setStream(stream,writeHeader);
|
||||
return dumper;
|
||||
}
|
||||
|
||||
|
||||
void SignallingDumpable::setDumper(SignallingDumper* dumper)
|
||||
{
|
||||
if (dumper == m_dumper)
|
||||
return;
|
||||
SignallingDumper* tmp = m_dumper;
|
||||
m_dumper = dumper;
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
bool SignallingDumpable::setDumper(const String& name, bool create, bool append)
|
||||
{
|
||||
if (name.null())
|
||||
setDumper();
|
||||
else {
|
||||
SignallingDumper* dumper = SignallingDumper::create(0,name,m_type,create,append);
|
||||
if (dumper)
|
||||
setDumper(dumper);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SignallingDumpable::control(NamedList& params, SignallingComponent* owner)
|
||||
{
|
||||
String* tmp = params.getParam("operation");
|
||||
if (!(tmp && (*tmp == "sigdump")))
|
||||
return false;
|
||||
tmp = params.getParam("component");
|
||||
if (tmp && *tmp && owner && (owner->toString() != *tmp))
|
||||
return false;
|
||||
tmp = params.getParam("completion");
|
||||
if (tmp) {
|
||||
if (!owner)
|
||||
return false;
|
||||
String part = params.getValue("partword");
|
||||
return Module::itemComplete(*tmp,owner->toString(),part);
|
||||
}
|
||||
tmp = params.getParam("file");
|
||||
if (tmp)
|
||||
return setDumper(*tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||
|
|
|
@ -116,6 +116,11 @@ const String& SignallingComponent::toString() const
|
|||
return m_name;
|
||||
}
|
||||
|
||||
bool SignallingComponent::control(NamedList& params)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void SignallingComponent::insert(SignallingComponent* component)
|
||||
{
|
||||
if (!component)
|
||||
|
@ -223,6 +228,15 @@ bool SignallingEngine::remove(const String& name)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SignallingEngine::control(NamedList& params)
|
||||
{
|
||||
bool ok = false;
|
||||
Lock lock(this);
|
||||
for (ObjList* l = m_components.skipNull(); l; l = l->skipNext())
|
||||
ok = static_cast<SignallingComponent*>(l->get())->control(params) || ok;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool SignallingEngine::start(const char* name, Thread::Priority prio, unsigned long usec)
|
||||
{
|
||||
Lock lock(this);
|
||||
|
|
|
@ -185,18 +185,16 @@ bool SS7Layer2::control(Operation oper, NamedList* params)
|
|||
|
||||
|
||||
SS7MTP2::SS7MTP2(const NamedList& params, unsigned int status)
|
||||
: Mutex(true),
|
||||
: SignallingDumpable(SignallingDumper::Mtp2),
|
||||
Mutex(true),
|
||||
m_status(status), m_lStatus(OutOfService), m_rStatus(OutOfAlignment),
|
||||
m_interval(0), m_resend(0), m_abort(0), m_congestion(false),
|
||||
m_bsn(127), m_fsn(127), m_bib(true), m_fib(true),
|
||||
m_lastBsn(127), m_lastBib(true), m_errors(0),
|
||||
m_resendMs(250), m_abortMs(5000), m_dumper(0)
|
||||
m_resendMs(250), m_abortMs(5000)
|
||||
{
|
||||
setName(params.getValue("debugname","mtp2"));
|
||||
|
||||
const char* fn = params.getValue("mtp2dump");
|
||||
if (fn)
|
||||
setDumper(SignallingDumper::create(this,fn,SignallingDumper::Mtp2));
|
||||
setDumper(params.getValue("mtp2dump"));
|
||||
}
|
||||
|
||||
SS7MTP2::~SS7MTP2()
|
||||
|
@ -438,8 +436,7 @@ ObjList* SS7MTP2::recoverMSU()
|
|||
// Decode a received packet into signalling units
|
||||
bool SS7MTP2::receivedPacket(const DataBlock& packet)
|
||||
{
|
||||
if (m_dumper)
|
||||
m_dumper->dump(packet,false,sls());
|
||||
dump(packet,false,sls());
|
||||
if (packet.length() < 3) {
|
||||
XDebug(this,DebugMild,"Received short packet of length %u [%p]",
|
||||
packet.length(),this);
|
||||
|
@ -559,8 +556,7 @@ bool SS7MTP2::receivedPacket(const DataBlock& packet)
|
|||
bool SS7MTP2::txPacket(const DataBlock& packet, bool repeat, SignallingInterface::PacketType type)
|
||||
{
|
||||
if (transmitPacket(packet,repeat,type)) {
|
||||
if (m_dumper)
|
||||
m_dumper->dump(packet,true,sls());
|
||||
dump(packet,true,sls());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -700,13 +696,4 @@ bool SS7MTP2::startProving()
|
|||
return true;
|
||||
}
|
||||
|
||||
void SS7MTP2::setDumper(SignallingDumper* dumper)
|
||||
{
|
||||
if (dumper == m_dumper)
|
||||
return;
|
||||
SignallingDumper* tmp = m_dumper;
|
||||
m_dumper = dumper;
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||
|
|
|
@ -337,8 +337,9 @@ void SS7Layer3::printRoutes()
|
|||
}
|
||||
|
||||
SS7MTP3::SS7MTP3(const NamedList& params)
|
||||
: Mutex(true),
|
||||
m_total(0), m_active(0), m_dumper(0)
|
||||
: SignallingDumpable(SignallingDumper::Mtp3),
|
||||
Mutex(true),
|
||||
m_total(0), m_active(0)
|
||||
{
|
||||
setName(params.getValue("debugname","mtp3"));
|
||||
// Set point code type for each network indicator
|
||||
|
@ -363,10 +364,7 @@ SS7MTP3::SS7MTP3(const NamedList& params)
|
|||
Debug(this,level,"Point code types are '%s' [%p]",stype.safe(),this);
|
||||
|
||||
buildRoutes(params);
|
||||
|
||||
const char* fn = params.getValue("mtp3dump");
|
||||
if (fn)
|
||||
setDumper(SignallingDumper::create(this,fn,SignallingDumper::Mtp3));
|
||||
setDumper(params.getValue("mtp3dump"));
|
||||
}
|
||||
|
||||
SS7MTP3::~SS7MTP3()
|
||||
|
@ -497,8 +495,7 @@ int SS7MTP3::transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls)
|
|||
DDebug(this,DebugAll,"Found link %p for SLS=%d [%p]",link,sls,this);
|
||||
if (link->operational()) {
|
||||
if (link->transmitMSU(msu)) {
|
||||
if (m_dumper)
|
||||
m_dumper->dump(msu,true,sls);
|
||||
dump(msu,true,sls);
|
||||
return sls;
|
||||
}
|
||||
return -1;
|
||||
|
@ -516,8 +513,7 @@ int SS7MTP3::transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls)
|
|||
continue;
|
||||
SS7Layer2* link = *p;
|
||||
if (link->operational() && link->transmitMSU(msu)) {
|
||||
if (m_dumper)
|
||||
m_dumper->dump(msu,true,link->sls());
|
||||
dump(msu,true,link->sls());
|
||||
return link->sls();
|
||||
}
|
||||
}
|
||||
|
@ -528,10 +524,7 @@ int SS7MTP3::transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls)
|
|||
|
||||
bool SS7MTP3::receivedMSU(const SS7MSU& msu, SS7Layer2* link, int sls)
|
||||
{
|
||||
if (m_dumper)
|
||||
m_dumper->dump(msu,false,sls);
|
||||
XDebug(this,DebugStub,"Possibly incomplete SS7MTP3::receivedMSU(%p,%p,%d) [%p]",
|
||||
&msu,link,sls,this);
|
||||
dump(msu,false,sls);
|
||||
int netType = msu.getNI();
|
||||
SS7PointCode::Type cpType = type(netType);
|
||||
unsigned int llen = SS7Label::length(cpType);
|
||||
|
@ -579,14 +572,4 @@ void SS7MTP3::notify(SS7Layer2* link)
|
|||
SS7Layer3::notify(link ? link->sls() : -1);
|
||||
}
|
||||
|
||||
void SS7MTP3::setDumper(SignallingDumper* dumper)
|
||||
{
|
||||
if (dumper == m_dumper)
|
||||
return;
|
||||
SignallingDumper* tmp = m_dumper;
|
||||
m_dumper = dumper;
|
||||
if (tmp)
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||
|
|
|
@ -98,6 +98,7 @@ public:
|
|||
ISDNQ921::ISDNQ921(const NamedList& params, const char* name)
|
||||
: ISDNLayer2(params,name),
|
||||
SignallingReceiver(),
|
||||
SignallingDumpable(SignallingDumper::Q921),
|
||||
m_remoteBusy(false),
|
||||
m_timerRecovery(false),
|
||||
m_rejectSent(false),
|
||||
|
@ -117,7 +118,6 @@ ISDNQ921::ISDNQ921(const NamedList& params, const char* name)
|
|||
m_rxRejectedFrames(0),
|
||||
m_rxDroppedFrames(0),
|
||||
m_hwErrors(0),
|
||||
m_dumper(0),
|
||||
m_printFrames(true),
|
||||
m_extendedDebug(false),
|
||||
m_errorSend(false),
|
||||
|
@ -147,6 +147,7 @@ ISDNQ921::ISDNQ921(const NamedList& params, const char* name)
|
|||
Debug(this,DebugInfo,"ISDN Data Link type=%s%s [%p]",
|
||||
linkSide(network()),tmp.safe(),this);
|
||||
}
|
||||
setDumper(params.getValue("q921dump"));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
@ -334,8 +335,8 @@ bool ISDNQ921::receivedPacket(const DataBlock& packet)
|
|||
frame->toString(tmp,m_extendedDebug);
|
||||
Debug(this,DebugInfo,"Received frame (%p):%s",frame,tmp.c_str());
|
||||
}
|
||||
if (m_dumper && frame->type() < ISDNFrame::Invalid)
|
||||
m_dumper->dump(frame->buffer(),false);
|
||||
if (frame->type() < ISDNFrame::Invalid)
|
||||
dump(frame->buffer(),false);
|
||||
// Accept
|
||||
bool reject = false;
|
||||
// Not accepted:
|
||||
|
@ -470,18 +471,6 @@ void ISDNQ921::reset()
|
|||
m_va = m_vs = m_vr = 0;
|
||||
}
|
||||
|
||||
// Set/remove data dumper
|
||||
void ISDNQ921::setDumper(SignallingDumper* dumper)
|
||||
{
|
||||
Lock lock(m_layer);
|
||||
if (m_dumper == dumper)
|
||||
return;
|
||||
SignallingDumper* tmp = m_dumper;
|
||||
m_dumper = dumper;
|
||||
delete tmp;
|
||||
XDebug(this,DebugAll,"Data dumper set to (%p)",m_dumper);
|
||||
}
|
||||
|
||||
// Acknoledge pending outgoing frames. See Q.921 5.6.3.2
|
||||
// Remove ack'd frames from queue. Start idle timer
|
||||
bool ISDNQ921::ackOutgoingFrames(const ISDNFrame* frame)
|
||||
|
@ -869,8 +858,7 @@ bool ISDNQ921::sendFrame(const ISDNFrame* frame)
|
|||
// Dump frame if no error and we have a dumper
|
||||
if (result) {
|
||||
m_txFrames++;
|
||||
if (m_dumper)
|
||||
m_dumper->dump(frame->buffer(),true);
|
||||
dump(frame->buffer(),true);
|
||||
m_errorSend = false;
|
||||
}
|
||||
else {
|
||||
|
@ -960,12 +948,13 @@ void ISDNQ921::timer(bool start, bool t203, u_int64_t time)
|
|||
}
|
||||
|
||||
/**
|
||||
* ISDNQ921Pasive
|
||||
* ISDNQ921Passive
|
||||
*/
|
||||
// Constructor. Set data members. Print them
|
||||
ISDNQ921Pasive::ISDNQ921Pasive(const NamedList& params, const char* name)
|
||||
ISDNQ921Passive::ISDNQ921Passive(const NamedList& params, const char* name)
|
||||
: ISDNLayer2(params,name),
|
||||
SignallingReceiver(),
|
||||
SignallingDumpable(SignallingDumper::Q921),
|
||||
m_layer(true),
|
||||
m_checkLinkSide(false),
|
||||
m_idleTimer(0),
|
||||
|
@ -974,7 +963,6 @@ ISDNQ921Pasive::ISDNQ921Pasive(const NamedList& params, const char* name)
|
|||
m_rxRejectedFrames(0),
|
||||
m_rxDroppedFrames(0),
|
||||
m_hwErrors(0),
|
||||
m_dumper(0),
|
||||
m_printFrames(true),
|
||||
m_extendedDebug(false),
|
||||
m_errorReceive(false)
|
||||
|
@ -989,10 +977,11 @@ ISDNQ921Pasive::ISDNQ921Pasive(const NamedList& params, const char* name)
|
|||
linkSide(network()),String::boolText(detectType()),
|
||||
(unsigned int)m_idleTimer.interval(),this);
|
||||
m_idleTimer.start();
|
||||
setDumper(params.getValue("q921dump"));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
ISDNQ921Pasive::~ISDNQ921Pasive()
|
||||
ISDNQ921Passive::~ISDNQ921Passive()
|
||||
{
|
||||
Lock lock(m_layer);
|
||||
ISDNLayer2::attach(0);
|
||||
|
@ -1006,35 +995,23 @@ ISDNQ921Pasive::~ISDNQ921Pasive()
|
|||
}
|
||||
|
||||
// Reset data
|
||||
void ISDNQ921Pasive::cleanup()
|
||||
void ISDNQ921Passive::cleanup()
|
||||
{
|
||||
Lock lock(m_layer);
|
||||
m_idleTimer.start();
|
||||
}
|
||||
|
||||
// Get data members pointers
|
||||
void* ISDNQ921Pasive::getObject(const String& name) const
|
||||
void* ISDNQ921Passive::getObject(const String& name) const
|
||||
{
|
||||
if (name == "ISDNQ921Pasive")
|
||||
if (name == "ISDNQ921Passive")
|
||||
return (void*)this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set/remove data dumper
|
||||
void ISDNQ921Pasive::setDumper(SignallingDumper* dumper)
|
||||
{
|
||||
Lock lock(m_layer);
|
||||
if (m_dumper == dumper)
|
||||
return;
|
||||
SignallingDumper* tmp = m_dumper;
|
||||
m_dumper = dumper;
|
||||
delete tmp;
|
||||
XDebug(this,DebugAll,"Data dumper set to (%p)",m_dumper);
|
||||
}
|
||||
|
||||
// Called periodically by the engine to check timeouts
|
||||
// Check idle timer. Notify upper layer on timeout
|
||||
void ISDNQ921Pasive::timerTick(const Time& when)
|
||||
void ISDNQ921Passive::timerTick(const Time& when)
|
||||
{
|
||||
Lock lock(m_layer);
|
||||
if (!m_idleTimer.timeout(when.msec()))
|
||||
|
@ -1047,7 +1024,7 @@ void ISDNQ921Pasive::timerTick(const Time& when)
|
|||
}
|
||||
|
||||
// Process a packet received by the receiver's interface
|
||||
bool ISDNQ921Pasive::receivedPacket(const DataBlock& packet)
|
||||
bool ISDNQ921Passive::receivedPacket(const DataBlock& packet)
|
||||
{
|
||||
if (!packet.length())
|
||||
return false;
|
||||
|
@ -1067,8 +1044,8 @@ bool ISDNQ921Pasive::receivedPacket(const DataBlock& packet)
|
|||
frame->toString(tmp,m_extendedDebug);
|
||||
Debug(this,DebugInfo,"Received frame (%p):%s",frame,tmp.c_str());
|
||||
}
|
||||
if (m_dumper && frame->type() < ISDNFrame::Invalid)
|
||||
m_dumper->dump(frame->buffer(),false);
|
||||
if (frame->type() < ISDNFrame::Invalid)
|
||||
dump(frame->buffer(),false);
|
||||
// Received enough data to parse. Assume the channel not idle (restart timer)
|
||||
// If accepted, the frame is a data frame or a unnumbered (SABME,DISC,UA,DM) one
|
||||
// Drop retransmissions of data frames
|
||||
|
@ -1093,7 +1070,7 @@ bool ISDNQ921Pasive::receivedPacket(const DataBlock& packet)
|
|||
}
|
||||
|
||||
// Process a notification generated by the attached interface
|
||||
bool ISDNQ921Pasive::notify(SignallingInterface::Notification event)
|
||||
bool ISDNQ921Passive::notify(SignallingInterface::Notification event)
|
||||
{
|
||||
Lock lock(m_layer);
|
||||
if (event != SignallingInterface::LinkUp)
|
||||
|
@ -1117,7 +1094,7 @@ bool ISDNQ921Pasive::notify(SignallingInterface::Notification event)
|
|||
// Accept frame according to Q.921 5.8.5
|
||||
// Filter received frames. Accept only frames that would generate a notification to the upper layer:
|
||||
// UI/I and valid SABME/DISC/UA/DM
|
||||
bool ISDNQ921Pasive::acceptFrame(ISDNFrame* frame, bool& cmd, bool& value)
|
||||
bool ISDNQ921Passive::acceptFrame(ISDNFrame* frame, bool& cmd, bool& value)
|
||||
{
|
||||
// Update received frames
|
||||
m_rxFrames++;
|
||||
|
@ -1169,7 +1146,7 @@ bool ISDNQ921Pasive::acceptFrame(ISDNFrame* frame, bool& cmd, bool& value)
|
|||
return dropFrame(frame);
|
||||
}
|
||||
|
||||
bool ISDNQ921Pasive::dropFrame(const ISDNFrame* frame, const char* reason)
|
||||
bool ISDNQ921Passive::dropFrame(const ISDNFrame* frame, const char* reason)
|
||||
{
|
||||
m_rxDroppedFrames++;
|
||||
DDebug(this,DebugNote,"Dropping frame (%p): %s. Reason: %s",
|
||||
|
|
|
@ -2189,7 +2189,8 @@ TokenDict ISDNQ931::s_swType[] = {
|
|||
|
||||
ISDNQ931::ISDNQ931(const NamedList& params, const char* name)
|
||||
: SignallingCallControl(params,"isdn."),
|
||||
ISDNLayer3(name),
|
||||
SignallingDumpable(SignallingDumper::Q931),
|
||||
ISDNLayer3(name),
|
||||
m_layer(true),
|
||||
m_q921(0),
|
||||
m_q921Up(false),
|
||||
|
@ -2281,9 +2282,7 @@ ISDNQ931::ISDNQ931(const NamedList& params, const char* name)
|
|||
#endif
|
||||
Debug(this,DebugInfo,"ISDN Call Controller %s [%p]",s.c_str(),this);
|
||||
}
|
||||
const char* fn = params.getValue("isdndump");
|
||||
if (fn)
|
||||
setDumper(SignallingDumper::create(this,fn,SignallingDumper::Hdlc));
|
||||
setDumper(params.getValue("q931dump"));
|
||||
m_syncGroupTimer.start();
|
||||
}
|
||||
|
||||
|
@ -2297,19 +2296,6 @@ ISDNQ931::~ISDNQ931()
|
|||
DDebug(this,DebugAll,"ISDN Call Controller destroyed [%p]",this);
|
||||
}
|
||||
|
||||
bool ISDNQ931::setDumpFile(const String& file)
|
||||
{
|
||||
if (file.null())
|
||||
setDumper();
|
||||
else {
|
||||
SignallingDumper* dumper = SignallingDumper::create(this,file,SignallingDumper::Hdlc);
|
||||
if (!dumper)
|
||||
return false;
|
||||
setDumper(dumper);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Send a message to layer 2
|
||||
bool ISDNQ931::sendMessage(ISDNQ931Message* msg, String* reason)
|
||||
{
|
||||
|
@ -3146,8 +3132,8 @@ ISDNQ931Monitor::ISDNQ931Monitor(const NamedList& params, const char* name)
|
|||
ISDNQ931Monitor::~ISDNQ931Monitor()
|
||||
{
|
||||
terminateMonitor(0,0);
|
||||
attach((ISDNQ921Pasive*)0,true);
|
||||
attach((ISDNQ921Pasive*)0,false);
|
||||
attach((ISDNQ921Passive*)0,true);
|
||||
attach((ISDNQ921Passive*)0,false);
|
||||
attach((SignallingCircuitGroup*)0,true);
|
||||
attach((SignallingCircuitGroup*)0,false);
|
||||
m_calls.clear();
|
||||
|
@ -3245,14 +3231,14 @@ void ISDNQ931Monitor::receiveData(const DataBlock& data, bool ack, ISDNLayer2* l
|
|||
}
|
||||
|
||||
// Attach ISDN Q.921 pasive transport that monitors one side of the link
|
||||
void ISDNQ931Monitor::attach(ISDNQ921Pasive* q921, bool net)
|
||||
void ISDNQ931Monitor::attach(ISDNQ921Passive* q921, bool net)
|
||||
{
|
||||
Lock lock(m_layer);
|
||||
ISDNQ921Pasive* which = net ? m_q921Net : m_q921Cpe;
|
||||
ISDNQ921Passive* which = net ? m_q921Net : m_q921Cpe;
|
||||
if (which == q921)
|
||||
return;
|
||||
terminateMonitor(0,q921 ? "layer 2 attach" : "layer 2 detach");
|
||||
ISDNQ921Pasive* tmp = which;
|
||||
ISDNQ921Passive* tmp = which;
|
||||
if (net)
|
||||
m_q921Net = q921;
|
||||
else
|
||||
|
|
|
@ -53,8 +53,7 @@ SignallingCallControl::SignallingCallControl(const NamedList& params,
|
|||
m_verifyTimer(0),
|
||||
m_circuits(0),
|
||||
m_strategy(SignallingCircuitGroup::Increment),
|
||||
m_exiting(false),
|
||||
m_dumper(0)
|
||||
m_exiting(false)
|
||||
{
|
||||
// Strategy
|
||||
const char* strategy = params.getValue("strategy","increment");
|
||||
|
@ -206,23 +205,6 @@ SignallingEvent* SignallingCallControl::getEvent(const Time& when)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void SignallingCallControl::setDumper(SignallingDumper* dumper)
|
||||
{
|
||||
Lock lock(this);
|
||||
if (m_dumper == dumper)
|
||||
return;
|
||||
SignallingDumper* tmp = m_dumper;
|
||||
m_dumper = dumper;
|
||||
delete tmp;
|
||||
XDebug(DebugAll,"SignallingCallControl. Data dumper set to (%p) [%p]",m_dumper,this);
|
||||
}
|
||||
|
||||
bool SignallingCallControl::setDumpFile(const String& file)
|
||||
{
|
||||
Debug(DebugMild,"SignallingCallControl does not support dumping");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clear call list
|
||||
void SignallingCallControl::clearCalls()
|
||||
{
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace TelEngine {
|
|||
|
||||
// Signalling classes
|
||||
class SignallingDumper; // A generic data dumper
|
||||
class SignallingDumpable; // A component that can dump data
|
||||
class SignallingTimer; // A signalling timer
|
||||
class SignallingCounter; // A signalling counter
|
||||
class SignallingFactory; // A signalling component factory
|
||||
|
@ -112,7 +113,7 @@ class ISDNLayer2; // Abstract ISDN layer 2 (Q.921) messag
|
|||
class ISDNLayer3; // Abstract ISDN layer 3 (Q.931) message transport
|
||||
class ISDNFrame; // An ISDN Q.921 frame
|
||||
class ISDNQ921; // ISDN Q.921 implementation on top of a hardware interface
|
||||
class ISDNQ921Pasive; // Stateless ISDN Q.921 implementation on top of a hardware interface
|
||||
class ISDNQ921Passive; // Stateless ISDN Q.921 implementation on top of a hardware interface
|
||||
class ISDNIUA; // SIGTRAN ISDN Q.921 User Adaptation Layer
|
||||
class ISDNQ931IE; // A Q.931 ISDN Layer 3 message Information Element
|
||||
class ISDNQ931Message; // A Q.931 ISDN Layer 3 message
|
||||
|
@ -158,6 +159,8 @@ public:
|
|||
Raw,
|
||||
Hexa,
|
||||
Hdlc,
|
||||
Q921,
|
||||
Q931,
|
||||
Mtp2,
|
||||
Mtp3,
|
||||
Sccp,
|
||||
|
@ -195,8 +198,9 @@ public:
|
|||
/**
|
||||
* Set a new output stream
|
||||
* @param stream New stream for output, NULL to terminate
|
||||
* @param writeHeader True to write the header (if any) at start of stream
|
||||
*/
|
||||
void setStream(Stream* stream = 0);
|
||||
void setStream(Stream* stream = 0, bool writeHeader = true);
|
||||
|
||||
/**
|
||||
* Dump the provided data
|
||||
|
@ -230,12 +234,92 @@ public:
|
|||
static SignallingDumper* create(DebugEnabler* dbg, const char* filename, Type type,
|
||||
bool create = true, bool append = false);
|
||||
|
||||
/**
|
||||
* Create a dumper from an already existing stream
|
||||
* @param stream Stream to use for output, will be owned by dumper
|
||||
* @param type The dumper type
|
||||
* @param writeHeader True to write the header (if any) at start of stream
|
||||
* @return SignallingDumper pointer on success, 0 on failure
|
||||
*/
|
||||
static SignallingDumper* create(Stream* stream, Type type, bool writeHeader = true);
|
||||
|
||||
private:
|
||||
void head();
|
||||
Type m_type;
|
||||
Stream* m_output;
|
||||
};
|
||||
|
||||
/**
|
||||
* A generic base class for components capable of creating data dumps
|
||||
* @short A data dumping capable component
|
||||
*/
|
||||
class YSIG_API SignallingDumpable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Destructor - destroys the data dumper
|
||||
*/
|
||||
inline ~SignallingDumpable()
|
||||
{ setDumper(); }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructor
|
||||
* @param type Default type of the data dumper
|
||||
*/
|
||||
inline SignallingDumpable(SignallingDumper::Type type)
|
||||
: m_type(type), m_dumper(0)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Dump the provided data if the dumper is valid
|
||||
* @param buf Pointer to buffer to dump
|
||||
* @param len Length of the data
|
||||
* @param sent True if data is being sent, false if is being received
|
||||
* @param link Link number (relevant to MTP2 only)
|
||||
* @return True if the data was dumped successfully
|
||||
*/
|
||||
inline bool dump(void* buf, unsigned int len, bool sent = false, int link = 0)
|
||||
{ return (m_dumper && m_dumper->dump(buf,len,sent,link)); }
|
||||
|
||||
/**
|
||||
* Dump data if the dumper is valid
|
||||
* @param data Buffer to dump
|
||||
* @param sent True if data is being sent, false if is being received
|
||||
* @param link Link number (relevant to MTP2 only)
|
||||
* @return True if the data was dumped successfully
|
||||
*/
|
||||
inline bool dump(const DataBlock& data, bool sent = false, int link = 0)
|
||||
{ return dump(data.data(),data.length(),sent,link); }
|
||||
|
||||
/**
|
||||
* Set or remove the data dumper
|
||||
* @param dumper Pointer to the data dumper object, 0 to remove
|
||||
*/
|
||||
void setDumper(SignallingDumper* dumper = 0);
|
||||
|
||||
/**
|
||||
* Set or remove a file data dumper
|
||||
* @param name Name of the file to dump to, empty to remove dumper
|
||||
* @param create True to create the file if doesn't exist
|
||||
* @param append Append to an existing file. If false and the file already exists, it will be truncated
|
||||
* @return True if the file dumper was created or removed
|
||||
*/
|
||||
bool setDumper(const String& name, bool create = true, bool append = false);
|
||||
|
||||
/**
|
||||
* Handle dumper related control on behalf of the owning component
|
||||
* @param params Control parameters to handle
|
||||
* @param owner Optional owning component
|
||||
* @return True if control operation was applied
|
||||
*/
|
||||
bool control(NamedList& params, SignallingComponent* owner = 0);
|
||||
|
||||
private:
|
||||
SignallingDumper::Type m_type;
|
||||
SignallingDumper* m_dumper;
|
||||
};
|
||||
|
||||
/**
|
||||
* Timer management class. Used to manage timeouts. The time is kept in miliseconds
|
||||
* @short A signalling timer
|
||||
|
@ -465,6 +549,13 @@ public:
|
|||
*/
|
||||
virtual const String& toString() const;
|
||||
|
||||
/**
|
||||
* Query or modify component's settings or operational parameters
|
||||
* @param params The list of parameters to query or change
|
||||
* @return True if the control operation was executed
|
||||
*/
|
||||
virtual bool control(NamedList& params);
|
||||
|
||||
/**
|
||||
* Get the @ref TelEngine::SignallingEngine that manages this component
|
||||
* @return Pointer to engine or NULL if not managed by an engine
|
||||
|
@ -560,6 +651,13 @@ public:
|
|||
*/
|
||||
SignallingComponent* find(const String& name);
|
||||
|
||||
/**
|
||||
* Apply a control operation to all components in the engine
|
||||
* @param params The list of parameters to query or change
|
||||
* @return True if the control operation was executed by at least one component
|
||||
*/
|
||||
bool control(NamedList& params);
|
||||
|
||||
/**
|
||||
* Check if a component is in the engine's list
|
||||
* @param component Pointer to component to check
|
||||
|
@ -780,18 +878,6 @@ public:
|
|||
virtual void buildVerifyEvent(NamedList& params)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Set or remove the data dumper
|
||||
* @param dumper Pointer to the data dumper object, 0 to remove
|
||||
*/
|
||||
void setDumper(SignallingDumper* dumper = 0);
|
||||
|
||||
/**
|
||||
* Set or remove a data dump file
|
||||
* @param file Name of the file to dump to, empty to remove dumper
|
||||
*/
|
||||
virtual bool setDumpFile(const String& file);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Get the strategy used by the attached circuit group to allocate circuits
|
||||
|
@ -832,19 +918,6 @@ protected:
|
|||
*/
|
||||
void removeCall(SignallingCall* call, bool del = false);
|
||||
|
||||
/**
|
||||
* Dump data if the dumper is valid
|
||||
* This method is thread safe
|
||||
* @param data Buffer to dump
|
||||
* @param sent True if data is being sent, false if is being received
|
||||
* @param link Link number (relevant to MTP2 only)
|
||||
* @return True if the data was dumped successfully
|
||||
*/
|
||||
inline bool dump(const DataBlock& data, bool sent = false, int link = 0) {
|
||||
Lock lock(this);
|
||||
return (m_dumper && m_dumper->dump(data.data(),data.length(),sent,link));
|
||||
}
|
||||
|
||||
/**
|
||||
* List of active calls
|
||||
*/
|
||||
|
@ -871,7 +944,6 @@ private:
|
|||
SignallingCircuitGroup* m_circuits; // Circuit group
|
||||
int m_strategy; // Strategy to allocate circuits for outgoing calls
|
||||
bool m_exiting; // Call control is terminating. Generate a Disable event when no more calls
|
||||
SignallingDumper* m_dumper; // Data dumper in use
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4223,7 +4295,7 @@ class YSIG_API SS7M3UA : public SS7Layer3, public SIGTRAN
|
|||
* Q.703 SS7 Layer 2 (Data Link) implementation on top of a hardware interface
|
||||
* @short SS7 Layer 2 implementation on top of a hardware interface
|
||||
*/
|
||||
class YSIG_API SS7MTP2 : public SS7Layer2, public SignallingReceiver, public Mutex
|
||||
class YSIG_API SS7MTP2 : public SS7Layer2, public SignallingReceiver, public SignallingDumpable, public Mutex
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
@ -4366,13 +4438,9 @@ protected:
|
|||
*/
|
||||
bool startProving();
|
||||
|
||||
/**
|
||||
* Set or remove a data dumper
|
||||
* @param dumper Pointer to the data dumper object, NULL to remove
|
||||
*/
|
||||
void setDumper(SignallingDumper* dumper = 0);
|
||||
|
||||
private:
|
||||
virtual bool control(NamedList& params)
|
||||
{ return SignallingDumpable::control(params,this); }
|
||||
bool txPacket(const DataBlock& packet, bool repeat, SignallingInterface::PacketType type = SignallingInterface::Unknown);
|
||||
void setLocalStatus(unsigned int status);
|
||||
void setRemoteStatus(unsigned int status);
|
||||
|
@ -4402,15 +4470,13 @@ private:
|
|||
unsigned int m_resendMs;
|
||||
// packet resend abort interval
|
||||
unsigned int m_abortMs;
|
||||
// data dumper in use
|
||||
SignallingDumper* m_dumper;
|
||||
};
|
||||
|
||||
/**
|
||||
* Q.704 SS7 Layer 3 (Network) implementation on top of SS7 Layer 2
|
||||
* @short SS7 Layer 3 implementation on top of Layer 2
|
||||
*/
|
||||
class YSIG_API SS7MTP3 : public SS7Layer3, public SS7L2User, public Mutex
|
||||
class YSIG_API SS7MTP3 : public SS7Layer3, public SS7L2User, public SignallingDumpable, public Mutex
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
@ -4494,20 +4560,14 @@ protected:
|
|||
*/
|
||||
unsigned int countLinks();
|
||||
|
||||
/**
|
||||
* Set or remove a data dumper
|
||||
* @param dumper Pointer to the data dumper object, NULL to remove
|
||||
*/
|
||||
void setDumper(SignallingDumper* dumper = 0);
|
||||
|
||||
private:
|
||||
virtual bool control(NamedList& params)
|
||||
{ return SignallingDumpable::control(params,this); }
|
||||
ObjList m_links;
|
||||
// total links in linkset
|
||||
unsigned int m_total;
|
||||
// currently active links
|
||||
unsigned int m_active;
|
||||
// data dumper in use
|
||||
SignallingDumper* m_dumper;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -6120,7 +6180,7 @@ private:
|
|||
* Q.921 ISDN Layer 2 implementation on top of a hardware HDLC interface
|
||||
* @short ISDN Q.921 implementation on top of a hardware interface
|
||||
*/
|
||||
class YSIG_API ISDNQ921 : public ISDNLayer2, public SignallingReceiver
|
||||
class YSIG_API ISDNQ921 : public ISDNLayer2, public SignallingReceiver, public SignallingDumpable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
@ -6197,12 +6257,6 @@ public:
|
|||
m_extendedDebug = m_printFrames && extendedDebug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or remove a data dumper
|
||||
* @param dumper Pointer to the data dumper object, 0 to remove
|
||||
*/
|
||||
void setDumper(SignallingDumper* dumper = 0);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Method called periodically to check timeouts
|
||||
|
@ -6234,6 +6288,8 @@ protected:
|
|||
void reset();
|
||||
|
||||
private:
|
||||
virtual bool control(NamedList& params)
|
||||
{ return SignallingDumpable::control(params,this); }
|
||||
// Acknoledge outgoing frames
|
||||
// @param frame The acknoledging frame
|
||||
bool ackOutgoingFrames(const ISDNFrame* frame);
|
||||
|
@ -6306,8 +6362,6 @@ private:
|
|||
u_int32_t m_rxRejectedFrames; // The number of rejected frames. Doesn't include dropped frames
|
||||
u_int32_t m_rxDroppedFrames; // The number of dropped frames. Doesn't include rejected frames
|
||||
u_int32_t m_hwErrors; // The number of hardware notifications
|
||||
// Dumper
|
||||
SignallingDumper* m_dumper; // Data dumper in use
|
||||
// Debug flags
|
||||
bool m_printFrames; // Print frames to output
|
||||
bool m_extendedDebug; // Extended debug flag
|
||||
|
@ -6320,7 +6374,7 @@ private:
|
|||
* Q.921 ISDN Layer 2 pasive (stateless) implementation on top of a hardware HDLC interface
|
||||
* @short Stateless pasive ISDN Q.921 implementation on top of a hardware interface
|
||||
*/
|
||||
class YSIG_API ISDNQ921Pasive : public ISDNLayer2, public SignallingReceiver
|
||||
class YSIG_API ISDNQ921Passive : public ISDNLayer2, public SignallingReceiver, public SignallingDumpable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
@ -6329,12 +6383,12 @@ public:
|
|||
* @param params Layer's and @ref TelEngine::ISDNLayer2 parameters
|
||||
* @param name Name of this component
|
||||
*/
|
||||
ISDNQ921Pasive(const NamedList& params, const char* name = 0);
|
||||
ISDNQ921Passive(const NamedList& params, const char* name = 0);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~ISDNQ921Pasive();
|
||||
virtual ~ISDNQ921Passive();
|
||||
|
||||
/**
|
||||
* Emergency release
|
||||
|
@ -6369,12 +6423,6 @@ public:
|
|||
m_extendedDebug = m_printFrames && extendedDebug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or remove a data dumper
|
||||
* @param dumper Pointer to the data dumper object, 0 to remove
|
||||
*/
|
||||
void setDumper(SignallingDumper* dumper = 0);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Method called periodically to check timeouts
|
||||
|
@ -6400,6 +6448,8 @@ protected:
|
|||
virtual bool notify(SignallingInterface::Notification event);
|
||||
|
||||
private:
|
||||
virtual bool control(NamedList& params)
|
||||
{ return SignallingDumpable::control(params,this); }
|
||||
// Filter received frames. Accept only frames that would generate a notification to the upper layer:
|
||||
// UI/I, and Valid SABME/DISC/UA/DM
|
||||
// On success, if frame is not a data one, prepare cmd and value to notify layer 3
|
||||
|
@ -6415,7 +6465,6 @@ private:
|
|||
u_int32_t m_rxRejectedFrames; // The number of rejected frames. Doesn't include dropped frames
|
||||
u_int32_t m_rxDroppedFrames; // The number of dropped frames. Doesn't include rejected frames
|
||||
u_int32_t m_hwErrors; // The number of hardware notifications
|
||||
SignallingDumper* m_dumper; // Data dumper in use
|
||||
bool m_printFrames; // Print frames to output
|
||||
bool m_extendedDebug; // Extended debug flag
|
||||
bool m_errorReceive; // Receive error
|
||||
|
@ -7242,7 +7291,7 @@ public:
|
|||
* Q.931 ISDN Layer 3 implementation on top of a Layer 2
|
||||
* @short ISDN Q.931 implementation on top of Q.921
|
||||
*/
|
||||
class YSIG_API ISDNQ931 : public SignallingCallControl, public ISDNLayer3
|
||||
class YSIG_API ISDNQ931 : public SignallingCallControl, public SignallingDumpable, public ISDNLayer3
|
||||
{
|
||||
friend class ISDNQ931Call;
|
||||
public:
|
||||
|
@ -7387,12 +7436,6 @@ public:
|
|||
inline const String& format() const
|
||||
{ return m_format; }
|
||||
|
||||
/**
|
||||
* Set or remove a data dump file
|
||||
* @param file Name of the file to dump to, empty to remove dumper
|
||||
*/
|
||||
virtual bool setDumpFile(const String& file);
|
||||
|
||||
/**
|
||||
* Send a message
|
||||
* @param msg The message to be sent
|
||||
|
@ -7656,6 +7699,8 @@ protected:
|
|||
bool initiator, const char* cause, const char* diag = 0,
|
||||
const char* display = 0, const char* signal = 0);
|
||||
private:
|
||||
virtual bool control(NamedList& params)
|
||||
{ return SignallingDumpable::control(params,this); }
|
||||
Mutex m_layer; // Lock layer operation
|
||||
ISDNLayer2* m_q921; // The attached layer 2
|
||||
bool m_q921Up; // Layer 2 state
|
||||
|
@ -7751,7 +7796,7 @@ public:
|
|||
* @param q921 Pointer to the monitor to attach
|
||||
* @param net True if this is the network side of the data link, false for user (CPE) side
|
||||
*/
|
||||
virtual void attach(ISDNQ921Pasive* q921, bool net);
|
||||
virtual void attach(ISDNQ921Passive* q921, bool net);
|
||||
|
||||
/**
|
||||
* Attach a circuit group to this call controller
|
||||
|
@ -7773,8 +7818,8 @@ public:
|
|||
*/
|
||||
virtual void destruct() {
|
||||
SignallingCallControl::attach(0);
|
||||
attach((ISDNQ921Pasive*)0,true);
|
||||
attach((ISDNQ921Pasive*)0,false);
|
||||
attach((ISDNQ921Passive*)0,true);
|
||||
attach((ISDNQ921Passive*)0,false);
|
||||
attach((SignallingCircuitGroup*)0,true);
|
||||
attach((SignallingCircuitGroup*)0,false);
|
||||
ISDNLayer3::destruct();
|
||||
|
@ -7852,8 +7897,8 @@ private:
|
|||
bool dropMessage(const ISDNQ931Message* msg);
|
||||
|
||||
Mutex m_layer; // Lock layer operation
|
||||
ISDNQ921Pasive* m_q921Net; // Net side of the link
|
||||
ISDNQ921Pasive* m_q921Cpe; // CPE side of the link
|
||||
ISDNQ921Passive* m_q921Net; // Net side of the link
|
||||
ISDNQ921Passive* m_q921Cpe; // CPE side of the link
|
||||
SignallingCircuitGroup* m_cicNet; // Circuit group for the net side of the link
|
||||
SignallingCircuitGroup* m_cicCpe; // Circuit group for the cpe side of the link
|
||||
ISDNQ931ParserData m_parserData; // Parser settings
|
||||
|
|
|
@ -217,8 +217,6 @@ public:
|
|||
{ return m_inband; }
|
||||
// Set exiting flag for call controller and timeout for the thread
|
||||
void setExiting(unsigned int msec);
|
||||
// Set or remove a data dumper on the link or its components
|
||||
bool setDumpFile(const String& file);
|
||||
// Initialize (create or reload) the link. Process the debuglayer parameter.
|
||||
// Fix some type depending parameters
|
||||
// Return false on failure
|
||||
|
@ -351,8 +349,8 @@ private:
|
|||
String m_netId; // The id of the network side of the data link
|
||||
String m_cpeId; // The id of the user side of the data link
|
||||
// Components
|
||||
ISDNQ921Pasive* m_q921Net;
|
||||
ISDNQ921Pasive* m_q921Cpe;
|
||||
ISDNQ921Passive* m_q921Net;
|
||||
ISDNQ921Passive* m_q921Cpe;
|
||||
SignallingInterface* m_ifaceNet;
|
||||
SignallingInterface* m_ifaceCpe;
|
||||
SigCircuitGroup* m_groupNet;
|
||||
|
@ -1315,9 +1313,14 @@ bool SigDriver::commandComplete(Message& msg, const String& partLine,
|
|||
return false;
|
||||
}
|
||||
else if (partLine == "sigdump") {
|
||||
Lock lock(m_linksMutex);
|
||||
for (ObjList* o = m_links.skipNull(); o; o = o->skipNext())
|
||||
itemComplete(msg.retValue(),static_cast<SigLink*>(o->get())->name(),partWord);
|
||||
if (m_engine) {
|
||||
NamedList params("");
|
||||
params.addParam("operation","sigdump");
|
||||
params.addParam("partword",partWord);
|
||||
params.addParam("completion",msg.retValue());
|
||||
if (m_engine->control(params))
|
||||
msg.retValue() = params.getValue("completion");
|
||||
}
|
||||
}
|
||||
bool status = partLine.startsWith("status");
|
||||
bool drop = !status && partLine.startsWith("drop");
|
||||
|
@ -1362,14 +1365,24 @@ bool SigDriver::commandExecute(String& retVal, const String& line)
|
|||
{
|
||||
String tmp = line;
|
||||
if (tmp.startSkip("sigdump")) {
|
||||
tmp.trimBlanks();
|
||||
if (tmp.null() || tmp == "help" || tmp == "?")
|
||||
retVal << "Usage: " << s_miniHelp << "\r\n" << s_fullHelp;
|
||||
else {
|
||||
Lock lock(m_linksMutex);
|
||||
for (ObjList* o = m_links.skipNull(); o; o = o->skipNext()) {
|
||||
SigLink* link = static_cast<SigLink*>(o->get());
|
||||
if (tmp.startSkip(link->name()))
|
||||
return link->setDumpFile(tmp.trimBlanks());
|
||||
if (m_engine) {
|
||||
NamedList params("");
|
||||
params.addParam("operation","sigdump");
|
||||
int sep = tmp.find(' ');
|
||||
if (sep > 0) {
|
||||
params.addParam("component",tmp.substr(0,sep));
|
||||
tmp >> " ";
|
||||
params.addParam("file",tmp.trimBlanks());
|
||||
}
|
||||
else {
|
||||
params.addParam("component",tmp);
|
||||
params.addParam("file","");
|
||||
}
|
||||
return m_engine->control(params);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1605,15 +1618,6 @@ void SigLink::setExiting(unsigned int msec)
|
|||
m_thread->m_timeout = Time::msecNow() + msec;
|
||||
}
|
||||
|
||||
// Set or remove a data dumper on the link or its components
|
||||
bool SigLink::setDumpFile(const String& file)
|
||||
{
|
||||
if (!(m_controller && m_controller->setDumpFile(file)))
|
||||
return false;
|
||||
Debug(&plugin,DebugNote,"Link '%s' dumping to '%s'",name().c_str(),file.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialize (create or reload) the link. Set debug levels for contained objects
|
||||
// Fix some type depending parameters:
|
||||
// Force 'readonly' to true for ISDN monitors
|
||||
|
@ -2329,12 +2333,12 @@ bool SigIsdnMonitor::create(NamedList& params, String& error)
|
|||
params.setParam("debugname",compName);
|
||||
params.setParam("network",String::boolText(true));
|
||||
params.setParam("print-frames",params.getValue("print-layer2PDU"));
|
||||
m_q921Net = new ISDNQ921Pasive(params,compName);
|
||||
m_q921Net = new ISDNQ921Passive(params,compName);
|
||||
plugin.engine()->insert(m_q921Net);
|
||||
buildName(compName,"Q921",false);
|
||||
params.setParam("debugname",compName);
|
||||
params.setParam("network",String::boolText(false));
|
||||
m_q921Cpe = new ISDNQ921Pasive(params,compName);
|
||||
m_q921Cpe = new ISDNQ921Passive(params,compName);
|
||||
plugin.engine()->insert(m_q921Cpe);
|
||||
|
||||
// Q931
|
||||
|
|
Loading…
Reference in New Issue