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:
parent
dd4a0224de
commit
8fe3d0585c
|
@ -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: */
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue