Added various methods for setting the link inhibition flags, use them from management to control changeover/changeback.

git-svn-id: http://voip.null.ro/svn/yate@3544 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2010-08-27 09:58:46 +00:00
parent 2a443d7a3b
commit 0194d1dff3
5 changed files with 148 additions and 25 deletions

View File

@ -231,6 +231,17 @@ bool SS7Layer2::getEmergency(NamedList* params, bool emg) const
return emg;
}
bool SS7Layer2::inhibit(int setFlags, int clrFlags)
{
int old = m_inhibited;
m_inhibited = (m_inhibited | setFlags) & ~clrFlags;
DDebug(this,DebugInfo,"Link inhibition changed 0x%02X -> 0x%02X [%p]",
old,m_inhibited,this);
if (((old != 0) ^ (m_inhibited != 0)) && operational())
notify();
return true;
}
SS7MTP2::SS7MTP2(const NamedList& params, unsigned int status)
: SignallingComponent(params.safe("SS7MTP2"),&params),

View File

@ -609,6 +609,24 @@ int SS7MTP3::inhibited(int sls) const
return SS7Layer2::Inactive;
}
bool SS7MTP3::inhibit(int sls, int setFlags, int clrFlags)
{
if (sls < 0)
return false;
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) {
DDebug(this,DebugAll,"Setting inhibition +0x%02X -0x%02X on %d '%s' [%p]",
setFlags,clrFlags,sls,(*p)->toString().c_str(),this);
return (*p)->inhibit(setFlags,clrFlags);
}
}
return false;
}
int SS7MTP3::getSequence(int sls) const
{
if (sls < 0)

View File

@ -438,15 +438,7 @@ HandledMSU SS7Management::receivedMSU(const SS7MSU& msu, const SS7Label& label,
String link;
link << msg->params().getValue("pointcodetype") << "," << *pend;
Debug(this,DebugNote,"Changeback acknowledged on %s",link.c_str());
if (router) {
NamedList* ctrl = router->controlCreate("inservice");
if (ctrl) {
ctrl->copyParams(msg->params());
ctrl->setParam("address",link);
ctrl->setParam("automatic",String::boolText(true));
router->controlExecute(ctrl);
}
}
inhibit(*pend,0,SS7Layer2::Inactive);
}
TelEngine::destruct(pend);
}
@ -479,6 +471,7 @@ HandledMSU SS7Management::receivedMSU(const SS7MSU& msu, const SS7Label& label,
String link;
link << msg->params().getValue("pointcodetype") << "," << *pend;
Debug(this,DebugNote,"Changeover acknowledged on %s",link.c_str());
inhibit(*pend,SS7Layer2::Inactive);
}
TelEngine::destruct(pend);
}
@ -672,6 +665,10 @@ void SS7Management::notify(SS7Layer3* network, int sls)
Debug(this,DebugStub,"Please implement SS7Management::notify(%p,%d) [%p]",
network,sls,this);
if (network && (sls >= 0)) {
bool linkAvail[256];
int txSls;
for (txSls = 0; txSls < 256; txSls++)
linkAvail[txSls] = (txSls != sls) && !network->inhibited(txSls) && network->operational(txSls);
bool linkUp = network->operational(sls);
for (unsigned int i = 0; i < YSS7_PCTYPE_COUNT; i++) {
SS7PointCode::Type type = static_cast<SS7PointCode::Type>(i+1);
@ -684,31 +681,40 @@ void SS7Management::notify(SS7Layer3* network, int sls)
addr << SS7PointCode::lookup(type) << "," << SS7PointCode(type,local);
Debug(this,DebugNote,"Link %s:%d is %s [%p]",addr.c_str(),sls,
(linkUp ? "up" : "down"),this);
const char* oper = linkUp ? "changeback" : "changeover";
ObjList* routes = getNetRoutes(network,type);
if (routes)
routes = routes->skipNull();
for (; routes; routes = routes->skipNext()) {
const SS7Route* r = static_cast<const SS7Route*>(routes->get());
if (r && !r->priority()) {
// found adjacent node, emit change order to it
const char* oper = linkUp ? "changeback" : "changeover";
NamedList* ctl = controlCreate(oper);
if (!ctl)
continue;
// found adjacent node, emit change orders to it
String tmp = addr;
tmp << "," << SS7PointCode(type,r->packed()) << "," << sls;
Debug(this,DebugAll,"Sending Link %d %s %s [%p]",sls,oper,tmp.c_str(),this);
ctl->setParam("address",tmp);
ctl->setParam("slc",String(sls));
if (!linkUp) {
int seq = network->getSequence(sls);
if (seq >= 0)
ctl->setParam("sequence",String(seq));
else
ctl->setParam("emergency",String::boolText(true));
String slc(sls);
for (txSls = 0; txSls < 256; txSls++) {
if (!linkAvail[txSls])
continue;
NamedList* ctl = controlCreate(oper);
if (!ctl)
continue;
Debug(this,DebugAll,"Sending Link %d %s %s on %d [%p]",
sls,oper,tmp.c_str(),txSls,this);
ctl->setParam("address",tmp);
ctl->setParam("slc",slc);
ctl->setParam("linksel",String(txSls));
if (linkUp)
ctl->setParam("code",String(txSls));
else {
int seq = network->getSequence(sls);
if (seq >= 0)
ctl->setParam("sequence",String(seq));
else
ctl->setParam("emergency",String::boolText(true));
}
ctl->setParam("automatic",String::boolText(true));
controlExecute(ctl);
}
ctl->setParam("automatic",String::boolText(true));
controlExecute(ctl);
}
}
}
@ -731,6 +737,25 @@ bool SS7Management::postpone(SS7MSU* msu, const SS7Label& label, int txSls,
bool SS7Management::timeout(const SS7MSU& msu, const SS7Label& label, int txSls, bool final)
{
Debug(this,DebugStub,"Timeout %u%s [%p]",txSls,(final ? " final" : ""),this);
if (!final)
return true;
const unsigned char* buf = msu.getData(label.length()+1,1);
if (!buf)
return false;
String link;
link << SS7PointCode::lookup(label.type()) << "," << label;
switch (buf[0]) {
case SS7MsgSNM::COO:
case SS7MsgSNM::XCO:
case SS7MsgSNM::ECO:
Debug(this,DebugNote,"Changeover timed out on %s",link.c_str());
inhibit(label,SS7Layer2::Inactive);
break;
case SS7MsgSNM::CBD:
Debug(this,DebugNote,"Changeback timed out on %s",link.c_str());
inhibit(label,0,SS7Layer2::Inactive);
break;
}
return true;
}
@ -765,6 +790,13 @@ void SS7Management::timerTick(const Time& when)
}
}
bool SS7Management::inhibit(const SS7Label& link, int setFlags, int clrFlags)
{
SS7Router* router = YOBJECT(SS7Router,SS7Layer4::network());
return router && router->inhibit(link,setFlags,clrFlags);
}
HandledMSU SS7Maintenance::receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls)
{
if (msu.getSIF() != sif() && msu.getSIF() != SS7MSU::MTNS)

View File

@ -795,6 +795,23 @@ void SS7Router::checkRoutes(const SS7Layer3* noResume)
}
}
bool SS7Router::inhibit(const SS7Label& link, int setFlags, int clrFlags)
{
int remote = link.dpc().pack(link.type());
if (!remote)
return false;
Lock mylock(this);
for (ObjList* o = m_layer3.skipNull(); o; o = o->skipNext()) {
L3Pointer* p = static_cast<L3Pointer*>(o->get());
if (!*p || (*p)->getRoutePriority(link.type(),remote))
continue;
RefPointer<SS7Layer3> net = static_cast<SS7Layer3*>(*p);
mylock.drop();
return net->inhibit(link.sls(),setFlags,clrFlags);
}
return false;
}
void SS7Router::notify(SS7Layer3* network, int sls)
{
DDebug(this,DebugInfo,"Notified %s on %p sls %d [%p]",

View File

@ -5115,6 +5115,14 @@ protected:
tmp->notify(this);
}
/**
* Set and clear inhibition flags, method used by MTP3
* @param setFlags Flag bits to set ORed together
* @param clrFlags Flag bits to clear ORed together (optional)
* @return True if inhibition flags were set
*/
bool inhibit(int setFlags, int clrFlags = 0);
/**
* Get a best guess of the emergency alignment requirement
* @param params Optional parameters whose "emergency" is used
@ -5383,6 +5391,16 @@ public:
virtual int inhibited(int sls) const
{ return 0; }
/**
* Set and clear inhibition flags on the links
* @param sls Signalling Link to modify
* @param setFlags Flag bits to set ORed together
* @param clrFlags Flag bits to clear ORed together (optional)
* @return True if inhibition flags were set
*/
virtual bool inhibit(int sls, int setFlags, int clrFlags = 0)
{ return false; }
/**
* Get the sequence number of the last MSU received on a link
* @param sls Signalling Link to retrieve MSU number from
@ -5892,6 +5910,15 @@ public:
*/
void detach(SS7Layer4* service);
/**
* Set and clear inhibition flags on a link of an attached network
* @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)
* @return True if inhibition flags were set
*/
bool inhibit(const SS7Label& link, int setFlags, int clrFlags = 0);
/**
* Check if the transfer function is enabled
* @return True if acting as a STP
@ -6590,6 +6617,15 @@ public:
*/
virtual int inhibited(int sls) const;
/**
* Set and clear inhibition flags on the links
* @param sls Signalling Link to modify
* @param setFlags Flag bits to set ORed together
* @param clrFlags Flag bits to clear ORed together (optional)
* @return True if inhibition flags were set
*/
virtual bool inhibit(int sls, int setFlags, int clrFlags = 0);
/**
* Get the sequence number of the last MSU received on a link
* @param sls Signalling Link to retrieve MSU number from
@ -7163,6 +7199,15 @@ protected:
*/
virtual HandledMSU receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
/**
* Set and clear inhibition flags on a link of a router attached network
* @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)
* @return True if inhibition flags were set
*/
bool inhibit(const SS7Label& link, int setFlags, int clrFlags = 0);
/**
* Process a notification generated by the attached network layer
* @param link Network or linkset that generated the notification