diff --git a/conf.d/ciscosm.conf.sample b/conf.d/ciscosm.conf.sample index a6d5d0aa..2ba460c4 100644 --- a/conf.d/ciscosm.conf.sample +++ b/conf.d/ciscosm.conf.sample @@ -60,6 +60,9 @@ ; channel: int: Number of the channel inside the session, must match remote config ;channel=0 +; autostart: bool: Automatically try to align the remote MTP2 at startup +;autostart=yes + ; configuration: int: Configuration request retransmission interval in ms, 250+ ;configuration=5000 diff --git a/conf.d/ysigchan.conf.sample b/conf.d/ysigchan.conf.sample index 4ae57a80..d0e82495 100644 --- a/conf.d/ysigchan.conf.sample +++ b/conf.d/ysigchan.conf.sample @@ -353,6 +353,9 @@ ; Example: route=ITU,2-2-2,0 ;route= +; autostart: bool: Automatically enable the linkset at startup +;autostart=yes + ; layer3dump: string: Filename to dump MTP3 packets to ;layer3dump= @@ -365,6 +368,9 @@ ; ss7-mtp2: SS7 Message Transfer Part - Layer 2 ;type=ss7-mtp2 +; autostart: bool: Automatically try to align the MTP2 at startup +;autostart=yes + ; emergency: boolean: Emergency align SS7 MTP2 layer at startup ;emergency=yes diff --git a/libs/ysig/layer2.cpp b/libs/ysig/layer2.cpp index c9879a45..7483ce92 100644 --- a/libs/ysig/layer2.cpp +++ b/libs/ysig/layer2.cpp @@ -293,6 +293,7 @@ bool SS7MTP2::initialize(const NamedList* config) if (config) debugLevel(config->getIntValue("debuglevel_mtp2", config->getIntValue("debuglevel",-1))); + bool noStart = true; if (config && !iface()) { NamedString* name = config->getParam("sig"); if (!name) @@ -318,8 +319,9 @@ bool SS7MTP2::initialize(const NamedList* config) if (!(ifc->initialize(ifConfig) && control((Operation)SignallingInterface::Enable,ifConfig))) TelEngine::destruct(SignallingReceiver::attach(0)); } + noStart = !config->getBoolValue("autostart",true); } - return iface() && control(Resume,const_cast(config)); + return iface() && (noStart || control(Resume,const_cast(config))); } bool SS7MTP2::control(Operation oper, NamedList* params) diff --git a/libs/ysig/layer3.cpp b/libs/ysig/layer3.cpp index 17fac5a9..1ad8d723 100644 --- a/libs/ysig/layer3.cpp +++ b/libs/ysig/layer3.cpp @@ -387,6 +387,7 @@ SS7MTP3::SS7MTP3(const NamedList& params) } Debug(this,level,"Point code types are '%s' [%p]",stype.safe(),this); + m_inhibit = !params.getBoolValue("autostart",true); buildRoutes(params); setDumper(params.getValue("layer3dump")); } @@ -573,6 +574,7 @@ bool SS7MTP3::initialize(const NamedList* config) TelEngine::destruct(link); } } + m_inhibit = !config->getBoolValue("autostart",true); } if (engine() && !user()) { NamedList params("ss7router"); @@ -615,9 +617,11 @@ int SS7MTP3::transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls) continue; SS7Layer2* link = *p; if (link->sls() == sls) { - DDebug(this,DebugAll,"Found link %p for SLS=%d [%p]",link,sls,this); + XDebug(this,DebugAll,"Found link %p for SLS=%d [%p]",link,sls,this); if (link->operational()) { if (link->transmitMSU(msu)) { + DDebug(this,DebugAll,"Sent MSU over link %p with SLS=%d%s [%p]", + link,sls,(m_inhibit ? " while inhibited" : ""),this); dump(msu,true,sls); return sls; } @@ -636,8 +640,11 @@ int SS7MTP3::transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls) continue; SS7Layer2* link = *p; if (link->operational() && link->transmitMSU(msu)) { - dump(msu,true,link->sls()); - return link->sls(); + sls = link->sls(); + DDebug(this,DebugAll,"Sent MSU over link %p with SLS=%d%s [%p]", + link,sls,(m_inhibit ? " while inhibited" : ""),this); + dump(msu,true,sls); + return sls; } } @@ -666,7 +673,8 @@ bool SS7MTP3::receivedMSU(const SS7MSU& msu, SS7Layer2* link, int sls) if (debugAt(DebugInfo)) { String tmp; tmp << label << " (" << label.opc().pack(cpType) << ":" << label.dpc().pack(cpType) << ":" << label.sls() << ")"; - Debug(this,DebugAll,"Received MSU. Address: %s",tmp.c_str()); + Debug(this,DebugAll,"Received MSU from link %p with SLS=%d. Address: %s", + link,sls,tmp.c_str()); } #endif // first try to call the user part diff --git a/modules/server/ciscosm.cpp b/modules/server/ciscosm.cpp index 5853473f..9131aeff 100644 --- a/modules/server/ciscosm.cpp +++ b/modules/server/ciscosm.cpp @@ -376,7 +376,6 @@ public: virtual ~SLT(); virtual unsigned int status() const; void setStatus(unsigned int status); - void setLocalStatus(unsigned int status); void setRemoteStatus(unsigned int status); void setReqStatus(unsigned int status); virtual void notify(bool up); @@ -424,7 +423,6 @@ public: static SignallingComponent* create(const String& type,const NamedList& params); protected: unsigned int m_status; // Layer status - unsigned int m_lStatus; // Local layer status unsigned int m_rStatus; // Remote layer status unsigned int m_reqStatus; // We keep the requested status and we change it when // receive the confirmation @@ -1537,9 +1535,10 @@ const TokenDict SLT::s_protocolError[] = { }; SLT::SLT(const String& name, const NamedList& param) - : SignallingComponent(param.safe("CiscoSLT")), SessionUser(1), - m_status(Unconfigured), m_lStatus(NormalAlignment), m_rStatus(OutOfAlignment), - m_reqStatus(NormalAlignment), m_messageId(1), m_channelId(0), m_bearerId(0), + : SignallingComponent(param.safe("CiscoSLT")), + SessionUser(1), + m_status(Unconfigured), m_rStatus(OutOfService), m_reqStatus(OutOfService), + m_messageId(1), m_channelId(0), m_bearerId(0), m_confReqTimer(0), m_printMsg(false) { m_channelId = param.getIntValue("channel",0); @@ -1552,6 +1551,8 @@ SLT::SLT(const String& name, const NamedList& param) } m_confReqTimer.interval(param,"configuration",250,5000,true); m_printMsg = param.getBoolValue("printslt",false); + if (param.getBoolValue("autostart",true)) + m_reqStatus = NormalAlignment; } SLT::~SLT() @@ -1581,22 +1582,16 @@ void SLT::setStatus(unsigned int status) m_status = status; } -void SLT::setLocalStatus(unsigned int status) -{ - if (status == m_lStatus) - return; - DDebug(this,DebugNote,"Local status change: %s -> %s [%p]", - statusName(m_lStatus,true),statusName(status,true),this); - m_lStatus = status; -} - void SLT::setRemoteStatus(unsigned int status) { if (status == m_rStatus) return; DDebug(this,DebugNote,"Remote status change: %s -> %s [%p]", statusName(m_rStatus,true),statusName(status,true),this); + bool old = aligned(); m_rStatus = status; + if (aligned() != old) + SS7Layer2::notify(); } void SLT::setReqStatus(unsigned int status) @@ -1605,7 +1600,10 @@ void SLT::setReqStatus(unsigned int status) return; DDebug(this,DebugNote,"Request status change: %s -> %s [%p]", statusName(m_reqStatus,true),statusName(status,true),this); + bool old = aligned(); m_reqStatus = status; + if (aligned() != old) + SS7Layer2::notify(); } // Process notification received from session manager @@ -1622,7 +1620,6 @@ void SLT::notify(bool up) bool SLT::control(Operation oper, NamedList* params) { - bool normal = true; switch (oper) { case Pause: setReqStatus(OutOfService); @@ -1632,11 +1629,21 @@ bool SLT::control(Operation oper, NamedList* params) if (aligned()) return true; case Align: - normal = !params->getBoolValue("emergency",false); - sendConnect(normal ? Emergency : Normal); - setReqStatus(normal ? EmergencyAlignment : NormalAlignment); - setLocalStatus(NormalAlignment); - setStatus(Waiting); + { + bool emg = params->getBoolValue("emergency"); + setReqStatus(emg ? EmergencyAlignment : NormalAlignment); + switch (m_status) { + case Configured: + sendConnect(emg ? Emergency : Normal); + break; + case Waiting: + break; + default: + sendManagement(Configuration_R); + m_confReqTimer.start(); + setStatus(Waiting); + } + } return true; case Status: return aligned() && m_status == Configured; @@ -1647,7 +1654,7 @@ bool SLT::control(Operation oper, NamedList* params) bool SLT::aligned() const { - return ((m_lStatus == NormalAlignment) || (m_lStatus == EmergencyAlignment)) && + return ((m_reqStatus == NormalAlignment) || (m_reqStatus == EmergencyAlignment)) && ((m_rStatus == NormalAlignment) || (m_rStatus == EmergencyAlignment)); } @@ -1746,8 +1753,8 @@ bool SLT::checkMessage(DataBlock& data) SS7MSU msu(data); return receivedMSU(msu); } else - DDebug(this,DebugWarn,"Received data message but we are not aligned local status = %s,remote status = %s", - statusName(m_lStatus,false),statusName(m_rStatus,false)); + DDebug(this,DebugWarn,"Received data message while not aligned, local status = %s, remote status = %s", + statusName(m_reqStatus,false),statusName(m_rStatus,false)); } else if (msgType & 0x40) { data.cut(-16); // Management message processManagement(msgType,data); @@ -1801,16 +1808,15 @@ void SLT::processSltMessage(u_int16_t msgType, DataBlock& data) setRemoteStatus(mes == Normal ? NormalAlignment : EmergencyAlignment); if (aligned()) m_session->userNotice(true); - SS7Layer2::notify(); } break; case Disconnect_C: + setRemoteStatus(OutOfService); if (m_reqStatus == EmergencyAlignment || m_reqStatus == NormalAlignment) sendConnect(m_reqStatus == NormalAlignment ? Normal : Emergency); - else - setRemoteStatus(m_reqStatus); break; case Disconnect_I: + setRemoteStatus(OutOfService); if (m_reqStatus == EmergencyAlignment || m_reqStatus == NormalAlignment) sendConnect(m_reqStatus == NormalAlignment ? Normal : Emergency); break; @@ -1818,7 +1824,6 @@ void SLT::processSltMessage(u_int16_t msgType, DataBlock& data) setRemoteStatus(m_reqStatus); if (aligned()) m_session->userNotice(false); - SS7Layer2::notify(); break; case Link_State_Controller_I: processCIndication(data); @@ -1961,7 +1966,6 @@ bool SLT::transmitMSU(const SS7MSU& msu) return false; if (!aligned()) { Debug(this,DebugNote,"Requested to send data while not operational"); - SS7Layer2::notify(); return false; } DataBlock data;