Notify SCCP about subsystem management status changes for TCAP.
git-svn-id: http://yate.null.ro/svn/yate/trunk@5290 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
cb0d669c39
commit
d8fe81ac8f
|
@ -53,6 +53,10 @@ void TCAPUser::destroyed()
|
|||
Debug(this,DebugAll,"TCAPUser::destroyed() [%p]",this);
|
||||
Lock lock(m_tcapMtx);
|
||||
if (m_tcap) {
|
||||
// notify SCCP OutOfService
|
||||
NamedList p("");
|
||||
m_tcap->updateUserStatus(this,SCCPManagement::UserOutOfService,p);
|
||||
|
||||
m_tcap->detach(this);
|
||||
Debug(this,DebugAll,"TCAPUser::~TCAPUser() [%p] - Detached from TCAP (%p,%s)",this,m_tcap,m_tcap->toString().safe());
|
||||
m_tcap->deref();
|
||||
|
@ -269,6 +273,7 @@ SS7TCAP::SS7TCAP(const NamedList& params)
|
|||
{
|
||||
Debug(this,DebugAll,"SS7TCAP::SS7TCAP() [%p] created",this);
|
||||
m_recvMsgs = m_sentMsgs = m_discardMsgs = m_normalMsgs = m_abnormalMsgs = 0;
|
||||
m_ssnStatus = SCCPManagement::UserOutOfService;
|
||||
}
|
||||
|
||||
SS7TCAP::~SS7TCAP()
|
||||
|
@ -322,7 +327,13 @@ bool SS7TCAP::initialize(const NamedList* config)
|
|||
s_printMsgs = config->getBoolValue(YSTRING("print-messages"),false);
|
||||
s_extendedDbg = config->getBoolValue(YSTRING("extended-debug"),false);
|
||||
}
|
||||
return SCCPUser::initialize(config);
|
||||
bool ok = SCCPUser::initialize(config);
|
||||
if (ok) {
|
||||
NamedList p("");
|
||||
sendSCCPNotify(p);
|
||||
Debug(this,DebugInfo,"SSN=%d has status='%s'[%p]",m_SSN,lookup(m_ssnStatus,SCCPManagement::broadcastType(),""),this);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool SS7TCAP::sendData(DataBlock& data, NamedList& params)
|
||||
|
@ -408,6 +419,56 @@ bool SS7TCAP::managementNotify(SCCP::Type type, NamedList& params)
|
|||
return ok;
|
||||
}
|
||||
|
||||
void SS7TCAP::updateUserStatus(TCAPUser* user, SCCPManagement::LocalBroadcast status, NamedList& params)
|
||||
{
|
||||
if (!user)
|
||||
return;
|
||||
DDebug(this,DebugAll,"SS7TCAP::updateUserStatus(user=%s[%p],status=%d) [%p]",user->toString().c_str(),user,status,this);
|
||||
bool notify = false;
|
||||
Lock l(m_usersMtx);
|
||||
SCCPManagement::LocalBroadcast tmp = m_ssnStatus;
|
||||
switch (m_ssnStatus) {
|
||||
case SCCPManagement::UserOutOfService:
|
||||
if (status == SCCPManagement::UserInService) {
|
||||
m_ssnStatus = SCCPManagement::UserInService;
|
||||
notify = true;
|
||||
}
|
||||
break;
|
||||
case SCCPManagement::UserInService:
|
||||
if (status == SCCPManagement::UserOutOfService) {
|
||||
ListIterator it(m_users);
|
||||
for (;;) {
|
||||
TCAPUser* usr = static_cast<TCAPUser*>(it.get());
|
||||
// End of iteration?
|
||||
if (!usr) {
|
||||
m_ssnStatus = SCCPManagement::UserOutOfService;
|
||||
notify = true;
|
||||
break;
|
||||
}
|
||||
if (usr->managementState() == (int) SCCPManagement::UserInService)
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (notify) {
|
||||
sendSCCPNotify(params); // it always returns false, so no point in checking result
|
||||
Debug(this,DebugInfo,"SSN=%d changed status from '%s' to '%s' [%p]",m_SSN,
|
||||
lookup(tmp,SCCPManagement::broadcastType(),""),lookup(m_ssnStatus,SCCPManagement::broadcastType(),""),this);
|
||||
}
|
||||
}
|
||||
|
||||
bool SS7TCAP::sendSCCPNotify(NamedList& params)
|
||||
{
|
||||
params.setParam(YSTRING("subsystem-status"),lookup(m_ssnStatus,SCCPManagement::broadcastType(),""));
|
||||
params.setParam(YSTRING("ssn"),String(m_SSN));
|
||||
if (!params.getParam(YSTRING("smi")))
|
||||
params.setParam("smi","0");
|
||||
return sccpNotify(SCCP::StatusRequest,params);
|
||||
}
|
||||
|
||||
void SS7TCAP::attach(TCAPUser* user)
|
||||
{
|
||||
if (!user)
|
||||
|
|
|
@ -10862,6 +10862,14 @@ public:
|
|||
*/
|
||||
virtual HandledMSU handleError(SS7TCAPError& error, NamedList& params, DataBlock& data, SS7TCAPTransaction* tr = 0);
|
||||
|
||||
/**
|
||||
* Update the SCCP Management state for this SSN when requested by a user
|
||||
* @param user The TCAP user which changed its state
|
||||
* @param status The state of the TCAP user
|
||||
* @param params Additional parameters to be transmitted to the SCPP
|
||||
*/
|
||||
virtual void updateUserStatus(TCAPUser* user, SCCPManagement::LocalBroadcast status, NamedList& params);
|
||||
|
||||
/**
|
||||
* Increment one of the status counters
|
||||
* @param counterType The type of the counter to increment
|
||||
|
@ -10948,6 +10956,7 @@ public:
|
|||
protected:
|
||||
virtual SS7TCAPError decodeTransactionPart(NamedList& params, DataBlock& data) = 0;
|
||||
virtual void encodeTransactionPart(NamedList& params, DataBlock& data) = 0;
|
||||
bool sendSCCPNotify(NamedList& params);
|
||||
// list of TCAP users attached to this TCAP instance
|
||||
ObjList m_users;
|
||||
Mutex m_usersMtx;
|
||||
|
@ -10978,6 +10987,9 @@ protected:
|
|||
unsigned int m_discardMsgs;
|
||||
unsigned int m_normalMsgs;
|
||||
unsigned int m_abnormalMsgs;
|
||||
|
||||
// Subsystem Status
|
||||
SCCPManagement::LocalBroadcast m_ssnStatus;
|
||||
};
|
||||
|
||||
class YSIG_API SS7TCAPError
|
||||
|
|
|
@ -233,6 +233,7 @@ public:
|
|||
virtual bool managementNotify(SCCP::Type type, NamedList& params);
|
||||
bool findTCAP(const char* name);
|
||||
int managementState();
|
||||
void notifyManagementState(bool forced = false);
|
||||
bool initialize(NamedList& sect);
|
||||
bool createApplication(Socket* skt, String& addr);
|
||||
void setListener(XMLConnListener* list);
|
||||
|
@ -261,6 +262,7 @@ protected:
|
|||
UserType m_type;
|
||||
bool m_printMsg;
|
||||
bool m_addEnc;
|
||||
SCCPManagement::LocalBroadcast m_mngtStatus;
|
||||
};
|
||||
|
||||
class TcapXApplication : public RefObject, public Mutex
|
||||
|
@ -8335,6 +8337,7 @@ void TcapXApplication::reportState(State state, const char* error)
|
|||
break;
|
||||
case Active:
|
||||
sendStateResponse();
|
||||
m_user->notifyManagementState();
|
||||
break;
|
||||
case ShutDown:
|
||||
Debug(&__plugin,DebugInfo,"Requested shutdown, %d transactions pending [%p]",trCount(),this);
|
||||
|
@ -8414,7 +8417,8 @@ TcapXUser::TcapXUser(const char* name)
|
|||
Mutex(true,name),
|
||||
m_appsMtx(true,"TCAPXApps"),
|
||||
m_listener(0), m_type(MAP),
|
||||
m_printMsg(false), m_addEnc(false)
|
||||
m_printMsg(false), m_addEnc(false),
|
||||
m_mngtStatus(SCCPManagement::UserOutOfService)
|
||||
{
|
||||
Debug(&__plugin,DebugAll,"TcapXUser '%s' created [%p]",toString().c_str(),this);
|
||||
}
|
||||
|
@ -8469,6 +8473,7 @@ bool TcapXUser::initialize(NamedList& sect)
|
|||
m_addEnc = sect.getBoolValue("add-encoding",false);
|
||||
if (!tcap() && !findTCAP(sect.getValue("tcap",0)))
|
||||
return false;
|
||||
notifyManagementState(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -8477,6 +8482,8 @@ void TcapXUser::removeApp(TcapXApplication* app)
|
|||
Debug(this,DebugAll,"Removing application=%s[%p] [%p]",(app ? app->toString().c_str() : ""),app,this);
|
||||
Lock l(m_appsMtx);
|
||||
m_apps.remove(app);
|
||||
l.drop();
|
||||
notifyManagementState();
|
||||
}
|
||||
|
||||
bool TcapXUser::tcapIndication(NamedList& params)
|
||||
|
@ -8694,6 +8701,23 @@ int TcapXUser::managementState()
|
|||
return SCCPManagement::UserOutOfService;
|
||||
}
|
||||
|
||||
void TcapXUser::notifyManagementState(bool forced)
|
||||
{
|
||||
DDebug(this,DebugAll,"TcapXUser::notifyManagementState(forced=%s) [%p]",String::boolText(forced),this);
|
||||
SCCPManagement::LocalBroadcast state = (SCCPManagement::LocalBroadcast)managementState();
|
||||
Lock l(this);
|
||||
if (forced || state != m_mngtStatus) {
|
||||
Debug(this,DebugInfo,"Changing management state from '%s' to '%s' [%p]",
|
||||
lookup(m_mngtStatus,SCCPManagement::broadcastType(),""),lookup(state,SCCPManagement::broadcastType(),""),this);
|
||||
m_mngtStatus = state;
|
||||
l.drop();
|
||||
if (tcap()) {
|
||||
NamedList p("");
|
||||
tcap()->updateUserStatus(this,state,p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TcapXUser::setListener(XMLConnListener* list)
|
||||
{
|
||||
Lock l(this);
|
||||
|
|
Loading…
Reference in New Issue