Implemented ISUP circuit block/unblock for local side.

git-svn-id: http://yate.null.ro/svn/yate/trunk@1796 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2008-03-18 11:37:15 +00:00
parent 3cacba3229
commit b2c0357ed5
2 changed files with 62 additions and 26 deletions

View File

@ -1968,7 +1968,10 @@ SS7ISUP::SS7ISUP(const NamedList& params)
m_sls(255), m_sls(255),
m_inn(false), m_inn(false),
m_rscTimer(0), m_rscTimer(0),
m_rscCic(0) m_rscCic(0),
m_lockTimer(0),
m_lockCic(false),
m_lockCicCode(0)
{ {
setName(params.getValue("debugname","isup")); setName(params.getValue("debugname","isup"));
@ -2011,6 +2014,7 @@ SS7ISUP::SS7ISUP(const NamedList& params)
m_callerCat = "ordinary"; m_callerCat = "ordinary";
m_rscTimer.interval(params,"channelsync",60,1000,true,true); m_rscTimer.interval(params,"channelsync",60,1000,true,true);
m_lockTimer.interval(params,"channellock",3,10,false,true);
if (debugAt(DebugInfo)) { if (debugAt(DebugInfo)) {
String s; String s;
@ -2200,30 +2204,58 @@ void SS7ISUP::destruct()
void SS7ISUP::timerTick(const Time& when) void SS7ISUP::timerTick(const Time& when)
{ {
Lock lock(this); Lock lock(this);
// Circuit reset if (!circuits())
while (circuits()) { return;
// Disabled ?
if (!m_rscTimer.interval()) // Blocking/unblocking circuits
break; if (m_lockCicCode <= circuits()->last() && m_lockTimer.interval()) {
if (m_rscTimer.started()) { if (m_lockTimer.started()) {
if (!m_rscTimer.timeout(when.msec())) if (!m_lockTimer.timeout(when.msec()))
break; return;
m_rscTimer.stop(); m_lockTimer.stop();
if (m_rscCic) { Debug(this,DebugMild,"Circuit %slocking timed out for cic=%u",
Debug(this,DebugMild,"Circuit reset timed out for cic=%u",m_rscCic->code()); m_lockCic?"":"un",m_lockCicCode);
releaseCircuit(m_rscCic);
break;
}
} }
m_rscTimer.start(when.msec()); // Try to get another cic
// Pick the next circuit to reset. Ignore lock flags for (ObjList* o = circuits()->circuits().skipNull(); o; o = o->skipNext()) {
int flags = SignallingCircuit::LockLocal | SignallingCircuit::LockRemote; SignallingCircuit* cic = static_cast<SignallingCircuit*>(o->get());
if (m_defPoint && m_remotePoint && reserveCircuit(m_rscCic,~flags)) { if (cic->code() <= m_lockCicCode)
SS7MsgISUP* msg = new SS7MsgISUP(SS7MsgISUP::RSC,m_rscCic->code()); continue;
m_lockCicCode = cic->code();
if (!cic->locked(SignallingCircuit::LockLocalChanged))
continue;
m_lockCic = cic->locked(SignallingCircuit::LockLocal);
break;
}
if (m_lockCicCode <= circuits()->last()) {
m_lockTimer.start();
SS7MsgISUP* msg = new SS7MsgISUP(m_lockCic?SS7MsgISUP::BLK:SS7MsgISUP::UBL,m_lockCicCode);
SS7Label label(m_type,*m_remotePoint,*m_defPoint,m_sls); SS7Label label(m_type,*m_remotePoint,*m_defPoint,m_sls);
transmitMessage(msg,label,false); transmitMessage(msg,label,false);
return;
} }
break; }
// Circuit reset disabled ?
if (!m_rscTimer.interval())
return;
if (m_rscTimer.started()) {
if (!m_rscTimer.timeout(when.msec()))
return;
m_rscTimer.stop();
if (m_rscCic) {
Debug(this,DebugMild,"Circuit reset timed out for cic=%u",m_rscCic->code());
releaseCircuit(m_rscCic);
return;
}
}
m_rscTimer.start(when.msec());
// Pick the next circuit to reset. Ignore lock flags
int flags = SignallingCircuit::LockLocal | SignallingCircuit::LockRemote;
if (m_defPoint && m_remotePoint && reserveCircuit(m_rscCic,~flags)) {
SS7MsgISUP* msg = new SS7MsgISUP(SS7MsgISUP::RSC,m_rscCic->code());
SS7Label label(m_type,*m_remotePoint,*m_defPoint,m_sls);
transmitMessage(msg,label,false);
} }
} }
@ -2236,8 +2268,8 @@ void SS7ISUP::notify(SS7Layer3* link, int sls)
link->toString().safe(),link->operational()?"":"not "); link->toString().safe(),link->operational()?"":"not ");
if (!link->operational(sls)) if (!link->operational(sls))
return; return;
Debug(this,DebugStub,"L3 (%p,'%s') is operational: please implement circuit block/unblock", // TODO: reset local state changed flag when link is not operational
link,link->toString().safe()); // set local state changed flag when link is operational to notify remote party
} }
SS7MSU* SS7ISUP::buildMSU(SS7MsgISUP::Type type, unsigned char sio, SS7MSU* SS7ISUP::buildMSU(SS7MsgISUP::Type type, unsigned char sio,
@ -2607,9 +2639,11 @@ SignallingEvent* SS7ISUP::processCircuitEvent(SignallingCircuitEvent& event,
switch (event.type()) { switch (event.type()) {
case SignallingCircuitEvent::Alarm: case SignallingCircuitEvent::Alarm:
case SignallingCircuitEvent::NoAlarm: case SignallingCircuitEvent::NoAlarm:
if (event.circuit()) if (event.circuit()) {
blockCircuit(event.circuit()->code(), blockCircuit(event.circuit()->code(),
event.type()==SignallingCircuitEvent::Alarm,false,true); event.type()==SignallingCircuitEvent::Alarm,false,true);
event.circuit()->setLock(SignallingCircuit::LockLocalChanged);
}
break; break;
default: default:
Debug(this,DebugStub,"Unhandled circuit event (%u,%s) from call %p", Debug(this,DebugStub,"Unhandled circuit event (%u,%s) from call %p",
@ -2894,8 +2928,6 @@ bool SS7ISUP::blockCircuit(unsigned int cic, bool block, bool remote, bool hwFai
call->replaceCircuit(newCircuit); call->replaceCircuit(newCircuit);
} }
lockFlag |= hwFlag; lockFlag |= hwFlag;
if (!remote)
lockFlag |= SignallingCircuit::LockLocalChanged;
if (block) if (block)
circuit->setLock(lockFlag); circuit->setLock(lockFlag);
else else

View File

@ -1411,6 +1411,7 @@ class YSIG_API SignallingCircuitGroup : public SignallingComponent, public Mutex
{ {
friend class SignallingCircuit; friend class SignallingCircuit;
friend class SignallingCallControl; friend class SignallingCallControl;
friend class SS7ISUP;
public: public:
/** /**
* Circuit allocation strategy * Circuit allocation strategy
@ -5166,6 +5167,9 @@ private:
String m_format; // Default format String m_format; // Default format
SignallingTimer m_rscTimer; // RSC message or idle timeout SignallingTimer m_rscTimer; // RSC message or idle timeout
SignallingCircuit* m_rscCic; // Circuit currently beeing reset SignallingCircuit* m_rscCic; // Circuit currently beeing reset
SignallingTimer m_lockTimer; // Block/unblock timer
bool m_lockCic; // Currently blocking or unblocking circuit
unsigned int m_lockCicCode; // Last blocked/unblocked circuit
}; };
/** /**