Made configurable ping interval, frame retransmission counter and interval.

git-svn-id: http://voip.null.ro/svn/yate@5537 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2013-06-11 13:41:36 +00:00
parent 373c4c2033
commit bda1e37157
6 changed files with 143 additions and 95 deletions

View File

@ -111,6 +111,24 @@
; Defaults to yes
;calltoken_rejectmissing=yes
; retrans_count: integer: The number of frame retransmissions
; This parameter is applied on reload for new calls only
; Allowed interval: 1..10
; Defaults to 4
;retrans_count=4
; retrans_interval: integer: The first frame retransmission interval in milliseconds
; This parameter is applied on reload for new calls only
; Allowed interval: 200..5000
; Defaults to 500
;retrans_interval=500
; ping_interval: integer: The interval, in milliseconds, to send ping
; This parameter is applied on reload for new calls only
; Minimum allowed value is 10000
; Defaults to 20000
;ping_interval=20000
; adjust_ts_out_threshold: integer: The difference, in milliseconds, between sent audio data
; timestamp and transaction timestamp at which audio data timestamp will be adjusted
; Its value will be rouded up to a multiple of 10

View File

@ -55,7 +55,7 @@ static void buildSecretDigest(String& buf, const String& secret, unsigned int t,
}
IAXEngine::IAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval,
IAXEngine::IAXEngine(const char* iface, int port, u_int16_t transListCount,
u_int16_t authTimeout, u_int16_t transTimeout, u_int16_t maxFullFrameDataLen,
u_int32_t format, u_int32_t capab, bool authRequired, NamedList* params)
: Mutex(true,"IAXEngine"),
@ -64,8 +64,6 @@ IAXEngine::IAXEngine(const char* iface, int port, u_int16_t transListCount, u_in
m_maxFullFrameDataLen(maxFullFrameDataLen),
m_startLocalCallNo(0),
m_transListCount(0),
m_retransCount(retransCount),
m_retransInterval(retransInterval),
m_authTimeout(authTimeout),
m_transTimeout(transTimeout),
m_callToken(false),
@ -80,7 +78,8 @@ IAXEngine::IAXEngine(const char* iface, int port, u_int16_t transListCount, u_in
m_adjustTsOutThreshold(IAX2_ADJUSTTSOUT_THRES),
m_adjustTsOutOverrun(IAX2_ADJUSTTSOUT_OVER),
m_adjustTsOutUnderrun(IAX2_ADJUSTTSOUT_UNDER),
m_mutexTrunk(false,"IAXEngine::Trunk")
m_mutexTrunk(false,"IAXEngine::Trunk"),
m_trunkInfoMutex(false,"IAXEngine::TrunkInfo")
{
debugName("iaxengine");
Debug(this,DebugAll,"Automatically request authentication set to '%s'.",
@ -410,8 +409,14 @@ void IAXEngine::initialize(const NamedList& params)
m_callerNumType = lookup(params["numtype"],IAXInfoElement::s_typeOfNumber);
m_callingPres = lookup(params["presentation"],IAXInfoElement::s_presentation) |
lookup(params["screening"],IAXInfoElement::s_screening);
m_trunkInfoDef.init(params,"trunk_");
initOutDataAdjust(params);
IAXTrunkInfo* ti = new IAXTrunkInfo;
ti->initTrunking(params,"trunk_",0,true);
ti->initTrunking(params,"trunk_",0,false);
ti->init(params);
Lock lck(m_trunkInfoMutex);
m_trunkInfoDef = ti;
TelEngine::destruct(ti);
}
void IAXEngine::readSocket(SocketAddr& addr)
@ -782,6 +787,20 @@ void IAXEngine::defaultEventHandler(IAXEvent* event)
}
}
static bool getTrunkingInfo(RefPointer<IAXTrunkInfo>& ti, IAXEngine* engine,
const NamedList* params, const String& prefix, bool out)
{
if (!engine->trunkInfo(ti))
return false;
if (!params)
return true;
IAXTrunkInfo* tmp = new IAXTrunkInfo;
tmp->initTrunking(*params,prefix,ti,out);
ti = tmp;
TelEngine::destruct(tmp);
return true;
}
void IAXEngine::enableTrunking(IAXTransaction* trans, const NamedList* params,
const String& prefix)
{
@ -797,14 +816,12 @@ void IAXEngine::enableTrunking(IAXTransaction* trans, const NamedList* params,
return;
}
}
IAXTrunkInfo tmp;
IAXTrunkInfo* trunk = &m_trunkInfoDef;
if (params) {
tmp.initTrunking(*params,prefix,trunk,true);
trunk = &tmp;
}
frame = new IAXMetaTrunkFrame(this,trans->remoteAddr(),trunk->m_timestamps,
trunk->m_maxLen,trunk->m_sendInterval);
RefPointer<IAXTrunkInfo> ti;
if (!getTrunkingInfo(ti,this,params,prefix,true))
return;
frame = new IAXMetaTrunkFrame(this,trans->remoteAddr(),ti->m_timestamps,
ti->m_maxLen,ti->m_sendInterval);
ti = 0;
if (trans->enableTrunking(frame)) {
m_trunkList.append(frame);
Debug(this,DebugAll,
@ -823,14 +840,12 @@ void IAXEngine::initTrunkIn(IAXTransaction* trans, const NamedList* params,
{
if (!trans)
return;
IAXTrunkInfo tmp;
IAXTrunkInfo* trunk = &m_trunkInfoDef;
if (params) {
tmp.initTrunking(*params,prefix,trunk,false);
trunk = &tmp;
}
trans->m_trunkInSyncUsingTs = trunk->m_trunkInSyncUsingTs;
trans->m_trunkInTsDiffRestart = trunk->m_trunkInTsDiffRestart;
RefPointer<IAXTrunkInfo> ti;
if (!getTrunkingInfo(ti,this,params,prefix,false))
return;
trans->m_trunkInSyncUsingTs = ti->m_trunkInSyncUsingTs;
trans->m_trunkInTsDiffRestart = ti->m_trunkInTsDiffRestart;
ti = 0;
}
void IAXEngine::runProcessTrunkFrames()

View File

@ -1447,8 +1447,15 @@ void IAXFrameOut::adjustAuthTimeout(u_int64_t nextTransTime)
void IAXTrunkInfo::init(const NamedList& params, const String& prefix,
const IAXTrunkInfo* def)
{
initTrunking(params,prefix,def,true);
initTrunking(params,prefix,def,false);
m_retransCount = params.getIntValue(prefix + "retrans_count",
def ? def->m_retransCount : IAX2_RETRANS_COUNT_DEF,
IAX2_RETRANS_COUNT_MIN,IAX2_RETRANS_COUNT_MAX);
m_retransInterval = params.getIntValue(prefix + "retrans_interval",
def ? def->m_retransInterval : IAX2_RETRANS_INTERVAL_DEF,
IAX2_RETRANS_INTERVAL_MIN,IAX2_RETRANS_INTERVAL_MAX);
m_pingInterval = params.getIntValue(prefix + "ping_interval",
def ? def->m_retransInterval : IAX2_PING_INTERVAL_DEF,
IAX2_PING_INTERVAL_MIN);
}
// Init from parameters

View File

@ -104,10 +104,6 @@ IAXTransaction::IAXTransaction(IAXEngine* engine, IAXFullFrame* frame, u_int16_t
m_trunkInTsDiffRestart(5000),
m_trunkInFirstTs(0)
{
// Setup transaction
m_retransCount = engine->retransCount();
m_retransInterval = engine->retransInterval();
m_timeToNextPing = m_timeStamp + m_pingInterval;
switch (frame->subclass()) {
case IAXControl::New:
m_type = New;
@ -126,11 +122,7 @@ IAXTransaction::IAXTransaction(IAXEngine* engine, IAXFullFrame* frame, u_int16_t
localCallNo(),remoteCallNo(),frame->subclass(),this);
return;
}
Debug(m_engine,DebugAll,"Transaction(%u,%u) incoming type=%s remote=%s:%d [%p]",
localCallNo(),remoteCallNo(),typeName(),m_addr.host().c_str(),m_addr.port(),this);
engine->getOutDataAdjust(m_adjustTsOutThreshold,m_adjustTsOutOverrun,
m_adjustTsOutUnderrun);
engine->initTrunkIn(this);
init();
// Append frame to incoming list
Lock lock(this);
m_inFrames.append(frame);
@ -181,8 +173,6 @@ IAXTransaction::IAXTransaction(IAXEngine* engine, Type type, u_int16_t lcallno,
m_trunkInTsDiffRestart(5000),
m_trunkInFirstTs(0)
{
Debug(m_engine,DebugAll,"Transaction(%u,%u) outgoing type=%s remote=%s:%d [%p]",
localCallNo(),remoteCallNo(),typeName(),m_addr.host().c_str(),m_addr.port(),this);
// Init data members
if (!m_addr.port()) {
XDebug(m_engine,DebugAll,
@ -190,9 +180,6 @@ IAXTransaction::IAXTransaction(IAXEngine* engine, Type type, u_int16_t lcallno,
localCallNo(),remoteCallNo(),this);
m_addr.port(4569);
}
m_retransCount = engine->retransCount();
m_retransInterval = engine->retransInterval();
m_timeToNextPing = m_timeStamp + m_pingInterval;
init(ieList);
IAXControl::Type frametype;
IAXIEList* ies = new IAXIEList;
@ -237,9 +224,7 @@ IAXTransaction::IAXTransaction(IAXEngine* engine, Type type, u_int16_t lcallno,
m_type = Incorrect;
return;
}
engine->getOutDataAdjust(m_adjustTsOutThreshold,m_adjustTsOutOverrun,
m_adjustTsOutUnderrun);
engine->initTrunkIn(this);
init();
postFrameIes(IAXFrame::IAX,frametype,ies);
changeState(NewLocalInvite);
}
@ -663,13 +648,15 @@ IAXEvent* IAXTransaction::getEvent(u_int64_t time)
if (state() == NewRemoteInvite_AuthSent && frame->ack())
frame->adjustAuthTimeout(time + m_engine->authTimeout() * 1000);
// No response. Timeout ?
if (frame->timeout() && frame->timeForRetrans(time)) {
if (m_state == Terminating)
// Client already notified: Terminate transaction
ev = terminate(IAXEvent::Timeout,true);
else
// Client not notified: Notify it and terminate transaction
ev = terminate(IAXEvent::Timeout,true,frame,false);
if (!frame->retransCount()) {
if (frame->timeForRetrans(time)) {
if (m_state == Terminating)
// Client already notified: Terminate transaction
ev = terminate(IAXEvent::Timeout,true);
else
// Client not notified: Notify it and terminate transaction
ev = terminate(IAXEvent::Timeout,true,frame,false);
}
break;
}
// Retransmit ?
@ -677,8 +664,10 @@ IAXEvent* IAXTransaction::getEvent(u_int64_t time)
if (frame->ack())
frame->transmitted(); // Frame acknoledged: just update retransmission info
else {
Debug(m_engine,DebugNote,"Transaction(%u,%u) resending Frame(%u,%u) oseq=%u iseq=%u stamp=%u [%p]",
localCallNo(),remoteCallNo(),frame->type(),frame->subclass(),frame->oSeqNo(),frame->iSeqNo(),frame->timeStamp(),this);
Debug(m_engine,DebugNote,
"Transaction(%u,%u) resending Frame(%u,%u) oseq=%u iseq=%u stamp=%u remaining=%u [%p]",
localCallNo(),remoteCallNo(),frame->type(),frame->subclass(),
frame->oSeqNo(),frame->iSeqNo(),frame->timeStamp(),frame->retransCount() - 1,this);
sendFrame(frame); // Retransmission
}
}
@ -2019,7 +2008,7 @@ void IAXTransaction::postFrame(IAXFrameOut* frame)
{
if (!frame)
return;
DDebug(m_engine,DebugAll,
Debug(m_engine,DebugAll,
"Transaction(%u,%u) posting Frame(%u,%u) oseq=%u iseq=%u stamp=%u [%p]",
localCallNo(),remoteCallNo(),frame->type(),frame->subclass(),
m_oSeqNo,m_iSeqNo,frame->timeStamp(),this);
@ -2041,4 +2030,22 @@ void IAXTransaction::receivedVoiceMiniBeforeFull()
sendVNAK();
}
void IAXTransaction::init()
{
Debug(m_engine,DebugAll,"Transaction %s call=%u type=%s remote=%s:%d [%p]",
outgoing() ? "outgoing" : "incoming",localCallNo(),typeName(),m_addr.host().c_str(),
m_addr.port(),this);
m_engine->getOutDataAdjust(m_adjustTsOutThreshold,m_adjustTsOutOverrun,m_adjustTsOutUnderrun);
RefPointer<IAXTrunkInfo> ti;
if (!m_engine->trunkInfo(ti))
return;
m_trunkInSyncUsingTs = ti->m_trunkInSyncUsingTs;
m_trunkInTsDiffRestart = ti->m_trunkInTsDiffRestart;
m_retransCount = ti->m_retransCount;
m_retransInterval = ti->m_retransInterval;
m_pingInterval = ti->m_pingInterval;
ti = 0;
m_timeToNextPing = m_timeStamp + m_pingInterval;
}
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -79,6 +79,18 @@ class IAXEngine; // IAX engine
#define IAX2_TRUNKFRAME_SEND_MIN 5
#define IAX2_TRUNKFRAME_SEND_DEF 20
// Frame retransmission
#define IAX2_RETRANS_COUNT_MIN 1
#define IAX2_RETRANS_COUNT_MAX 10
#define IAX2_RETRANS_COUNT_DEF 4
#define IAX2_RETRANS_INTERVAL_MIN 200
#define IAX2_RETRANS_INTERVAL_MAX 5000
#define IAX2_RETRANS_INTERVAL_DEF 500
// Ping
#define IAX2_PING_INTERVAL_MIN 10000
#define IAX2_PING_INTERVAL_DEF 20000
/**
* This class holds a single Information Element with no data
* @short A single IAX2 Information Element
@ -1344,11 +1356,11 @@ public:
{}
/**
* Get the timeout (retransmission counter) of this frame
* @return True if the retransmission counter is 0
* Get the retransmission counter of this frame
* @return The retransmission counter is 0
*/
inline bool timeout() const
{ return m_retransCount == 0; }
inline unsigned int retransCount() const
{ return m_retransCount; }
/**
* Ask the frame if it's time for retransmit
@ -1406,7 +1418,7 @@ private:
* This class holds trunk description
* @short Trunk info
*/
class YIAX_API IAXTrunkInfo : public GenObject
class YIAX_API IAXTrunkInfo : public RefObject
{
public:
/**
@ -1415,22 +1427,25 @@ public:
inline IAXTrunkInfo()
: m_timestamps(true), m_sendInterval(IAX2_TRUNKFRAME_SEND_DEF),
m_maxLen(IAX2_TRUNKFRAME_LEN_DEF), m_trunkInSyncUsingTs(true),
m_trunkInTsDiffRestart(5000)
m_trunkInTsDiffRestart(5000),
m_retransCount(IAX2_RETRANS_COUNT_DEF),
m_retransInterval(IAX2_RETRANS_INTERVAL_DEF),
m_pingInterval(IAX2_PING_INTERVAL_DEF)
{}
/**
* Init all data from parameters
* Init non trunking related data
* @param params Parameter list
* @param prefix Parameter prefix (used as value for enable parameter also)
* @param prefix Parameter prefix
* @param def Optional defaults
*/
void init(const NamedList& params, const String& prefix,
void init(const NamedList& params, const String& prefix = String::empty(),
const IAXTrunkInfo* def = 0);
/**
* Init trunking from parameters
* @param params Parameter list
* @param prefix Parameter prefix (used as value for enable parameter also)
* @param prefix Parameter prefix
* @param def Optional defaults
* @param out True to init outgoing trunk data, false to init incoming trunk info
*/
@ -1444,6 +1459,9 @@ public:
// time or trunk timestamp to re-build frame ts
u_int32_t m_trunkInTsDiffRestart; // Incoming trunk without timestamp: diff between
// timestamps at which we restart
unsigned int m_retransCount; // Frame retransmission counter
unsigned int m_retransInterval; // Frame retransmission interval in milliseconds
unsigned int m_pingInterval; // Ping interval in milliseconds
};
/**
@ -2471,6 +2489,7 @@ private:
void adjustTStamp(u_int32_t& tStamp);
void postFrame(IAXFrameOut* frame);
void receivedVoiceMiniBeforeFull();
void init();
inline void restartTrunkIn(u_int64_t now, u_int32_t ts) {
m_trunkInStartTime = now;
u_int64_t dt = (now - m_lastVoiceFrameIn) / 1000;
@ -2500,8 +2519,8 @@ private:
IAXEvent* m_currentEvent; // Pointer to last generated event or 0
// Outgoing frames management
ObjList m_outFrames; // Transaction & protocol control outgoing frames
u_int16_t m_retransCount; // Retransmission counter. 0 --> Timeout
u_int32_t m_retransInterval; // Frame retransmission interval
unsigned int m_retransCount; // Retransmission counter. 0 --> Timeout
unsigned int m_retransInterval; // Frame retransmission interval
// Incoming frames management
ObjList m_inFrames; // Transaction & protocol control incoming frames
static unsigned char m_maxInFrames; // Max frames number allowed in m_inFrames
@ -2700,8 +2719,6 @@ public:
* @param iface Address of the interface to use, default all (0.0.0.0)
* @param port UDP port to run the protocol on
* @param transListCount Number of entries in the transaction hash table
* @param retransCount Retransmission counter for each transaction belonging to this engine
* @param retransInterval Retransmission interval default value in miliseconds
* @param authTimeout Timeout (in seconds) of acknoledged auth frames sent
* @param transTimeout Timeout (in seconds) on remote request of transactions belonging to this engine
* @param maxFullFrameDataLen Max full frame IE list (buffer) length
@ -2710,7 +2727,7 @@ public:
* @param authRequired Automatically challenge all clients for authentication
* @param params Optional extra parameter list
*/
IAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval,
IAXEngine(const char* iface, int port, u_int16_t transListCount,
u_int16_t authTimeout, u_int16_t transTimeout, u_int16_t maxFullFrameDataLen,
u_int32_t format, u_int32_t capab, bool authRequired, NamedList* params = 0);
@ -2779,20 +2796,6 @@ public:
*/
bool process();
/**
* Get default frame retransmission counter
* @return Frame retransmission counter
*/
inline u_int16_t retransCount() const
{ return m_retransCount; }
/**
* Get default frame retransmission starting interval
* @return Frame retransmission starting interval
*/
inline u_int16_t retransInterval() const
{ return m_retransInterval; }
/**
* Check if a transaction should automatically request authentication
* @return True to automatically request authentication
@ -2972,10 +2975,14 @@ public:
/**
* Retrieve the default trunk info data
* @return Trunk info pointer, 0 if not found
* @param info Destination to be set with trunk info pointer
* @return True if destination pointr is valid
*/
inline IAXTrunkInfo* trunkInfo()
{ return &m_trunkInfoDef; }
inline bool trunkInfo(RefPointer<IAXTrunkInfo>& info) {
Lock lck(m_trunkInfoMutex);
info = m_trunkInfoDef;
return info != 0;
}
/**
* Send an INVAL frame
@ -3129,8 +3136,6 @@ private:
int m_maxFullFrameDataLen; // Max full frame data (IE list) length
u_int16_t m_startLocalCallNo; // Start index of local call number allocation
u_int16_t m_transListCount; // m_transList count
u_int16_t m_retransCount; // Retransmission counter for each transaction belonging to this engine
u_int16_t m_retransInterval; // Retransmission interval default value in miliseconds
u_int16_t m_authTimeout; // Timeout (in seconds) of acknoledged auth frames sent
u_int32_t m_transTimeout; // Timeout (in seconds) on remote request of transactions
// belonging to this engine
@ -3154,7 +3159,8 @@ private:
// Trunking
Mutex m_mutexTrunk; // Mutex for trunk operations
ObjList m_trunkList; // Trunk frames list
IAXTrunkInfo m_trunkInfoDef; // Defaults for trunk data
Mutex m_trunkInfoMutex; // Trunk info mutex
RefPointer<IAXTrunkInfo> m_trunkInfoDef; // Defaults for trunk data
};
}

View File

@ -279,14 +279,12 @@ public:
* @param iface Interface address to use
* @param port UDP port to use
* @param transListCount Number of entries in the transaction hash table
* @param retransCount Retransmission counter for each transaction belonging to this engine
* @param retransInterval Retransmission interval default value in miliseconds
* @param authTimeout Timeout (in seconds) of acknoledged auth frames sent
* @param transTimeout Timeout (in seconds) on remote request of transactions belonging to this engine
* @param maxFullFrameDataLen Max full frame IE list (buffer) length
* @param authRequired Automatically challenge all clients for authentication
*/
YIAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval,
YIAXEngine(const char* iface, int port, u_int16_t transListCount,
u_int16_t authTimeout, u_int16_t transTimeout,
u_int16_t maxFullFrameDataLen, bool authRequired,
NamedList* params);
@ -1033,10 +1031,9 @@ void YIAXTrunking::run()
* YIAXEngine
*/
YIAXEngine::YIAXEngine(const char* iface, int port, u_int16_t transListCount,
u_int16_t retransCount, u_int16_t retransInterval, u_int16_t authTimeout,
u_int16_t transTimeout, u_int16_t maxFullFrameDataLen,
u_int16_t authTimeout, u_int16_t transTimeout, u_int16_t maxFullFrameDataLen,
bool authRequired, NamedList* params)
: IAXEngine(iface,port,transListCount,retransCount,retransInterval,authTimeout,
: IAXEngine(iface,port,transListCount,authTimeout,
transTimeout,maxFullFrameDataLen,0,0,authRequired,params),
m_threadsCreated(false)
{
@ -1448,8 +1445,6 @@ void YIAXDriver::initialize()
Engine::install(new YIAXRegDataHandler);
// Init IAX engine
u_int16_t transListCount = 64;
u_int16_t retransCount = 4;
u_int16_t retransInterval = 500;
u_int16_t authTimeout = 30;
u_int16_t transTimeout = 10;
u_int16_t maxFullFrameDataLen = 1400;
@ -1458,8 +1453,8 @@ void YIAXDriver::initialize()
// set max chans
maxChans(gen->getIntValue("maxchans",maxChans()));
bool authReq = cfg.getBoolValue("registrar","auth_required",true);
m_iaxEngine = new YIAXEngine(iface,m_port,transListCount,retransCount,
retransInterval,authTimeout,transTimeout,maxFullFrameDataLen,authReq,gen);
m_iaxEngine = new YIAXEngine(iface,m_port,transListCount,
authTimeout,transTimeout,maxFullFrameDataLen,authReq,gen);
m_iaxEngine->debugChain(this);
m_iaxEngine->initFormats(cfg.getSection("formats"));
int tos = gen->getIntValue("tos",dict_tos,0);