Added still incomplete support for capturing ISDN data at runtime.
git-svn-id: http://yate.null.ro/svn/yate/trunk@2205 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
dc67319d01
commit
eba177f500
|
@ -79,11 +79,21 @@ bool SignallingDumper::dump(void* buf, unsigned int len, bool sent, int link)
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
u_int32_t hdr[4];
|
u_int32_t hdr[4];
|
||||||
t.toTimeval(&tv);
|
t.toTimeval(&tv);
|
||||||
|
DataBlock hdr2;
|
||||||
|
if (m_type == 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;
|
||||||
|
}
|
||||||
hdr[0] = tv.tv_sec;
|
hdr[0] = tv.tv_sec;
|
||||||
hdr[1] = tv.tv_usec;
|
hdr[1] = tv.tv_usec;
|
||||||
hdr[2] = len;
|
hdr[2] = len + hdr2.length();
|
||||||
hdr[3] = len;
|
hdr[3] = hdr[2];
|
||||||
DataBlock blk(hdr,sizeof(hdr));
|
DataBlock blk(hdr,sizeof(hdr));
|
||||||
|
blk += hdr2;
|
||||||
DataBlock dat(buf,len,false);
|
DataBlock dat(buf,len,false);
|
||||||
blk += dat;
|
blk += dat;
|
||||||
dat.clear(false);
|
dat.clear(false);
|
||||||
|
@ -107,16 +117,16 @@ void SignallingDumper::head()
|
||||||
hdr[4] = 65535; // rather arbitrary snaplen
|
hdr[4] = 65535; // rather arbitrary snaplen
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case Hdlc:
|
case Hdlc:
|
||||||
hdr[5] = 0;
|
hdr[5] = 177; // DLT_LINUX_LAPD
|
||||||
break;
|
break;
|
||||||
case Mtp2:
|
case Mtp2:
|
||||||
hdr[5] = 140;
|
hdr[5] = 140; // DLT_MTP2
|
||||||
break;
|
break;
|
||||||
case Mtp3:
|
case Mtp3:
|
||||||
hdr[5] = 141;
|
hdr[5] = 141; // DLT_MTP3
|
||||||
break;
|
break;
|
||||||
case Sccp:
|
case Sccp:
|
||||||
hdr[5] = 142;
|
hdr[5] = 142; // DLT_SCCP
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// compiler, please shut up
|
// compiler, please shut up
|
||||||
|
|
|
@ -2281,6 +2281,9 @@ ISDNQ931::ISDNQ931(const NamedList& params, const char* name)
|
||||||
#endif
|
#endif
|
||||||
Debug(this,DebugInfo,"ISDN Call Controller %s [%p]",s.c_str(),this);
|
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));
|
||||||
m_syncGroupTimer.start();
|
m_syncGroupTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2294,6 +2297,19 @@ ISDNQ931::~ISDNQ931()
|
||||||
DDebug(this,DebugAll,"ISDN Call Controller destroyed [%p]",this);
|
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
|
// Send a message to layer 2
|
||||||
bool ISDNQ931::sendMessage(ISDNQ931Message* msg, String* reason)
|
bool ISDNQ931::sendMessage(ISDNQ931Message* msg, String* reason)
|
||||||
{
|
{
|
||||||
|
|
|
@ -217,6 +217,12 @@ void SignallingCallControl::setDumper(SignallingDumper* dumper)
|
||||||
XDebug(DebugAll,"SignallingCallControl. Data dumper set to (%p) [%p]",m_dumper,this);
|
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
|
// Clear call list
|
||||||
void SignallingCallControl::clearCalls()
|
void SignallingCallControl::clearCalls()
|
||||||
{
|
{
|
||||||
|
|
|
@ -786,6 +786,12 @@ public:
|
||||||
*/
|
*/
|
||||||
void setDumper(SignallingDumper* dumper = 0);
|
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:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Get the strategy used by the attached circuit group to allocate circuits
|
* Get the strategy used by the attached circuit group to allocate circuits
|
||||||
|
@ -7381,6 +7387,12 @@ public:
|
||||||
inline const String& format() const
|
inline const String& format() const
|
||||||
{ return m_format; }
|
{ 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
|
* Send a message
|
||||||
* @param msg The message to be sent
|
* @param msg The message to be sent
|
||||||
|
|
|
@ -144,6 +144,10 @@ private:
|
||||||
// Handle command complete requests
|
// Handle command complete requests
|
||||||
virtual bool commandComplete(Message& msg, const String& partLine,
|
virtual bool commandComplete(Message& msg, const String& partLine,
|
||||||
const String& partWord);
|
const String& partWord);
|
||||||
|
// Custom command handler
|
||||||
|
virtual bool commandExecute(String& retVal, const String& line);
|
||||||
|
// Help message handler
|
||||||
|
bool commandHelp(String& retVal, const String& line);
|
||||||
// Delete the given link if found
|
// Delete the given link if found
|
||||||
// Clear link list if name is 0
|
// Clear link list if name is 0
|
||||||
// Clear all stacks without waiting for call termination if name is 0
|
// Clear all stacks without waiting for call termination if name is 0
|
||||||
|
@ -213,6 +217,8 @@ public:
|
||||||
{ return m_inband; }
|
{ return m_inband; }
|
||||||
// Set exiting flag for call controller and timeout for the thread
|
// Set exiting flag for call controller and timeout for the thread
|
||||||
void setExiting(unsigned int msec);
|
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.
|
// Initialize (create or reload) the link. Process the debuglayer parameter.
|
||||||
// Fix some type depending parameters
|
// Fix some type depending parameters
|
||||||
// Return false on failure
|
// Return false on failure
|
||||||
|
@ -494,6 +500,9 @@ static SigDriver plugin;
|
||||||
static Configuration s_cfg;
|
static Configuration s_cfg;
|
||||||
static Configuration s_cfgData;
|
static Configuration s_cfgData;
|
||||||
|
|
||||||
|
static const char s_miniHelp[] = "sigdump component [filename]";
|
||||||
|
static const char s_fullHelp[] = "Command to dump signalling data to a file";
|
||||||
|
|
||||||
inline void applyDebugLevel(DebugEnabler* dbg, int level)
|
inline void applyDebugLevel(DebugEnabler* dbg, int level)
|
||||||
{
|
{
|
||||||
if (dbg)
|
if (dbg)
|
||||||
|
@ -1092,6 +1101,8 @@ bool SigDriver::received(Message& msg, int id)
|
||||||
if (m_engine)
|
if (m_engine)
|
||||||
m_engine->stop();
|
m_engine->stop();
|
||||||
return Driver::received(msg,id);
|
return Driver::received(msg,id);
|
||||||
|
case Help:
|
||||||
|
return commandHelp(msg.retValue(),msg.getValue("line"));
|
||||||
default:
|
default:
|
||||||
return Driver::received(msg,id);
|
return Driver::received(msg,id);
|
||||||
}
|
}
|
||||||
|
@ -1299,6 +1310,15 @@ void SigDriver::copySigMsgParams(NamedList& dest, SignallingEvent* event,
|
||||||
bool SigDriver::commandComplete(Message& msg, const String& partLine,
|
bool SigDriver::commandComplete(Message& msg, const String& partLine,
|
||||||
const String& partWord)
|
const String& partWord)
|
||||||
{
|
{
|
||||||
|
if (partLine.null() || partLine == "help") {
|
||||||
|
if (itemComplete(msg.retValue(),"sigdump",partWord))
|
||||||
|
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);
|
||||||
|
}
|
||||||
bool status = partLine.startsWith("status");
|
bool status = partLine.startsWith("status");
|
||||||
bool drop = !status && partLine.startsWith("drop");
|
bool drop = !status && partLine.startsWith("drop");
|
||||||
if (!(status || drop))
|
if (!(status || drop))
|
||||||
|
@ -1337,6 +1357,41 @@ bool SigDriver::commandComplete(Message& msg, const String& partLine,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom command handler
|
||||||
|
bool SigDriver::commandExecute(String& retVal, const String& line)
|
||||||
|
{
|
||||||
|
String tmp = line;
|
||||||
|
if (tmp.startSkip("sigdump")) {
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
retVal << "\r\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return Driver::commandExecute(retVal,line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Help message handler
|
||||||
|
bool SigDriver::commandHelp(String& retVal, const String& line)
|
||||||
|
{
|
||||||
|
if (line.null() || line == "sigdump") {
|
||||||
|
retVal << " " << s_miniHelp << "\r\n";
|
||||||
|
if (line) {
|
||||||
|
retVal << s_fullHelp << "\r\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Append a link to the list. Duplicate names are not allowed
|
// Append a link to the list. Duplicate names are not allowed
|
||||||
bool SigDriver::appendLink(SigLink* link)
|
bool SigDriver::appendLink(SigLink* link)
|
||||||
{
|
{
|
||||||
|
@ -1406,6 +1461,7 @@ void SigDriver::initialize()
|
||||||
setup();
|
setup();
|
||||||
installRelay(Masquerade);
|
installRelay(Masquerade);
|
||||||
installRelay(Halt);
|
installRelay(Halt);
|
||||||
|
installRelay(Help);
|
||||||
installRelay(Progress);
|
installRelay(Progress);
|
||||||
installRelay(Update);
|
installRelay(Update);
|
||||||
installRelay(Route);
|
installRelay(Route);
|
||||||
|
@ -1549,6 +1605,15 @@ void SigLink::setExiting(unsigned int msec)
|
||||||
m_thread->m_timeout = Time::msecNow() + 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
|
// Initialize (create or reload) the link. Set debug levels for contained objects
|
||||||
// Fix some type depending parameters:
|
// Fix some type depending parameters:
|
||||||
// Force 'readonly' to true for ISDN monitors
|
// Force 'readonly' to true for ISDN monitors
|
||||||
|
|
Loading…
Reference in New Issue