More work on performance issues.

git-svn-id: http://yate.null.ro/svn/yate/trunk@932 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2006-07-04 19:34:46 +00:00
parent 6f581a90d7
commit 168d0006af
5 changed files with 137 additions and 126 deletions

View File

@ -45,9 +45,7 @@ IAXEngine::IAXEngine(int port, u_int16_t transListCount, u_int16_t retransCount,
m_format(format),
m_capability(capab),
m_mutexTrunk(true),
m_trunkSendInterval(trunkSendInterval),
m_writeCommands(0),
m_writeCommandsFail(0)
m_trunkSendInterval(trunkSendInterval)
{
debugName("iaxengine");
if ((port <= 0) || port > 65535)
@ -77,10 +75,6 @@ IAXEngine::~IAXEngine()
for (int i = 0; i < m_transListCount; i++)
delete m_transList[i];
delete[] m_transList;
print();
}
IAXTransaction* IAXEngine::addFrame(const SocketAddr& addr, IAXFrame* frame)
@ -100,7 +94,7 @@ IAXTransaction* IAXEngine::addFrame(const SocketAddr& addr, IAXFrame* frame)
continue;
// Complete transaction
if (tr->processFrame(frame)) {
tr->m_rCallNo = frame->sourceCallNo();
tr->m_rCallNo = frame->sourceCallNo();
m_incompleteTransList.remove(tr,false);
m_transList[frame->sourceCallNo() % m_transListCount]->append(tr);
XDebug(this,DebugAll,"New incomplete outgoing transaction completed (%u,%u)",
@ -223,9 +217,7 @@ void IAXEngine::readSocket(SocketAddr& addr)
bool IAXEngine::writeSocket(const void* buf, int len, const SocketAddr& addr)
{
len = m_socket.sendTo(buf,len,addr);
m_writeCommands++;
if (len == Socket::socketError()) {
m_writeCommandsFail++;
if (!m_socket.canRetry())
Debug(this,DebugWarn,"Socket write error: %s (%d)",
::strerror(m_socket.error()),m_socket.error());
@ -452,6 +444,8 @@ void IAXEngine::defaultEventHandler(IAXEvent* event)
void IAXEngine::enableTrunking(IAXTransaction* trans)
{
if (!trans || trans->type() != IAXTransaction::New)
return;
Lock lock(&m_mutexTrunk);
IAXMetaTrunkFrame* frame;
// Already enabled ?
@ -483,14 +477,6 @@ void IAXEngine::runProcessTrunkFrames()
}
}
void IAXEngine::print()
{
Debug(this,DebugInfo,"IAXEngine - START PRINT [%p]",this);
Output("Write commands: " FMT64U,m_writeCommands);
Output("Write commands failed: " FMT64U,m_writeCommandsFail);
Debug(this,DebugInfo,"IAXEngine - END PRINT [%p]",this);
}
void IAXEngine::getMD5FromChallenge(String& md5data, const String& challenge, const String& password)
{
MD5 md5;
@ -530,10 +516,8 @@ IAXEvent::IAXEvent(Type type, bool local, bool final, IAXTransaction* transactio
IAXEvent::~IAXEvent()
{
// Moved to transaction destructor
// if (m_final && m_transaction && m_transaction->state() == IAXTransaction::Terminated) {
// m_transaction->getEngine()->removeTransaction(m_transaction);
// }
if (m_final && m_transaction && m_transaction->state() == IAXTransaction::Terminated)
m_transaction->getEngine()->removeTransaction(m_transaction);
if (m_transaction) {
m_transaction->eventTerminated(this);
m_transaction->deref();

View File

@ -28,7 +28,7 @@
using namespace TelEngine;
/**
/*
* IAXInfoElement
*/
static TokenDict s_ieData[] = {
@ -94,20 +94,20 @@ const char* IAXInfoElement::ieText(u_int8_t ieCode)
void IAXInfoElement::toBuffer(DataBlock& buf)
{
unsigned char d[2] = {m_type,0};
buf.assign(d,2);
buf.assign(d,sizeof(d));
}
/**
/*
* IAXInfoElementString
*/
void IAXInfoElementString::toBuffer(DataBlock& buf)
{
unsigned char d[2] = {m_type,m_strData.length()};
buf.assign(d,2);
unsigned char d[2] = {type(),m_strData.length()};
buf.assign(d,sizeof(d));
buf.append(data());
}
/**
/*
* IAXInfoElementNumeric
*/
IAXInfoElementNumeric::IAXInfoElementNumeric(Type type, u_int32_t val, u_int8_t len)
@ -129,7 +129,7 @@ IAXInfoElementNumeric::IAXInfoElementNumeric(Type type, u_int32_t val, u_int8_t
void IAXInfoElementNumeric::toBuffer(DataBlock& buf)
{
unsigned char d[6] = {m_type,m_length};
unsigned char d[6] = {type(),m_length};
switch (m_length) {
case 1:
@ -149,14 +149,13 @@ void IAXInfoElementNumeric::toBuffer(DataBlock& buf)
buf.assign(d,2 + m_length);
}
/**
/*
* IAXInfoElementBinary
*/
void IAXInfoElementBinary::toBuffer(DataBlock& buf)
{
unsigned char d[2] = {m_type,m_data.length()};
DataBlock data(d,2);
buf.assign(d,2);
unsigned char d[2] = {type(),m_data.length()};
buf.assign(d,sizeof(d));
buf += m_data;
}
@ -174,7 +173,7 @@ bool IAXInfoElementBinary::unpackIP(SocketAddr& addr, IAXInfoElementBinary* ie)
return true;
}
/**
/*
* IAXIEList
*/
void IAXIEList::insertVersion()
@ -275,7 +274,7 @@ bool IAXIEList::createFromFrame(const IAXFullFrame* frame)
i += 5;
break;
// 2 bytes
case IAXInfoElement::VERSION: // Value: 0x0002
case IAXInfoElement::VERSION:
case IAXInfoElement::ADSICPE:
case IAXInfoElement::AUTHMETHODS:
case IAXInfoElement::REFRESH:
@ -387,7 +386,7 @@ bool IAXIEList::getBinary(IAXInfoElement::Type type, DataBlock& dest)
return true;
}
/**
/*
* IAXFormat
*/
TokenDict IAXFormat::audioData[] = {
@ -428,7 +427,7 @@ const char* IAXFormat::videoText(u_int32_t video)
*/
IAXFrame::IAXFrame(Type type, u_int16_t sCallNo, u_int32_t tStamp, bool retrans,
const unsigned char* buf, unsigned int len)
: m_type(type), m_data((char*)buf,len,true), m_retrans(retrans),
: m_data((char*)buf,len,true), m_retrans(retrans), m_type(type),
m_sCallNo(sCallNo), m_tStamp(tStamp)
{
XDebug(DebugAll,"IAXFrame::IAXFrame(%u) [%p]",type,this);
@ -569,7 +568,7 @@ const IAXFullFrame* IAXFrame::fullFrame() const
return 0;
}
/**
/*
* IAXFullFrame
*/
IAXFullFrame::IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo,
@ -597,25 +596,25 @@ IAXFullFrame::IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_i
DataBlock ie;
// Full frame flag + Source call number
header[0] = 0x80 | (unsigned char)(m_sCallNo >> 8);
header[1] = (unsigned char)(m_sCallNo);
header[0] = 0x80 | (unsigned char)(sourceCallNo() >> 8);
header[1] = (unsigned char)(sourceCallNo());
// Retrans + Destination call number
header[2] = (unsigned char)(m_dCallNo >> 8); // retrans is false: bit 7 is 0
header[3] = (unsigned char)m_dCallNo;
header[2] = (unsigned char)(destCallNo() >> 8); // retrans is false: bit 7 is 0
header[3] = (unsigned char)destCallNo();
// Timestamp
header[4] = (unsigned char)(m_tStamp >> 24);
header[5] = (unsigned char)(m_tStamp >> 16);
header[6] = (unsigned char)(m_tStamp >> 8);
header[7] = (unsigned char)m_tStamp;
header[4] = (unsigned char)(timeStamp() >> 24);
header[5] = (unsigned char)(timeStamp() >> 16);
header[6] = (unsigned char)(timeStamp() >> 8);
header[7] = (unsigned char)timeStamp();
// oSeqNo + iSeqNo
header[8] = m_oSeqNo;
header[9] = m_iSeqNo;
// Type
header[10] = m_type;
header[10] = type;
// Subclass
header[11] = packSubclass(m_subclass);
// Set data
m_data.assign(header,12);
m_data.assign(header,sizeof(header));
if (buf) {
ie.assign((void*)buf,(unsigned int)len);
m_data += ie;
@ -633,7 +632,7 @@ const IAXFullFrame* IAXFullFrame::fullFrame() const
return this;
}
/**
/*
* IAXFrameOut
*/
void IAXFrameOut::setRetrans()
@ -661,9 +660,9 @@ void IAXFrameOut::adjustAuthTimeout(u_int64_t nextTransTime)
m_nextTransTime = nextTransTime;
}
/**
* IAXFrameOut
*/
/*
* IAXMetaTrunkFrame
*/
#define IAX2_METATRUNK_HEADERLENGTH 8
#define IAX2_MINIFRAME_HEADERLENGTH 6

View File

@ -194,7 +194,6 @@ IAXTransaction::~IAXTransaction()
#endif
if (m_trunkFrame)
m_trunkFrame->deref();
m_engine->removeTransaction(this);
if (state() != Terminating && state() != Terminated)
sendReject("Server shutdown");
}
@ -245,7 +244,7 @@ IAXTransaction* IAXTransaction::processFrame(IAXFrame* frame)
return retransmitOnVNAK(frame->fullFrame()->iSeqNo());
// Do we have enough space to keep this frame ?
if (m_inFrames.count() == m_maxInFrames) {
Debug(DebugWarn,"Transaction(%u,%u) - processFrame. Buffer overrun!",localCallNo(),remoteCallNo());
Debug(DebugWarn,"Transaction(%u,%u). processFrame. Buffer overrun! (MAX=%u)",localCallNo(),remoteCallNo(),m_maxInFrames);
m_inDroppedFrames++;
return 0;
}
@ -258,6 +257,9 @@ IAXTransaction* IAXTransaction::processFrame(IAXFrame* frame)
return processVoiceFrame(frame->fullFrame());
// Process incoming Ping
if (frame->type() == IAXFrame::IAX && frame->fullFrame()->subclass() == IAXControl::Ping) {
DDebug(m_engine,DebugAll,"Transaction(%u,%u) received Ping iseq=%u oseq=%u stamp=%u [%p]",
localCallNo(),remoteCallNo(),frame->fullFrame()->iSeqNo(),frame->fullFrame()->oSeqNo(),
frame->timeStamp(),this);
postFrame(IAXFrame::IAX,IAXControl::Pong,0,0,frame->timeStamp(),true);
return 0;
}
@ -357,7 +359,6 @@ IAXEvent* IAXTransaction::getEvent(u_int64_t time)
}
// Time to Ping remote peer ?
if (time > m_timeToNextPing && state() != Terminating) {
DDebug(m_engine,DebugAll,"Time to PING. %u",(u_int32_t)timeStamp());
postFrame(IAXFrame::IAX,IAXControl::Ping,0,0,timeStamp(),false);
m_timeToNextPing = time + m_pingInterval;
}
@ -496,7 +497,7 @@ bool IAXTransaction::sendHangup(const char* cause, u_int8_t code)
postFrame(IAXFrame::IAX,IAXControl::Hangup,data.data(),data.length(),0,true);
changeState(Terminating);
m_localReqEnd = true;
Debug(m_engine,DebugAll,"Transaction(%u,%u) - Hangup call. Cause: '%s'",localCallNo(),remoteCallNo(),cause);
Debug(m_engine,DebugAll,"Transaction(%u,%u). Hangup call. Cause: '%s'",localCallNo(),remoteCallNo(),cause);
return true;
}
@ -536,7 +537,7 @@ bool IAXTransaction::sendReject(const char* cause, u_int8_t code)
data += aux;
}
postFrame(IAXFrame::IAX,frametype,data.data(),data.length(),0,true);
Debug(m_engine,DebugAll,"Transaction(%u,%u) - Reject. Cause: '%s'",localCallNo(),remoteCallNo(),cause);
Debug(m_engine,DebugAll,"Transaction(%u,%u). Reject. Cause: '%s'",localCallNo(),remoteCallNo(),cause);
changeState(Terminating);
m_localReqEnd = true;
return true;
@ -722,10 +723,9 @@ bool IAXTransaction::incrementSeqNo(const IAXFullFrame* frame, bool inbound)
m_iSeqNo++;
else
m_oSeqNo++;
XDebug(m_engine,DebugAll,"Incremented %s=%u for Frame(%u,%u) iseq=%u oseq=%u [%p]",
inbound ? "iseq" : "oseq", inbound ? m_iSeqNo : m_oSeqNo,
frame->type(),frame->subclass(),
frame->iSeqNo(),frame->oSeqNo(),this);
XDebug(m_engine,DebugAll,"Transaction(%u,%u). Incremented %s=%u for Frame(%u,%u) iseq=%u oseq=%u [%p]",
localCallNo(),remoteCallNo(),inbound ? "iseq" : "oseq", inbound ? m_iSeqNo : m_oSeqNo,
frame->type(),frame->subclass(),frame->iSeqNo(),frame->oSeqNo(),this);
return true;
}
@ -736,13 +736,13 @@ bool IAXTransaction::isFrameAcceptable(const IAXFullFrame* frame)
return true;
if (delta > 0) {
// We missed some frames before this one: Send VNAK
Debug(m_engine,DebugInfo,"Transaction(%u,%u) - received Frame(%u,%u) out of order! oseq=%u expecting %u. Send VNAK",
Debug(m_engine,DebugInfo,"Transaction(%u,%u). Received Frame(%u,%u) out of order! oseq=%u expecting %u. Send VNAK",
localCallNo(),remoteCallNo(),frame->type(),frame->subclass(),frame->oSeqNo(),m_iSeqNo);
sendVNAK();
m_inOutOfOrderFrames++;
return false;
}
DDebug(m_engine,DebugInfo,"Transaction(%u,%u) - received late Frame(%u,%u) with oseq=%u expecting %u [%p]",
DDebug(m_engine,DebugInfo,"Transaction(%u,%u). Received late Frame(%u,%u) with oseq=%u expecting %u [%p]",
localCallNo(),remoteCallNo(),frame->type(),frame->subclass(),frame->oSeqNo(),m_iSeqNo,this);
sendAck(frame);
return false;
@ -761,7 +761,7 @@ bool IAXTransaction::changeState(State newState)
return false;
default: ;
}
//Output("TRANSACTION: State change: %u --> %u",m_state,newState);
XDebug(m_engine,DebugInfo,"Transaction(%u,%u). State change: %u --> %u [%p]",localCallNo(),remoteCallNo(),m_state,newState,this);
m_state = newState;
return true;
}
@ -776,7 +776,7 @@ IAXEvent* IAXTransaction::terminate(u_int8_t evType, bool local, const IAXFullFr
ev = new IAXEvent((IAXEvent::Type)evType,local,true,this,frame->type(),frame->subclass());
else
ev = new IAXEvent((IAXEvent::Type)evType,local,true,this,0,0);
Debug(m_engine,DebugAll,"Transaction(%u,%u) - Terminated. Event: %u, Frame(%u,%u)",
Debug(m_engine,DebugAll,"Transaction(%u,%u). Terminated. Event: %u, Frame(%u,%u)",
localCallNo(),remoteCallNo(),evType,ev->frameType(),ev->subclass());
changeState(Terminated);
deref();
@ -786,7 +786,7 @@ IAXEvent* IAXTransaction::terminate(u_int8_t evType, bool local, const IAXFullFr
IAXEvent* IAXTransaction::waitForTerminate(u_int8_t evType, bool local, const IAXFullFrame* frame)
{
IAXEvent* ev = new IAXEvent((IAXEvent::Type)evType,local,true,this,frame);
Debug(m_engine,DebugAll,"Transaction(%u,%u) - Terminating. Event: %u, Frame(%u,%u)",
Debug(m_engine,DebugAll,"Transaction(%u,%u). Terminating. Event: %u, Frame(%u,%u)",
localCallNo(),remoteCallNo(),evType,ev->frameType(),ev->subclass());
changeState(Terminating);
m_timeout = (m_engine->transactionTimeout() + Time::secNow()) * 1000;
@ -955,7 +955,7 @@ IAXEvent* IAXTransaction::getEventResponse_New(IAXFrameOut* frame, bool& delFram
IAXEvent* IAXTransaction::processAuthReq(IAXEvent* event)
{
Debug(m_engine,DebugAll,"Transaction(%u,%u) - AuthReq received",localCallNo(),remoteCallNo());
Debug(m_engine,DebugAll,"Transaction(%u,%u). AuthReq received",localCallNo(),remoteCallNo());
if (event->type() == IAXEvent::Invalid)
return event;
// Valid authmethod & challenge ?
@ -964,20 +964,20 @@ IAXEvent* IAXTransaction::processAuthReq(IAXEvent* event)
bool bChallenge = event->getList().getString(IAXInfoElement::CHALLENGE,m_challenge);
IAXEvent* retEv;
if (bAuthMethod && bChallenge) {
Debug(m_engine,DebugAll,"Transaction(%u,%u) - Internal authentication reply",localCallNo(),remoteCallNo());
Debug(m_engine,DebugAll,"Transaction(%u,%u). Internal authentication reply",localCallNo(),remoteCallNo());
sendAuthReply();
retEv = event;
}
else {
retEv = internalReject(s_iax_modNoAuthMethod);
delete event;
retEv = internalReject(s_iax_modNoAuthMethod);
}
return retEv;
}
IAXEvent* IAXTransaction::processAuthRep(IAXEvent* event)
{
Debug(m_engine,DebugAll,"Transaction(%u,%u) - Auth Reply received",localCallNo(),remoteCallNo());
Debug(m_engine,DebugAll,"Transaction(%u,%u). Auth Reply received",localCallNo(),remoteCallNo());
if (event->type() == IAXEvent::Invalid)
return event;
event->getList().getString(IAXInfoElement::MD5_RESULT,m_authdata);
@ -1070,12 +1070,6 @@ IAXEvent* IAXTransaction::getEventStartTrans(IAXFullFrame* frame, bool& delFrame
init(ev->getList());
}
return ev;
case Poke:
if (!(frame->type() == IAXFrame::IAX && frame->subclass() == IAXControl::Poke))
break;
// Send PONG
postFrame(IAXFrame::IAX,IAXControl::Pong,0,0,frame->timeStamp(),true);
return createEvent(IAXEvent::Terminated,false,0,Terminating);
case RegReq:
case RegRel:
if (!(frame->type() == IAXFrame::IAX &&
@ -1084,6 +1078,12 @@ IAXEvent* IAXTransaction::getEventStartTrans(IAXFullFrame* frame, bool& delFrame
ev = createEvent(IAXEvent::New,false,frame,NewRemoteInvite);
init(ev->getList());
return ev;
case Poke:
if (!(frame->type() == IAXFrame::IAX && frame->subclass() == IAXControl::Poke))
break;
// Send PONG
postFrame(IAXFrame::IAX,IAXControl::Pong,0,0,frame->timeStamp(),true);
return createEvent(IAXEvent::Terminated,false,0,Terminating);
default: ;
}
delFrame = false;
@ -1096,7 +1096,7 @@ IAXEvent* IAXTransaction::getEventRequest(IAXFullFrame* frame, bool& delFrame)
delFrame = true;
// INVAL ?
if (frame->type() == IAXFrame::IAX && frame->subclass() == IAXControl::Inval) {
Debug(m_engine,DebugAll,"IAXTransaction(%u,%u) - Received INVAL. Terminate [%p]",
Debug(m_engine,DebugAll,"IAXTransaction(%u,%u). Received INVAL. Terminate [%p]",
localCallNo(),remoteCallNo(),this);
return createEvent(IAXEvent::Invalid,false,frame,Terminated);
}
@ -1115,13 +1115,6 @@ IAXEvent* IAXTransaction::getEventRequest(IAXFullFrame* frame, bool& delFrame)
default: ;
}
break;
case Poke:
if (!(frame->type() == IAXFrame::IAX && frame->subclass() == IAXControl::Poke))
break;
// Send PONG
postFrame(IAXFrame::IAX,IAXControl::Pong,0,0,frame->timeStamp());
changeState(Terminating);
return 0;
default: ;
}
delFrame = false;
@ -1241,9 +1234,9 @@ void IAXTransaction::sendAck(const IAXFullFrame* frame)
unsigned char buf[12] = {0x80 | localCallNo() >> 8,localCallNo(),remoteCallNo() >> 8,remoteCallNo(),
frame->timeStamp() >> 24,frame->timeStamp() >> 16,frame->timeStamp() >> 8,frame->timeStamp(),
frame->iSeqNo(),m_iSeqNo,IAXFrame::IAX,IAXControl::Ack};
DDebug(m_engine,DebugInfo,"Transaction(%u,%u) - Send ACK for Frame(%u,%u) oseq: %u iseq: %u",
DDebug(m_engine,DebugInfo,"Transaction(%u,%u). Send ACK for Frame(%u,%u) oseq: %u iseq: %u",
localCallNo(),remoteCallNo(),frame->type(),frame->subclass(),frame->oSeqNo(),frame->iSeqNo());
m_engine->writeSocket(buf,12,remoteAddr());
m_engine->writeSocket(buf,sizeof(buf),remoteAddr());
}
void IAXTransaction::sendInval()
@ -1252,7 +1245,7 @@ void IAXTransaction::sendInval()
unsigned char buf[12] = {0x80 | localCallNo() >> 8,localCallNo(),remoteCallNo() >> 8,remoteCallNo(),
ts >> 24,ts >> 16,ts >> 8,ts,
m_oSeqNo++,m_iSeqNo,IAXFrame::IAX,IAXControl::Inval};
m_engine->writeSocket(buf,12,remoteAddr());
m_engine->writeSocket(buf,sizeof(buf),remoteAddr());
}
void IAXTransaction::sendVNAK()
@ -1275,14 +1268,10 @@ IAXEvent* IAXTransaction::processInternalOutgoingRequest(IAXFrameOut* frame, boo
if (findInFrameTimestamp(frame,IAXFrame::IAX,IAXControl::Pong))
return 0;
break;
case IAXControl::Pong:
return 0;
case IAXControl::LagRq:
if (findInFrameTimestamp(frame,IAXFrame::IAX,IAXControl::LagRp))
return 0;
break;
case IAXControl::LagRp:
return 0;
default: ;
}
delFrame = false;
@ -1357,7 +1346,24 @@ IAXEvent* IAXTransaction::processMidCallIAXControl(const IAXFullFrame* frame, bo
case IAXControl::Inval:
return createEvent(IAXEvent::Invalid,false,frame,Terminated);
case IAXControl::Unsupport:
break;
return 0;
case IAXControl::Transfer:
case IAXControl::TxReady:
postFrame(IAXFrame::IAX,IAXControl::Unsupport,0,0,0,true);
return createEvent(IAXEvent::NotImplemented,false,frame,Terminating);
case IAXControl::DpReq:
case IAXControl::DpRep:
case IAXControl::Dial:
case IAXControl::TxReq:
case IAXControl::TxCnt:
case IAXControl::TxAcc:
case IAXControl::TxRel:
case IAXControl::TxRej:
case IAXControl::MWI:
case IAXControl::Provision:
case IAXControl::FwData:
//postFrame(IAXFrame::IAX,IAXControl::Unsupport,0,0,0,true);
return createEvent(IAXEvent::NotImplemented,false,frame,state());
default: ;
}
delFrame = false;
@ -1369,7 +1375,8 @@ IAXEvent* IAXTransaction::remoteRejectCall(const IAXFullFrame* frame, bool& delF
delFrame = true;
switch (type()) {
case New:
if (frame->type() == IAXFrame::IAX && (frame->subclass() == IAXControl::Hangup || frame->subclass() == IAXControl::Reject))
if ((frame->type() == IAXFrame::IAX && (frame->subclass() == IAXControl::Hangup || frame->subclass() == IAXControl::Reject)) ||
(frame->type() == IAXFrame::Control && frame->subclass() == IAXFullFrame::Hangup))
return createEvent(IAXEvent::Reject,false,frame,Terminating);
break;
case RegReq:
@ -1396,7 +1403,7 @@ IAXEvent* IAXTransaction::getEventTerminating(u_int64_t time)
IAXTransaction* IAXTransaction::processVoiceFrame(const IAXFullFrame* frame)
{
// Process format
DDebug(m_engine,DebugAll,"Transaction(%u,%u) - Received Voice Frame(%u,%u) iseq=%u oseq=%u stamp=%u [%p]",
DDebug(m_engine,DebugAll,"Transaction(%u,%u). Received Voice Frame(%u,%u) iseq=%u oseq=%u stamp=%u [%p]",
localCallNo(),remoteCallNo(),frame->type(),frame->subclass(),
frame->fullFrame()->iSeqNo(),frame->fullFrame()->oSeqNo(),frame->timeStamp(),this);
sendAck(frame);
@ -1426,21 +1433,21 @@ IAXTransaction* IAXTransaction::retransmitOnVNAK(u_int16_t seqNo)
c++;
}
}
DDebug(m_engine,DebugNote,"Transaction(%u,%u) - Retransmitted %d frames on VNAK(%u)",
DDebug(m_engine,DebugNote,"Transaction(%u,%u). Retransmitted %d frames on VNAK(%u)",
localCallNo(),remoteCallNo(),c,seqNo);
return 0;
}
IAXEvent* IAXTransaction::internalAccept()
{
Debug(m_engine,DebugAll,"Transaction(%u,%u) - Internal accept",localCallNo(),remoteCallNo());
Debug(m_engine,DebugAll,"Transaction(%u,%u). Internal accept",localCallNo(),remoteCallNo());
sendAccept();
return new IAXEvent(IAXEvent::Accept,true,true,this,IAXFrame::IAX,IAXControl::Accept);
}
IAXEvent* IAXTransaction::internalReject(String& reason)
{
Debug(m_engine,DebugAll,"Transaction(%u,%u) - Internal reject: '%s'",localCallNo(),remoteCallNo(),reason.c_str());
Debug(m_engine,DebugAll,"Transaction(%u,%u). Internal reject: '%s'",localCallNo(),remoteCallNo(),reason.c_str());
sendReject(reason);
IAXEvent* event = new IAXEvent(IAXEvent::Reject,true,true,this,IAXFrame::IAX,IAXControl::Reject);
event->getList().appendString(IAXInfoElement::CAUSE,reason);

View File

@ -52,6 +52,7 @@ class IAXInfoElementString;
class IAXInfoElementNumeric;
class IAXInfoElementBinary;
class IAXFullFrame;
class IAXFrameOut;
class IAXEvent;
class IAXEngine;
@ -155,7 +156,7 @@ public:
*/
static const char* ieText(u_int8_t ieCode);
protected:
private:
Type m_type; // Type of this IE
};
@ -200,7 +201,7 @@ public:
*/
virtual void toBuffer(DataBlock& buf);
protected:
private:
String m_strData; // IE text data
};
@ -244,7 +245,7 @@ public:
*/
virtual void toBuffer(DataBlock& buf);
protected:
private:
u_int8_t m_length; // IE data length
u_int32_t m_numericData; // IE numeric data
};
@ -305,7 +306,7 @@ public:
*/
static bool unpackIP(SocketAddr& addr, IAXInfoElementBinary* ie);
protected:
private:
DataBlock m_data; // IE binary data
};
@ -695,9 +696,18 @@ public:
static u_int32_t unpackSubclass(u_int8_t value);
protected:
/**
* Contains the frame's IE list for an incoming frame or the whole frame for an outgoing one
*/
DataBlock m_data;
/**
* Retransmission flag
*/
bool m_retrans;
private:
Type m_type; // Frame type
DataBlock m_data; // Frame IE list if incoming, the whole frame if outgoing
bool m_retrans; // Retransmission flag
u_int16_t m_sCallNo; // Source call number
u_int32_t m_tStamp; // Frame timestamp
};
@ -804,7 +814,7 @@ public:
*/
virtual const IAXFullFrame* fullFrame() const;
protected:
private:
u_int16_t m_dCallNo; // Destination call number
unsigned char m_oSeqNo; // Out sequence number
unsigned char m_iSeqNo; // In sequence number
@ -898,7 +908,7 @@ public:
*/
void adjustAuthTimeout(u_int64_t nextTransTime);
protected:
private:
bool m_ack; // Acknoledge flag
bool m_ackOnly; // Frame need only ACK as a response
u_int16_t m_retransCount; // Retransmission counter
@ -961,7 +971,7 @@ public:
*/
bool send(u_int32_t tStamp);
protected:
private:
u_int8_t* m_data; // Data buffer
u_int16_t m_dataAddIdx; // Current add index
u_int32_t m_timestamp; // Frame timestamp
@ -2092,11 +2102,6 @@ public:
inline Socket& socket()
{ return m_socket; }
/**
* Print engine data on stdin
*/
void print();
/**
* Get the MD5 data from a challenge and a password
* @param md5data Destination String
@ -2180,9 +2185,6 @@ private:
Mutex m_mutexTrunk; // Mutex for trunk operations
ObjList m_trunkList; // Trunk frames list
u_int32_t m_trunkSendInterval; // Trunk frame send interval
// Statistics
u_int64_t m_writeCommands;
u_int64_t m_writeCommandsFail;
};
}

View File

@ -332,6 +332,10 @@ public:
inline YIAXEngine* getEngine() const
{ return m_iaxEngine; }
static bool msgHasTrunkIn(Message& msg); // Test param: trunkin=yes
static bool msgHasTrunkOut(Message& msg); // Test param: trunkout=yes
protected:
YIAXEngine* m_iaxEngine;
u_int32_t m_defaultCodec;
@ -520,14 +524,14 @@ void YIAXLineContainer::regTerminate(IAXEvent* event)
line->m_nextReg = Time::secNow() + (line->expire() * 3 / 4);
line->m_callingNo = trans->callingNo();
line->m_callingName = trans->callingName();
Debug(&iplugin,DebugAll,"YIAXLineContainer::regTerminate[%s] - Ack for '%s'. Next: %u",
Debug(&iplugin,DebugAll,"YIAXLineContainer::regTerminate[%s] - ACK for '%s'. Next: %u",
line->c_str(),line->state() == YIAXLine::Registering?"Register":"Unregister",line->m_nextReg);
line->m_registered = true;
break;
case IAXEvent::Reject:
// retry at 25% of the expire time
line->m_nextReg = Time::secNow() + (line->expire() / 2);
Debug(&iplugin,DebugAll,"YIAXLineContainer::regTerminate[%s] - Reject for '%s'. Next: %u",
Debug(&iplugin,DebugAll,"YIAXLineContainer::regTerminate[%s] - REJECT for '%s'. Next: %u",
line->c_str(),line->state() == YIAXLine::Registering?"Register":"Unregister",line->m_nextReg);
line->m_registered = false;
break;
@ -779,7 +783,7 @@ IAXTransaction* YIAXEngine::reg(YIAXLine* line, bool regreq)
addr.host(line->remoteAddr());
addr.port(line->remotePort());
Debug(this,DebugAll,"Outgoing Registration[%s]:\nUsername: %s\nHost: %s\nPort: %d\nTime(sec): %u",
line->c_str(),line->username().c_str(),addr.host().c_str(),addr.port(),Time::secNow());
line->c_str(),line->username().c_str(),addr.host().c_str(),addr.port(),Time::secNow());
// Create IE list
IAXIEList ieList;
ieList.appendString(IAXInfoElement::USERNAME,line->username());
@ -824,11 +828,11 @@ void YIAXEngine::start(u_int16_t listenThreadCount, u_int16_t eventThreadCount,
if (m_threadsCreated)
return;
if (!listenThreadCount)
Debug(DebugWarn,"YIAXEngine - start. No reading socket threads(s)!.");
Debug(DebugWarn,"YIAXEngine. No reading socket threads(s)!.");
if (!eventThreadCount)
Debug(DebugWarn,"YIAXEngine - start. No reading event threads(s)!.");
Debug(DebugWarn,"YIAXEngine. No reading event threads(s)!.");
if (!trunkThreadCount)
Debug(DebugWarn,"YIAXEngine - start. No trunking threads(s)!.");
Debug(DebugWarn,"YIAXEngine. No trunking threads(s)!.");
for (; listenThreadCount; listenThreadCount--)
(new YIAXListener(this,"YIAXListener thread"))->startup();
for (; eventThreadCount; eventThreadCount--)
@ -860,8 +864,6 @@ void YIAXEngine::processEvent(IAXEvent* event)
event->getTransaction()->setUserData(connection);
if (!connection->route())
event->getTransaction()->setUserData(0);
else
enableTrunking(event->getTransaction());
}
}
break;
@ -1086,6 +1088,9 @@ bool YIAXDriver::msgExecute(Message& msg, String& dest)
if (ch && conn->connect(ch,msg.getValue("reason"))) {
msg.setParam("peerid",conn->id());
msg.setParam("targetid",conn->id());
// Enable trunking
if (msgHasTrunkOut(msg))
m_iaxEngine->enableTrunking(tr);
}
else
tr->setUserData(0);
@ -1106,6 +1111,16 @@ bool YIAXDriver::received(Message& msg, int id)
return Driver::received(msg,id);
}
bool YIAXDriver::msgHasTrunkIn(Message& msg)
{
return String(msg.getValue("trunkin")) == "yes";
}
bool YIAXDriver::msgHasTrunkOut(Message& msg)
{
return String(msg.getValue("trunkout")) == "yes";
}
/**
* IAXConsumer
*/
@ -1184,8 +1199,12 @@ void YIAXConnection::callAccept(Message& msg)
{
DDebug(this,DebugAll,"callAccept [%p]",this);
m_mutexTrans.lock();
if (m_transaction)
if (m_transaction) {
m_transaction->sendAccept();
// Enable trunking
if (YIAXDriver::msgHasTrunkIn(msg))
m_iaxEngine->enableTrunking(m_transaction);
}
m_mutexTrans.unlock();
Channel::callAccept(msg);
}
@ -1316,7 +1335,7 @@ void YIAXConnection::handleEvent(IAXEvent* event)
case IAXEvent::Answer:
if (isAnswered())
break;
Debug(this,DebugAll,"YIAXConnection - ANSWERED (%s)",isOutgoing()?"outgoing":"incoming");
Debug(this,DebugAll,"YIAXConnection - ANSWER");
status("answered");
startAudioIn();
startAudioOut();
@ -1430,7 +1449,7 @@ void YIAXConnection::startAudioIn()
const char* formatText = IAXFormat::audioText(format);
setSource(new YIAXSource(this,format,formatText));
getSource()->deref();
DDebug(this,DebugAll,"startAudioIn - Format %u: '%s'",format,formatText);
DDebug(this,DebugAll,"startAudioIn. Format %u: '%s'",format,formatText);
}
void YIAXConnection::startAudioOut()
@ -1445,7 +1464,7 @@ void YIAXConnection::startAudioOut()
const char* formatText = (char*)IAXFormat::audioText(format);
setConsumer(new YIAXConsumer(this,format,formatText));
getConsumer()->deref();
DDebug(this,DebugAll,"startAudioOut - Format %u: '%s'",format,formatText);
DDebug(this,DebugAll,"startAudioOut. Format %u: '%s'",format,formatText);
}
void YIAXConnection::evAuthRep(IAXEvent* event)