Added support for reporting route congestion.
Detection is currently implemented only on SIGTRAN M2UA. git-svn-id: http://yate.null.ro/svn/yate/trunk@3619 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
68e38ecffc
commit
1c176bb1cc
|
@ -705,6 +705,25 @@ bool SS7MTP3::inhibit(int sls, int setFlags, int clrFlags)
|
|||
return false;
|
||||
}
|
||||
|
||||
unsigned int SS7MTP3::congestion(int sls)
|
||||
{
|
||||
unsigned int level = 0;
|
||||
const ObjList* l = &m_links;
|
||||
for (; l; l = l->next()) {
|
||||
L2Pointer* p = static_cast<L2Pointer*>(l->get());
|
||||
if (!(p && *p))
|
||||
continue;
|
||||
if ((*p)->sls() == sls)
|
||||
return (*p)->congestion();
|
||||
else if (sls >= 0) {
|
||||
unsigned int cong = (*p)->congestion();;
|
||||
if (level < cong)
|
||||
level = cong;
|
||||
}
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
int SS7MTP3::getSequence(int sls) const
|
||||
{
|
||||
if (sls < 0)
|
||||
|
|
|
@ -171,7 +171,7 @@ SS7MsgSNM* SS7MsgSNM::parse(SS7Management* receiver, unsigned char type,
|
|||
do {
|
||||
// TFP,TFR,TFA: Q.704 15.7, RST,RSR: Q.704 15.10
|
||||
// There must be at least 2 bytes in buffer
|
||||
if (type == TFP || type == TFR || type == TFA ||
|
||||
if (type == TFP || type == TFR || type == TFA || type == TFC ||
|
||||
type == RST || type == RSR) {
|
||||
// 2 bytes destination
|
||||
SS7PointCode pc;
|
||||
|
@ -390,6 +390,7 @@ HandledMSU SS7Management::receivedMSU(const SS7MSU& msu, const SS7Label& label,
|
|||
if (msg->type() == SS7MsgSNM::TFP ||
|
||||
msg->type() == SS7MsgSNM::TFR ||
|
||||
msg->type() == SS7MsgSNM::TFA ||
|
||||
msg->type() == SS7MsgSNM::TFC ||
|
||||
msg->type() == SS7MsgSNM::RST ||
|
||||
msg->type() == SS7MsgSNM::RSR) {
|
||||
String dest = msg->params().getValue("destination");
|
||||
|
|
|
@ -168,6 +168,17 @@ bool SS7Route::operational(int sls)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check and reset congestion status
|
||||
bool SS7Route::congested()
|
||||
{
|
||||
if (m_congCount >= 8 || m_congBytes >= 256) {
|
||||
m_congCount = 0;
|
||||
m_congBytes = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to transmit a MSU through one of the attached networks
|
||||
int SS7Route::transmitMSU(const SS7Router* router, const SS7MSU& msu,
|
||||
const SS7Label& label, int sls, const SS7Layer3* source)
|
||||
|
@ -182,8 +193,14 @@ int SS7Route::transmitMSU(const SS7Router* router, const SS7MSU& msu,
|
|||
XDebug(router,DebugAll,"Attempting transmitMSU on L3=%p '%s' [%p]",
|
||||
(void*)l3,l3->toString().c_str(),router);
|
||||
int res = l3->transmitMSU(msu,label,sls);
|
||||
if (res != -1)
|
||||
if (res != -1) {
|
||||
unsigned int cong = l3->congestion(res);
|
||||
if (cong) {
|
||||
m_congCount++;
|
||||
m_congBytes += msu.length();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
lock();
|
||||
}
|
||||
unlock();
|
||||
|
@ -200,7 +217,7 @@ SS7Router::SS7Router(const NamedList& params)
|
|||
m_changes(0), m_transfer(false), m_phase2(false), m_started(false),
|
||||
m_restart(0), m_isolate(0), m_routeTest(0), m_testRestricted(false),
|
||||
m_checkRoutes(false), m_sendUnavail(true), m_sendProhibited(true),
|
||||
m_rxMsu(0), m_txMsu(0), m_fwdMsu(0),
|
||||
m_rxMsu(0), m_txMsu(0), m_fwdMsu(0), m_congestions(0),
|
||||
m_mngmt(0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -223,8 +240,8 @@ SS7Router::SS7Router(const NamedList& params)
|
|||
|
||||
SS7Router::~SS7Router()
|
||||
{
|
||||
Debug(this,DebugInfo,"SS7Router destroyed, rx=%lu, tx=%lu, fwd=%lu",
|
||||
m_rxMsu,m_txMsu,m_fwdMsu);
|
||||
Debug(this,DebugInfo,"SS7Router destroyed, rx=%lu, tx=%lu, fwd=%lu, cong=%lu",
|
||||
m_rxMsu,m_txMsu,m_fwdMsu,m_congestions);
|
||||
}
|
||||
|
||||
bool SS7Router::initialize(const NamedList* config)
|
||||
|
@ -538,10 +555,34 @@ int SS7Router::routeMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* net
|
|||
unlock();
|
||||
int slsTx = route ? route->transmitMSU(this,msu,label,sls,network) : -1;
|
||||
if (slsTx >= 0) {
|
||||
bool cong = route->congested();
|
||||
if (cong) {
|
||||
Debug(this,DebugMild,"Route to %u reports congestion",route->packed());
|
||||
while (m_mngmt) {
|
||||
unsigned int local = getLocal(label.type());
|
||||
if (!local)
|
||||
break;
|
||||
NamedList* ctl = m_mngmt->controlCreate("congest");
|
||||
if (!ctl)
|
||||
break;
|
||||
String addr;
|
||||
addr << SS7PointCode::lookup(label.type()) << ",";
|
||||
addr << SS7PointCode(label.type(),local) << "," << label.opc();
|
||||
String dest;
|
||||
dest << SS7PointCode(label.type(),route->packed());
|
||||
ctl->addParam("address",addr);
|
||||
ctl->addParam("destination",dest);
|
||||
ctl->setParam("automatic",String::boolText(true));
|
||||
m_mngmt->controlExecute(ctl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lock();
|
||||
m_txMsu++;
|
||||
if (network)
|
||||
m_fwdMsu++;
|
||||
if (cong)
|
||||
m_congestions++;
|
||||
unlock();
|
||||
}
|
||||
return slsTx;
|
||||
|
|
|
@ -1669,6 +1669,7 @@ bool SS7M2UA::processMAUP(unsigned char msgType, const DataBlock& msg, int strea
|
|||
case 3: // Establish Confirm
|
||||
m_lastSeqRx = -1;
|
||||
m_linkState = LinkUp;
|
||||
m_congestion = 0;
|
||||
m_rpo = false;
|
||||
SS7Layer2::notify();
|
||||
return true;
|
||||
|
@ -1751,6 +1752,20 @@ bool SS7M2UA::processMAUP(unsigned char msgType, const DataBlock& msg, int strea
|
|||
return recoveredMSU(data);
|
||||
}
|
||||
break;
|
||||
case 14: // Congestion Indication
|
||||
{
|
||||
u_int32_t cong = 0;
|
||||
if (!SIGAdaptation::getTag(msg,0x0304,cong)) {
|
||||
err = "Missing congestion state";
|
||||
break;
|
||||
}
|
||||
u_int32_t disc = 0;
|
||||
SIGAdaptation::getTag(msg,0x0305,disc);
|
||||
int level = disc ? DebugWarn : (cong ? DebugMild : DebugNote);
|
||||
Debug(this,level,"Congestion level %u, discard level %u",cong,disc);
|
||||
m_congestion = cong;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Debug(this,DebugStub,"%s M2UA MAUP message type %u",err,msgType);
|
||||
return false;
|
||||
|
@ -1760,6 +1775,7 @@ void SS7M2UA::activeChange(bool active)
|
|||
{
|
||||
if (!active) {
|
||||
getSequence();
|
||||
m_congestion = 0;
|
||||
m_rpo = false;
|
||||
switch (m_linkState) {
|
||||
case LinkUpEmg:
|
||||
|
|
|
@ -5089,6 +5089,13 @@ public:
|
|||
inline bool inhibited(int flags) const
|
||||
{ return (m_inhibited & flags) != 0; }
|
||||
|
||||
/**
|
||||
* Get the current congestion level of the link
|
||||
* @return Congestion level, 0 if not congested, 3 if maximum congestion
|
||||
*/
|
||||
virtual unsigned int congestion()
|
||||
{ return m_congestion; }
|
||||
|
||||
/**
|
||||
* Get the sequence number of the last MSU received
|
||||
* @return Last FSN received, negative if not available
|
||||
|
@ -5118,7 +5125,7 @@ protected:
|
|||
* Constructor
|
||||
*/
|
||||
inline SS7Layer2()
|
||||
: m_autoEmergency(true), m_lastSeqRx(-1),
|
||||
: m_autoEmergency(true), m_lastSeqRx(-1), m_congestion(0),
|
||||
m_l2userMutex(true,"SS7Layer2::l2user"), m_l2user(0), m_sls(-1),
|
||||
m_checkTime(0), m_checkFail(false), m_inhibited(Unchecked)
|
||||
{ }
|
||||
|
@ -5187,6 +5194,11 @@ protected:
|
|||
*/
|
||||
int m_lastSeqRx;
|
||||
|
||||
/**
|
||||
* Current congestion level
|
||||
*/
|
||||
unsigned int m_congestion;
|
||||
|
||||
private:
|
||||
Mutex m_l2userMutex;
|
||||
SS7L2User* m_l2user;
|
||||
|
@ -5234,7 +5246,7 @@ public:
|
|||
inline SS7Route(unsigned int packed, unsigned int priority = 0, unsigned int shift = 0)
|
||||
: Mutex(true,"SS7Route"),
|
||||
m_packed(packed), m_priority(priority), m_shift(shift),
|
||||
m_state(Unknown)
|
||||
m_state(Unknown), m_congCount(0), m_congBytes(0)
|
||||
{ m_networks.setDelete(false); }
|
||||
|
||||
/**
|
||||
|
@ -5244,7 +5256,8 @@ public:
|
|||
inline SS7Route(const SS7Route& original)
|
||||
: Mutex(true,"SS7Route"),
|
||||
m_packed(original.packed()), m_priority(original.priority()),
|
||||
m_shift(original.shift()), m_state(original.state())
|
||||
m_shift(original.shift()), m_state(original.state()),
|
||||
m_congCount(0), m_congBytes(0)
|
||||
{ m_networks.setDelete(false); }
|
||||
|
||||
/**
|
||||
|
@ -5343,12 +5356,20 @@ public:
|
|||
int transmitMSU(const SS7Router* router, const SS7MSU& msu,
|
||||
const SS7Label& label, int sls, const SS7Layer3* source = 0);
|
||||
|
||||
/**
|
||||
* Check the current congestion status according to Q.704 11.2.3.1
|
||||
* @return True if a TFC should be sent
|
||||
*/
|
||||
bool congested();
|
||||
|
||||
private:
|
||||
unsigned int m_packed; // Packed destination point code
|
||||
unsigned int m_priority; // Network priority for the given destination (used by SS7Layer3)
|
||||
unsigned int m_shift; // SLS right shift when selecting linkset
|
||||
ObjList m_networks; // List of networks used to route to the given destination (used by SS7Router)
|
||||
State m_state; // State of the route
|
||||
unsigned int m_congCount; // Congestion event count
|
||||
unsigned int m_congBytes; // Congestion MSU bytes count
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -5491,6 +5512,14 @@ public:
|
|||
virtual bool inhibit(int sls, int setFlags, int clrFlags = 0)
|
||||
{ return false; }
|
||||
|
||||
/**
|
||||
* Get the current congestion level of a link
|
||||
* @param sls Signalling Link to check for congestion, -1 for maximum
|
||||
* @return Congestion level, 0 if not congested, 3 if maximum congestion
|
||||
*/
|
||||
virtual unsigned int congestion(int sls)
|
||||
{ return 0; }
|
||||
|
||||
/**
|
||||
* Get the sequence number of the last MSU received on a link
|
||||
* @param sls Signalling Link to retrieve MSU number from
|
||||
|
@ -6206,6 +6235,7 @@ private:
|
|||
unsigned long m_rxMsu;
|
||||
unsigned long m_txMsu;
|
||||
unsigned long m_fwdMsu;
|
||||
unsigned long m_congestions;
|
||||
SS7Management* m_mngmt;
|
||||
};
|
||||
|
||||
|
@ -6828,6 +6858,13 @@ public:
|
|||
*/
|
||||
virtual bool inhibit(int sls, int setFlags, int clrFlags = 0);
|
||||
|
||||
/**
|
||||
* Get the current congestion level of a link
|
||||
* @param sls Signalling Link to check for congestion, -1 for maximum
|
||||
* @return Congestion level, 0 if not congested, 3 if maximum congestion
|
||||
*/
|
||||
virtual unsigned int congestion(int sls);
|
||||
|
||||
/**
|
||||
* Get the sequence number of the last MSU received on a link
|
||||
* @param sls Signalling Link to retrieve MSU number from
|
||||
|
|
Loading…
Reference in New Issue