From 0cdcf17b92c602561ca48975da4bbb85680b4fca Mon Sep 17 00:00:00 2001 From: paulc Date: Fri, 27 Aug 2010 13:40:28 +0000 Subject: [PATCH] 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 --- libs/ysig/layer3.cpp | 16 +++++++++++----- libs/ysig/management.cpp | 38 +++++++++++++++++++++++++++++++++++++- libs/ysig/router.cpp | 7 ++++++- libs/ysig/yatesig.h | 3 ++- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/libs/ysig/layer3.cpp b/libs/ysig/layer3.cpp index a8577d16..25adbd39 100644 --- a/libs/ysig/layer3.cpp +++ b/libs/ysig/layer3.cpp @@ -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(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); } } diff --git a/libs/ysig/management.cpp b/libs/ysig/management.cpp index 2735210a..31c10d34 100644 --- a/libs/ysig/management.cpp +++ b/libs/ysig/management.cpp @@ -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); diff --git a/libs/ysig/router.cpp b/libs/ysig/router.cpp index 1fd91d86..0561d5e3 100644 --- a/libs/ysig/router.cpp +++ b/libs/ysig/router.cpp @@ -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 net = static_cast(*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; diff --git a/libs/ysig/yatesig.h b/libs/ysig/yatesig.h index 5c9d6a43..4ca3c75b 100644 --- a/libs/ysig/yatesig.h +++ b/libs/ysig/yatesig.h @@ -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