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:
parent
6f581a90d7
commit
168d0006af
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue