Fixed various SS7 rouning and STP problems.
Fixed the behavior of routes and the advertising to other nodes. Added a lot of debug messages. git-svn-id: http://voip.null.ro/svn/yate@3634 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
e1006baeb1
commit
5acaceaae6
|
@ -394,10 +394,19 @@ bool SS7Router::restart()
|
||||||
Lock mylock(this);
|
Lock mylock(this);
|
||||||
m_phase2 = false;
|
m_phase2 = false;
|
||||||
m_started = false;
|
m_started = false;
|
||||||
m_checkRoutes = true;
|
|
||||||
m_isolate.stop();
|
m_isolate.stop();
|
||||||
m_restart.start();
|
|
||||||
m_routeTest.stop();
|
m_routeTest.stop();
|
||||||
|
m_restart.stop();
|
||||||
|
for (ObjList* o = m_layer3.skipNull(); o; o = o->skipNext()) {
|
||||||
|
L3Pointer* p = static_cast<L3Pointer*>(o->get());
|
||||||
|
if (!(*p)->operational()) {
|
||||||
|
clearView(*p);
|
||||||
|
clearRoutes(*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkRoutes();
|
||||||
|
m_checkRoutes = true;
|
||||||
|
m_restart.start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,8 +556,11 @@ void SS7Router::buildView(SS7PointCode::Type type, ObjList& view, SS7Layer3* net
|
||||||
if (r->packed() == route->packed())
|
if (r->packed() == route->packed())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!v)
|
if (!v) {
|
||||||
|
DDebug(this,DebugAll,"Creating route to %u from %s in view of %s",
|
||||||
|
route->packed(),(*p)->toString().c_str(),network->toString().c_str());
|
||||||
view.append(new SS7Route(route->packed()));
|
view.append(new SS7Route(route->packed()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -730,8 +742,8 @@ HandledMSU SS7Router::receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7L
|
||||||
return HandledMSU::Failure;
|
return HandledMSU::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the route changed notification for all known routes that match
|
// Call the route changed notification for all known routes
|
||||||
void SS7Router::notifyRoutes(SS7Route::State states, unsigned int remotePC)
|
void SS7Router::notifyRoutes(SS7Route::State states, unsigned int onlyPC)
|
||||||
{
|
{
|
||||||
if (SS7Route::Unknown == states)
|
if (SS7Route::Unknown == states)
|
||||||
return;
|
return;
|
||||||
|
@ -744,7 +756,7 @@ void SS7Router::notifyRoutes(SS7Route::State states, unsigned int remotePC)
|
||||||
break;
|
break;
|
||||||
if ((route->state() & states) == 0)
|
if ((route->state() & states) == 0)
|
||||||
continue;
|
continue;
|
||||||
routeChanged(route,static_cast<SS7PointCode::Type>(i+1),0,0,remotePC,true);
|
routeChanged(route,static_cast<SS7PointCode::Type>(i+1),0,0,onlyPC,true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -823,8 +835,8 @@ void SS7Router::routeChanged(const SS7Route* route, SS7PointCode::Type type,
|
||||||
dest << SS7PointCode(type,route->packed());
|
dest << SS7PointCode(type,route->packed());
|
||||||
if (dest.null())
|
if (dest.null())
|
||||||
return;
|
return;
|
||||||
Debug(this,DebugAll,"Destination %s:%s state: %s [%p]",
|
DDebug(this,DebugAll,"Destination %s:%u state: %s set by %u only to %u [%p]",
|
||||||
pct,dest.c_str(),route->stateName(),this);
|
pct,route->packed(),route->stateName(),remotePC,onlyPC,this);
|
||||||
// only forward TRx if we are a STP and not in Restart Phase 1
|
// only forward TRx if we are a STP and not in Restart Phase 1
|
||||||
if (!(m_transfer && (m_started || m_phase2)))
|
if (!(m_transfer && (m_started || m_phase2)))
|
||||||
return;
|
return;
|
||||||
|
@ -836,15 +848,20 @@ void SS7Router::routeChanged(const SS7Route* route, SS7PointCode::Type type,
|
||||||
L3Pointer* l3p = static_cast<L3Pointer*>(o->get());
|
L3Pointer* l3p = static_cast<L3Pointer*>(o->get());
|
||||||
if (!l3p || ((*l3p) == network))
|
if (!l3p || ((*l3p) == network))
|
||||||
continue;
|
continue;
|
||||||
|
if (!(*l3p)->operational())
|
||||||
|
continue;
|
||||||
if (!(*l3p)->getRoutePriority(type,remotePC))
|
if (!(*l3p)->getRoutePriority(type,remotePC))
|
||||||
continue;
|
continue;
|
||||||
for (ObjList* v = l3p->view(type).skipNull(); v; v = v->skipNext()) {
|
for (ObjList* v = l3p->view(type).skipNull(); v; v = v->skipNext()) {
|
||||||
SS7Route* r = static_cast<const SS7Route*>(v->get());
|
SS7Route* r = static_cast<const SS7Route*>(v->get());
|
||||||
if (r->packed() != route->packed())
|
if (r->packed() != route->packed())
|
||||||
continue;
|
continue;
|
||||||
SS7Route::State state = getRouteView(type,r->packed(),remotePC,*l3p);
|
SS7Route::State state = getRouteView(type,r->packed(),0,*l3p);
|
||||||
if ((r->state() == state) && !forced)
|
if ((r->state() == state) && !forced)
|
||||||
break;
|
break;
|
||||||
|
DDebug(this,DebugAll,"Route %u of view '%s' changed: %s -> %s",
|
||||||
|
r->packed(),(*l3p)->toString().c_str(),
|
||||||
|
SS7Route::stateName(r->state()),SS7Route::stateName(state));
|
||||||
r->m_state = state;
|
r->m_state = state;
|
||||||
unsigned int local = (*l3p)->getLocal(type);
|
unsigned int local = (*l3p)->getLocal(type);
|
||||||
if (!local)
|
if (!local)
|
||||||
|
@ -857,7 +874,7 @@ void SS7Router::routeChanged(const SS7Route* route, SS7PointCode::Type type,
|
||||||
v = v->skipNull();
|
v = v->skipNull();
|
||||||
for (; v; v = v->skipNext()) {
|
for (; v; v = v->skipNext()) {
|
||||||
r = static_cast<const SS7Route*>(v->get());
|
r = static_cast<const SS7Route*>(v->get());
|
||||||
if (r->priority())
|
if (r->priority() || (r->state() == SS7Route::Prohibited))
|
||||||
continue;
|
continue;
|
||||||
if (onlyPC && (r->packed() != onlyPC))
|
if (onlyPC && (r->packed() != onlyPC))
|
||||||
continue;
|
continue;
|
||||||
|
@ -867,7 +884,7 @@ void SS7Router::routeChanged(const SS7Route* route, SS7PointCode::Type type,
|
||||||
String addr;
|
String addr;
|
||||||
addr << pct << "," << SS7PointCode(type,local) << ","
|
addr << pct << "," << SS7PointCode(type,local) << ","
|
||||||
<< SS7PointCode(type,r->packed());
|
<< SS7PointCode(type,r->packed());
|
||||||
Debug(this,DebugAll,"Advertising Route %s %s %s [%p]",
|
Debug(this,DebugInfo,"Advertising Route %s %s %s [%p]",
|
||||||
dest.c_str(),cmd,addr.c_str(),this);
|
dest.c_str(),cmd,addr.c_str(),this);
|
||||||
ctl->addParam("address",addr);
|
ctl->addParam("address",addr);
|
||||||
ctl->addParam("destination",dest);
|
ctl->addParam("destination",dest);
|
||||||
|
@ -912,8 +929,9 @@ SS7Route::State SS7Router::getRouteView(SS7PointCode::Type type, unsigned int pa
|
||||||
if ((state & SS7Route::KnownState) > (best & SS7Route::KnownState))
|
if ((state & SS7Route::KnownState) > (best & SS7Route::KnownState))
|
||||||
best = state;
|
best = state;
|
||||||
}
|
}
|
||||||
DDebug(this,DebugInfo,"Route view of %u from %u: %s",
|
DDebug(this,DebugInfo,"Route view of %u from %u%s%s: %s",
|
||||||
packedPC,remotePC,SS7Route::stateName(best));
|
packedPC,remotePC,(network ? " on " : ""),
|
||||||
|
(network ? network->toString().c_str() : ""),SS7Route::stateName(best));
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,16 +939,19 @@ void SS7Router::clearView(const SS7Layer3* network)
|
||||||
{
|
{
|
||||||
for (ObjList* o = m_layer3.skipNull(); o; o = o->skipNext()) {
|
for (ObjList* o = m_layer3.skipNull(); o; o = o->skipNext()) {
|
||||||
L3Pointer* p = static_cast<L3Pointer*>(o->get());
|
L3Pointer* p = static_cast<L3Pointer*>(o->get());
|
||||||
if (!*p || ((*p) == network))
|
if (!*p || ((*p) != network))
|
||||||
continue;
|
continue;
|
||||||
for (unsigned int i = 0; i < YSS7_PCTYPE_COUNT; i++) {
|
for (unsigned int i = 0; i < YSS7_PCTYPE_COUNT; i++) {
|
||||||
SS7PointCode::Type type = static_cast<SS7PointCode::Type>(i+1);
|
SS7PointCode::Type type = static_cast<SS7PointCode::Type>(i+1);
|
||||||
for (ObjList* v = p->view(type).skipNull(); v; v = v->skipNext()) {
|
for (ObjList* v = p->view(type).skipNull(); v; v = v->skipNext()) {
|
||||||
SS7Route* r = static_cast<const SS7Route*>(v->get());
|
SS7Route* r = static_cast<const SS7Route*>(v->get());
|
||||||
|
DDebug(this,DebugAll,"Route %u of view '%s' cleared: %s -> Prohibited",
|
||||||
|
r->packed(),network->toString().c_str(),
|
||||||
|
SS7Route::stateName(r->state()));
|
||||||
r->m_state = SS7Route::Unknown;
|
r->m_state = SS7Route::Unknown;
|
||||||
routeChanged(r,type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,6 +966,9 @@ bool SS7Router::setRouteState(SS7PointCode::Type type, unsigned int packedPC, SS
|
||||||
if (!route)
|
if (!route)
|
||||||
return false;
|
return false;
|
||||||
if (state != route->m_state) {
|
if (state != route->m_state) {
|
||||||
|
DDebug(this,DebugAll,"Local route %u/%u changed by %u: %s -> %s",
|
||||||
|
packedPC,route->priority(),remotePC,
|
||||||
|
SS7Route::stateName(route->state()),SS7Route::stateName(state));
|
||||||
route->m_state = state;
|
route->m_state = state;
|
||||||
if (state != SS7Route::Unknown)
|
if (state != SS7Route::Unknown)
|
||||||
routeChanged(route,type,remotePC,network);
|
routeChanged(route,type,remotePC,network);
|
||||||
|
@ -982,6 +1006,9 @@ bool SS7Router::setRouteSpecificState(SS7PointCode::Type type, unsigned int pack
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ok = true;
|
ok = true;
|
||||||
|
DDebug(this,DebugAll,"Route %u/%u of network '%s' changed: %s -> %s",
|
||||||
|
r->packed(),r->priority(),l3->toString().c_str(),
|
||||||
|
SS7Route::stateName(r->state()),SS7Route::stateName(state));
|
||||||
r->m_state = state;
|
r->m_state = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -989,6 +1016,8 @@ bool SS7Router::setRouteSpecificState(SS7PointCode::Type type, unsigned int pack
|
||||||
Debug(this,DebugWarn,"Route to %u advertised by %u not found in any network",packedPC,srcPC);
|
Debug(this,DebugWarn,"Route to %u advertised by %u not found in any network",packedPC,srcPC);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
DDebug(this,DebugAll,"Local best route %u/%u changed by %u: %s -> %s",packedPC,
|
||||||
|
route->priority(),srcPC,SS7Route::stateName(route->state()),SS7Route::stateName(best));
|
||||||
route->m_state = best;
|
route->m_state = best;
|
||||||
routeChanged(route,type,srcPC,changer);
|
routeChanged(route,type,srcPC,changer);
|
||||||
return true;
|
return true;
|
||||||
|
@ -1134,9 +1163,12 @@ void SS7Router::checkRoutes(const SS7Layer3* noResume)
|
||||||
for (; l; l = l->skipNext()) {
|
for (; l; l = l->skipNext()) {
|
||||||
SS7Route* r = static_cast<SS7Route*>(l->get());
|
SS7Route* r = static_cast<SS7Route*>(l->get());
|
||||||
SS7Route::State state = getRouteView(type,r->packed());
|
SS7Route::State state = getRouteView(type,r->packed());
|
||||||
if (state & SS7Route::NotProhibited)
|
if ((state & (SS7Route::NotProhibited|SS7Route::Unknown)) && !r->priority())
|
||||||
isolated = false;
|
isolated = false;
|
||||||
if (r->state() != state) {
|
if (r->state() != state) {
|
||||||
|
DDebug(this,DebugAll,"Local route %u/%u changed during check: %s -> %s",
|
||||||
|
r->packed(),r->priority(),
|
||||||
|
SS7Route::stateName(r->state()),SS7Route::stateName(state));
|
||||||
r->m_state = state;
|
r->m_state = state;
|
||||||
routeChanged(r,type,0);
|
routeChanged(r,type,0);
|
||||||
}
|
}
|
||||||
|
@ -1167,17 +1199,21 @@ void SS7Router::clearRoutes(SS7Layer3* network)
|
||||||
{
|
{
|
||||||
if (!network)
|
if (!network)
|
||||||
return;
|
return;
|
||||||
|
// if an adjacent node is operational but not in service we may have a chance
|
||||||
|
SS7Route::State adjacentState = network->operational() ?
|
||||||
|
SS7Route::Unknown : SS7Route::Prohibited;
|
||||||
for (unsigned int i = 0; i < YSS7_PCTYPE_COUNT; i++) {
|
for (unsigned int i = 0; i < YSS7_PCTYPE_COUNT; i++) {
|
||||||
SS7PointCode::Type type = static_cast<SS7PointCode::Type>(i+1);
|
SS7PointCode::Type type = static_cast<SS7PointCode::Type>(i+1);
|
||||||
const ObjList* l = getRoutes(type);
|
const ObjList* l = network->getRoutes(type);
|
||||||
if (l)
|
if (l)
|
||||||
l = l->skipNull();
|
l = l->skipNull();
|
||||||
for (; l; l = l->skipNext()) {
|
for (; l; l = l->skipNext()) {
|
||||||
SS7Route* r = static_cast<SS7Route*>(l->get());
|
SS7Route* r = static_cast<SS7Route*>(l->get());
|
||||||
DDebug(DebugInfo,"Clearing route %u of %s",
|
|
||||||
r->packed(),network->toString().c_str());
|
|
||||||
SS7Route::State state = r->priority() ?
|
SS7Route::State state = r->priority() ?
|
||||||
SS7Route::Unknown : SS7Route::Prohibited;
|
SS7Route::Unknown : adjacentState;
|
||||||
|
DDebug(DebugInfo,"Clearing route %u/%u of %s to %s",
|
||||||
|
r->packed(),r->priority(),network->toString().c_str(),
|
||||||
|
SS7Route::stateName(state));
|
||||||
setRouteSpecificState(type,r->packed(),0,state,network);
|
setRouteSpecificState(type,r->packed(),0,state,network);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1208,7 +1244,7 @@ bool SS7Router::uninhibit(SS7Layer3* network, int sls, bool remote)
|
||||||
"," << SS7PointCode(type,local) <<
|
"," << SS7PointCode(type,local) <<
|
||||||
"," << SS7PointCode(type,r->packed()) <<
|
"," << SS7PointCode(type,r->packed()) <<
|
||||||
"," << sls;
|
"," << sls;
|
||||||
DDebug(this,DebugAll,"Requesting %s %s [%p]",cmd,addr.c_str(),this);
|
DDebug(this,DebugInfo,"Requesting %s %s [%p]",cmd,addr.c_str(),this);
|
||||||
ctl->addParam("address",addr);
|
ctl->addParam("address",addr);
|
||||||
ctl->setParam("automatic",String::boolText(true));
|
ctl->setParam("automatic",String::boolText(true));
|
||||||
m_mngmt->controlExecute(ctl);
|
m_mngmt->controlExecute(ctl);
|
||||||
|
@ -1320,7 +1356,7 @@ void SS7Router::notify(SS7Layer3* network, int sls)
|
||||||
bool useMe = false;
|
bool useMe = false;
|
||||||
Lock lock(this);
|
Lock lock(this);
|
||||||
if (network) {
|
if (network) {
|
||||||
if (network->operational()) {
|
if (network->inService(sls)) {
|
||||||
if (m_isolate.started()) {
|
if (m_isolate.started()) {
|
||||||
Debug(this,DebugNote,"Isolation ended before shutting down [%p]",this);
|
Debug(this,DebugNote,"Isolation ended before shutting down [%p]",this);
|
||||||
m_isolate.stop();
|
m_isolate.stop();
|
||||||
|
@ -1457,7 +1493,7 @@ bool SS7Router::control(NamedList& params)
|
||||||
NamedList* ctl = m_mngmt->controlCreate(oper);
|
NamedList* ctl = m_mngmt->controlCreate(oper);
|
||||||
if (!ctl)
|
if (!ctl)
|
||||||
return false;
|
return false;
|
||||||
DDebug(this,DebugAll,"Advertising %s %s to %s [%p]",
|
Debug(this,DebugInfo,"Requesting %s %s to %s [%p]",
|
||||||
dest->c_str(),oper,addr,this);
|
dest->c_str(),oper,addr,this);
|
||||||
ctl->addParam("address",addr);
|
ctl->addParam("address",addr);
|
||||||
ctl->addParam("destination",*dest);
|
ctl->addParam("destination",*dest);
|
||||||
|
|
|
@ -6208,9 +6208,9 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Trigger the route changed notification for each route that is not Unknown
|
* Trigger the route changed notification for each route that is not Unknown
|
||||||
* @param states Mask of required states of the route
|
* @param states Mask of required states of the route
|
||||||
* @param remotePC The point code that caused the route change
|
* @param onlyPC The only point code that should receive notifications
|
||||||
*/
|
*/
|
||||||
void notifyRoutes(SS7Route::State states = SS7Route::AnyState, unsigned int remotePC = 0);
|
void notifyRoutes(SS7Route::State states = SS7Route::AnyState, unsigned int onlyPC = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification callback when a route state changed to other than Unknown.
|
* Notification callback when a route state changed to other than Unknown.
|
||||||
|
|
Loading…
Reference in New Issue