Handle 'silent' error/reason in reject, disconnect, drop. Silence channel's transaction: process it but send nothing to remote party.

git-svn-id: http://yate.null.ro/svn/yate/trunk@6387 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2020-02-27 12:11:28 +00:00
parent dd4a0224de
commit 8fe3d0585c
3 changed files with 58 additions and 16 deletions

View File

@ -33,7 +33,7 @@ SIPTransaction::SIPTransaction(SIPMessage* message, SIPEngine* engine, bool outg
m_response(0), m_timeouts(0), m_timeout(0),
m_firstMessage(message), m_lastMessage(0), m_pending(0), m_engine(engine), m_private(0),
m_autoChangeParty(autoChangeParty ? *autoChangeParty : engine->autoChangeParty()),
m_autoAck(true)
m_autoAck(true), m_silent(false)
{
DDebug(getEngine(),DebugAll,"SIPTransaction::SIPTransaction(%p,%p,%d) [%p]",
message,engine,outgoing,this);
@ -81,7 +81,7 @@ SIPTransaction::SIPTransaction(SIPTransaction& original, SIPMessage* answer)
m_pending(0), m_engine(original.m_engine),
m_branch(original.m_branch), m_callid(original.m_callid), m_tag(original.m_tag),
m_private(0), m_autoChangeParty(original.m_autoChangeParty),
m_autoAck(original.m_autoAck)
m_autoAck(original.m_autoAck), m_silent(original.m_silent)
{
DDebug(getEngine(),DebugAll,"SIPTransaction::SIPTransaction(&%p,%p) [%p]",
&original,answer,this);
@ -127,7 +127,7 @@ SIPTransaction::SIPTransaction(const SIPTransaction& original, const String& tag
m_pending(0), m_engine(original.m_engine),
m_branch(original.m_branch), m_callid(original.m_callid), m_tag(tag),
m_private(0), m_autoChangeParty(original.m_autoChangeParty),
m_autoAck(original.m_autoAck)
m_autoAck(original.m_autoAck), m_silent(original.m_silent)
{
if (m_firstMessage)
m_firstMessage->ref();
@ -269,13 +269,18 @@ SIPEvent* SIPTransaction::getEvent(bool pendingOnly, u_int64_t time)
SIPEvent *e = 0;
if (m_pending) {
e = m_pending;
if (m_silent)
delete m_pending;
else
e = m_pending;
m_pending = 0;
return e;
}
if (m_transmit) {
m_transmit = false;
if (m_silent)
return 0;
return new SIPEvent(m_lastMessage ? m_lastMessage : m_firstMessage,this);
}
@ -295,15 +300,19 @@ SIPEvent* SIPTransaction::getEvent(bool pendingOnly, u_int64_t time)
}
e = isOutgoing() ? getClientEvent(m_state,timeout) : getServerEvent(m_state,timeout);
if (e)
return e;
if (e) {
if (!m_silent)
return e;
delete e;
return 0;
}
// do some common default processing
switch (m_state) {
case Retrans:
if (timeout < 0)
break;
if (timeout && m_lastMessage)
if (timeout && m_lastMessage && !m_silent)
e = new SIPEvent(m_lastMessage,this);
// fall through because we recheck the timeout
case Finish:
@ -313,7 +322,10 @@ SIPEvent* SIPTransaction::getEvent(bool pendingOnly, u_int64_t time)
// fall through so we don't wait another turn for processing
case Cleared:
setTimeout();
e = new SIPEvent(m_firstMessage,this);
if (!m_silent)
e = new SIPEvent(m_firstMessage,this);
else
e = new SIPEvent(0,this);
// make sure we don't get trough this one again
changeState(Invalid);
return e;
@ -794,4 +806,10 @@ bool SIPTransaction::tryAutoAuth(SIPMessage* answer)
return true;
}
void SIPTransaction::setSilent()
{
m_silent = true;
DDebug(getEngine(),DebugAll,"SIPTransaction silenced in state=%s [%p]",stateName(m_state),this);
}
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -1052,6 +1052,11 @@ public:
inline void* getUserData() const
{ return m_private; }
/**
* Silent this transaction
*/
void setSilent();
protected:
/**
* Constructor from previous auto authenticated transaction. This is used only internally
@ -1159,6 +1164,7 @@ protected:
void *m_private;
bool m_autoChangeParty;
bool m_autoAck;
bool m_silent;
};
/**

View File

@ -1056,6 +1056,12 @@ private:
bool infoAllowed(const SIPMessage* msg);
// Send tone(s) using method
bool sendTone(Message& msg, const char* tone, int meth, bool& retVal);
inline void setSilent(const char* reason) {
if (m_silent || (YSTRING("silent") != reason))
return;
m_silent = true;
clearTransaction();
}
SIPTransaction* m_tr;
SIPTransaction* m_tr2;
@ -1092,6 +1098,7 @@ private:
int m_lastRseq;
// media parameters before we sent a reINVITE
NamedList m_revert;
bool m_silent; // Silently discard SIP dialog
};
class YateSIPGenerate : public GenObject
@ -6041,7 +6048,8 @@ YateSIPConnection::YateSIPConnection(SIPEvent* ev, SIPTransaction* tr)
m_authBye(true), m_autoChangeParty(tr->getEngine()->autoChangeParty()),
m_checkAllowInfo(s_checkAllowInfo), m_missingAllowInfoDefVal(s_missingAllowInfoDefVal),
m_honorDtmfDetect(s_honorDtmfDetect),
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0), m_revert("")
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0),
m_revert(""), m_silent(false)
{
m_ipv6 = s_ipv6;
setSdpDebug(this,this);
@ -6238,7 +6246,8 @@ YateSIPConnection::YateSIPConnection(Message& msg, const String& uri, const char
m_authBye(false), m_autoChangeParty(true),
m_checkAllowInfo(s_checkAllowInfo), m_missingAllowInfoDefVal(s_missingAllowInfoDefVal),
m_honorDtmfDetect(s_honorDtmfDetect),
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0), m_revert("")
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0),
m_revert(""), m_silent(false)
{
Debug(this,DebugAll,"YateSIPConnection::YateSIPConnection(%p,'%s') [%p]",
&msg,uri.c_str(),this);
@ -6487,7 +6496,9 @@ void YateSIPConnection::clearTransaction()
Lock lock(driver());
if (m_tr) {
m_tr->setUserData(0);
if (m_tr->setResponse()) {
if (m_silent)
m_tr->setSilent();
else if (m_tr->setResponse()) {
SIPMessage* m = new SIPMessage(m_tr->initialMessage(),m_reasonCode,
m_reason.safe("Request Terminated"));
paramMutex().lock();
@ -6506,9 +6517,13 @@ void YateSIPConnection::clearTransaction()
// cancel any pending reINVITE
if (m_tr2) {
m_tr2->setUserData(0);
m_tr2->autoAck(true);
if (m_tr2->isIncoming())
m_tr2->setResponse(487);
if (m_silent)
m_tr2->setSilent();
else {
m_tr2->autoAck(true);
if (m_tr2->isIncoming())
m_tr2->setResponse(487);
}
m_tr2->deref();
m_tr2 = 0;
}
@ -6548,7 +6563,7 @@ void YateSIPConnection::hangup()
Engine::enqueue(m);
if (!error)
error = res.c_str();
bool sendBye = true;
bool sendBye = !m_silent;
switch (m_state) {
case Cleared:
clearTransaction();
@ -6563,7 +6578,7 @@ void YateSIPConnection::hangup()
break;
case Outgoing:
case Ringing:
if (m_cancel && m_tr) {
if (!m_silent && m_cancel && m_tr) {
SIPMessage* m = new SIPMessage("CANCEL",m_uri);
setSipParty(m,plugin.findLine(m_line),true,m_host,m_port);
if (!m->getParty())
@ -7731,6 +7746,7 @@ void YateSIPConnection::complete(Message& msg, bool minimal) const
void YateSIPConnection::disconnected(bool final, const char *reason)
{
Debug(this,DebugAll,"YateSIPConnection::disconnected() '%s' [%p]",reason,this);
setSilent(reason);
if (reason) {
int code = lookup(reason,dict_errors);
if (code >= 300 && code <= 699)
@ -7903,6 +7919,7 @@ bool YateSIPConnection::msgDrop(Message& msg, const char* reason)
{
if (!Channel::msgDrop(msg,reason))
return false;
setSilent(reason);
int code = lookup(reason,dict_errors);
if (code >= 300 && code <= 699)
setReason(lookup(code,SIPResponses,reason),code,driver());
@ -8207,6 +8224,7 @@ void YateSIPConnection::callAccept(Message& msg)
void YateSIPConnection::callRejected(const char* error, const char* reason, const Message* msg)
{
Channel::callRejected(error,reason,msg);
setSilent(error);
int code = lookup(error,dict_errors,500);
if (code < 300 || code > 699)
code = 500;