Added special option to avoid inhibiting the last link in a linkset.

If a linkset becomes isolated try to forcibly uninhibit operational links.


git-svn-id: http://voip.null.ro/svn/yate@3552 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2010-08-27 13:40:28 +00:00
parent 529db7197a
commit 0cdcf17b92
4 changed files with 56 additions and 8 deletions

View File

@ -569,7 +569,7 @@ unsigned int SS7MTP3::countLinks()
if (!(p && *p))
continue;
total++;
if ((*p)->operational() && !((*p)->inhibited(SS7Layer2::Unchecked|SS7Layer2::Inactive)))
if ((*p)->operational() && !((*p)->inhibited()))
active++;
}
m_total = total;
@ -957,7 +957,8 @@ bool SS7MTP3::receivedMSU(const SS7MSU& msu, SS7Layer2* link, int sls)
notify(link);
}
}
if (!maint && (msu.getSIF() != SS7MSU::SNM) && link->inhibited()) {
if (!maint && (msu.getSIF() != SS7MSU::SNM) &&
link->inhibited(SS7Layer2::Unchecked|SS7Layer2::Inactive|SS7Layer2::Local)) {
Debug(this,DebugMild,"Received MSU on inhibited link %d '%s' [%p]",
sls,link->toString().c_str(),this);
return false;
@ -1010,7 +1011,7 @@ void SS7MTP3::notify(SS7Layer2* link)
if (act != m_active) {
Debug(this,DebugNote,"Linkset is%s operational [%p]",
(operational() ? "" : " not"),this);
// if we became inaccessible try to resume all other links
// if we became inaccessible try to uninhibit or resume all other links
unsigned int cnt = 0;
for (const ObjList* l = &m_links; l && !(m_active || m_inhibit); l = l->next()) {
L2Pointer* p = static_cast<L2Pointer*>(l->get());
@ -1020,10 +1021,15 @@ void SS7MTP3::notify(SS7Layer2* link)
if ((l2 == link) || !l2)
continue;
cnt++;
l2->control(SS7Layer2::Resume);
if (l2->operational() &&
l2->inhibited(SS7Layer2::Local|SS7Layer2::Remote) &&
!l2->inhibited(SS7Layer2::Unchecked|SS7Layer2::Inactive))
l2->inhibit(0,SS7Layer2::Local|SS7Layer2::Remote);
else
l2->control(SS7Layer2::Resume);
}
if (cnt)
Debug(this,DebugNote,"Attempted to resume %u links [%p]",cnt,this);
Debug(this,DebugNote,"Attempted to uninhibit/resume %u links [%p]",cnt,this);
SS7Layer3::notify(link ? link->sls() : -1);
}
}

View File

@ -303,6 +303,17 @@ HandledMSU SS7Management::receivedMSU(const SS7MSU& msu, const SS7Label& label,
{
if (msu.getSIF() != sif())
return HandledMSU::Rejected;
if (network) {
unsigned int local = network->getLocal(label.type());
if (local && label.dpc().pack(label.type()) != local)
return HandledMSU::Rejected;
}
SS7Router* router = YOBJECT(SS7Router,SS7Layer4::network());
if (router && (router != network)) {
unsigned int local = network->getLocal(label.type());
if (local && label.dpc().pack(label.type()) != local)
return HandledMSU::Rejected;
}
unsigned int len = msu.length() - label.length() - 1;
// according to Q.704 there should be at least the heading codes (8 bit)
@ -320,7 +331,6 @@ HandledMSU SS7Management::receivedMSU(const SS7MSU& msu, const SS7Label& label,
len,msg,sls,tmp.c_str());
}
SS7Router* router = YOBJECT(SS7Router,SS7Layer4::network());
// TODO: implement
String addr;
addr << label;
@ -440,6 +450,8 @@ HandledMSU SS7Management::receivedMSU(const SS7MSU& msu, const SS7Label& label,
Debug(this,DebugNote,"Changeback acknowledged on %s",link.c_str());
inhibit(*pend,0,SS7Layer2::Inactive);
}
else
Debug(this,DebugMild,"Unexpected %s %s [%p]",msg->name(),addr.c_str(),this);
TelEngine::destruct(pend);
}
else if (msg->type() == SS7MsgSNM::COA ||
@ -473,8 +485,27 @@ HandledMSU SS7Management::receivedMSU(const SS7MSU& msu, const SS7Label& label,
Debug(this,DebugNote,"Changeover acknowledged on %s",link.c_str());
inhibit(*pend,SS7Layer2::Inactive);
}
else
Debug(this,DebugMild,"Unexpected %s %s [%p]",msg->name(),addr.c_str(),this);
TelEngine::destruct(pend);
}
else if (msg->type() == SS7MsgSNM::LIN) {
Debug(this,DebugAll,"%s (code len=%u) [%p]",msg->name(),len,this);
SS7Label lbl(label,label.sls(),0);
if (router) {
unsigned char data = (router->inhibit(lbl,SS7Layer2::Remote,0,true))
? SS7MsgSNM::LIA : SS7MsgSNM::LID;
return transmitMSU(SS7MSU(msu.getSIO(),lbl,&data,1),lbl,sls) >= 0;
}
}
else if (msg->type() == SS7MsgSNM::LUN || msg->type() == SS7MsgSNM::LFU) {
Debug(this,DebugAll,"%s (code len=%u) [%p]",msg->name(),len,this);
SS7Label lbl(label,label.sls(),0);
if (router && router->inhibit(lbl,0,SS7Layer2::Remote)) {
static unsigned char lua = SS7MsgSNM::LUA;
return transmitMSU(SS7MSU(msu.getSIO(),lbl,&lua,1),lbl,sls) >= 0;
}
}
else {
String tmp;
tmp.hexify((void*)buf,len,' ');
@ -800,6 +831,11 @@ HandledMSU SS7Maintenance::receivedMSU(const SS7MSU& msu, const SS7Label& label,
{
if (msu.getSIF() != sif() && msu.getSIF() != SS7MSU::MTNS)
return HandledMSU::Rejected;
if (network) {
unsigned int local = network->getLocal(label.type());
if (local && label.dpc().pack(label.type()) != local)
return HandledMSU::Rejected;
}
XDebug(this,DebugStub,"Possibly incomplete SS7Maintenance::receivedMSU(%p,%p,%p,%d) [%p]",
&msu,&label,network,sls,this);

View File

@ -784,7 +784,7 @@ void SS7Router::checkRoutes(const SS7Layer3* noResume)
}
}
bool SS7Router::inhibit(const SS7Label& link, int setFlags, int clrFlags)
bool SS7Router::inhibit(const SS7Label& link, int setFlags, int clrFlags, bool notLast)
{
int remote = link.dpc().pack(link.type());
if (!remote)
@ -796,6 +796,11 @@ bool SS7Router::inhibit(const SS7Label& link, int setFlags, int clrFlags)
continue;
RefPointer<SS7Layer3> net = static_cast<SS7Layer3*>(*p);
mylock.drop();
if (notLast && setFlags) {
const SS7MTP3* mtp3 = YOBJECT(SS7MTP3,net);
if (mtp3 && (mtp3->linksActive() == 1) && !mtp3->inhibited(link.sls()))
return false;
}
return net->inhibit(link.sls(),setFlags,clrFlags);
}
return false;

View File

@ -5923,9 +5923,10 @@ public:
* @param link Signalling Link to modify identified by a routing label
* @param setFlags Flag bits to set ORed together
* @param clrFlags Flag bits to clear ORed together (optional)
* @param notLast Do not apply inhibition to the last usable link
* @return True if inhibition flags were set
*/
bool inhibit(const SS7Label& link, int setFlags, int clrFlags = 0);
bool inhibit(const SS7Label& link, int setFlags, int clrFlags = 0, bool notLast = false);
/**
* Check if the transfer function is enabled