Add option to stop execution of an outgoing call.
Propagate that parameter in dumb channel, tone generator and wave file. In SIP, simulate going through the whole SIP stack before stopping execution of the call. git-svn-id: http://voip.null.ro/svn/yate@6401 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
1db8917b18
commit
47908cf938
|
@ -1499,8 +1499,13 @@ bool Driver::received(Message &msg, int id)
|
||||||
if (!canAccept(false))
|
if (!canAccept(false))
|
||||||
return false;
|
return false;
|
||||||
if (dest.startSkip(m_prefix,false) ||
|
if (dest.startSkip(m_prefix,false) ||
|
||||||
(dest.startSkip("line/",false) && hasLine(msg.getValue(YSTRING("line")))))
|
(dest.startSkip("line/",false) && hasLine(msg.getValue(YSTRING("line"))))) {
|
||||||
|
if (msg.getBoolValue(YSTRING("stop_call"),false) && !canStopCall()) {
|
||||||
|
msg.setParam(YSTRING("error"),"stopped_call");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return msgExecute(msg,dest);
|
return msgExecute(msg,dest);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ SIPMessage::SIPMessage(const SIPMessage& original)
|
||||||
body(0), m_ep(0),
|
body(0), m_ep(0),
|
||||||
m_valid(original.isValid()), m_answer(original.isAnswer()),
|
m_valid(original.isValid()), m_answer(original.isAnswer()),
|
||||||
m_outgoing(original.isOutgoing()), m_ack(original.isACK()),
|
m_outgoing(original.isOutgoing()), m_ack(original.isACK()),
|
||||||
m_cseq(-1), m_flags(original.getFlags())
|
m_cseq(-1), m_flags(original.getFlags()), m_dontSend(original.m_dontSend)
|
||||||
{
|
{
|
||||||
DDebug(DebugAll,"SIPMessage::SIPMessage(&%p) [%p]",
|
DDebug(DebugAll,"SIPMessage::SIPMessage(&%p) [%p]",
|
||||||
&original,this);
|
&original,this);
|
||||||
|
@ -66,7 +66,8 @@ SIPMessage::SIPMessage(const SIPMessage& original)
|
||||||
SIPMessage::SIPMessage(const char* _method, const char* _uri, const char* _version)
|
SIPMessage::SIPMessage(const char* _method, const char* _uri, const char* _version)
|
||||||
: version(_version), method(_method), uri(_uri), code(0),
|
: version(_version), method(_method), uri(_uri), code(0),
|
||||||
body(0), m_ep(0), m_valid(true),
|
body(0), m_ep(0), m_valid(true),
|
||||||
m_answer(false), m_outgoing(true), m_ack(false), m_cseq(-1), m_flags(-1)
|
m_answer(false), m_outgoing(true), m_ack(false), m_cseq(-1), m_flags(-1),
|
||||||
|
m_dontSend(false)
|
||||||
{
|
{
|
||||||
DDebug(DebugAll,"SIPMessage::SIPMessage('%s','%s','%s') [%p]",
|
DDebug(DebugAll,"SIPMessage::SIPMessage('%s','%s','%s') [%p]",
|
||||||
_method,_uri,_version,this);
|
_method,_uri,_version,this);
|
||||||
|
@ -74,7 +75,8 @@ SIPMessage::SIPMessage(const char* _method, const char* _uri, const char* _versi
|
||||||
|
|
||||||
SIPMessage::SIPMessage(SIPParty* ep, const char* buf, int len, unsigned int* bodyLen)
|
SIPMessage::SIPMessage(SIPParty* ep, const char* buf, int len, unsigned int* bodyLen)
|
||||||
: code(0), body(0), m_ep(ep), m_valid(false),
|
: code(0), body(0), m_ep(ep), m_valid(false),
|
||||||
m_answer(false), m_outgoing(false), m_ack(false), m_cseq(-1), m_flags(-1)
|
m_answer(false), m_outgoing(false), m_ack(false), m_cseq(-1), m_flags(-1),
|
||||||
|
m_dontSend(false)
|
||||||
{
|
{
|
||||||
DDebug(DebugInfo,"SIPMessage::SIPMessage(%p,%d) [%p]\r\n------\r\n%s------",
|
DDebug(DebugInfo,"SIPMessage::SIPMessage(%p,%d) [%p]\r\n------\r\n%s------",
|
||||||
buf,len,this,buf);
|
buf,len,this,buf);
|
||||||
|
@ -92,7 +94,8 @@ SIPMessage::SIPMessage(SIPParty* ep, const char* buf, int len, unsigned int* bod
|
||||||
SIPMessage::SIPMessage(const SIPMessage* message, int _code, const char* _reason)
|
SIPMessage::SIPMessage(const SIPMessage* message, int _code, const char* _reason)
|
||||||
: code(_code), body(0),
|
: code(_code), body(0),
|
||||||
m_ep(0), m_valid(false),
|
m_ep(0), m_valid(false),
|
||||||
m_answer(true), m_outgoing(true), m_ack(false), m_cseq(-1), m_flags(-1)
|
m_answer(true), m_outgoing(true), m_ack(false), m_cseq(-1), m_flags(-1),
|
||||||
|
m_dontSend(false)
|
||||||
{
|
{
|
||||||
DDebug(DebugAll,"SIPMessage::SIPMessage(%p,%d,'%s') [%p]",
|
DDebug(DebugAll,"SIPMessage::SIPMessage(%p,%d,'%s') [%p]",
|
||||||
message,_code,_reason,this);
|
message,_code,_reason,this);
|
||||||
|
@ -121,7 +124,8 @@ SIPMessage::SIPMessage(const SIPMessage* message, int _code, const char* _reason
|
||||||
SIPMessage::SIPMessage(const SIPMessage* original, const SIPMessage* answer)
|
SIPMessage::SIPMessage(const SIPMessage* original, const SIPMessage* answer)
|
||||||
: method("ACK"), code(0),
|
: method("ACK"), code(0),
|
||||||
body(0), m_ep(0), m_valid(false),
|
body(0), m_ep(0), m_valid(false),
|
||||||
m_answer(false), m_outgoing(true), m_ack(true), m_cseq(-1), m_flags(-1)
|
m_answer(false), m_outgoing(true), m_ack(true), m_cseq(-1), m_flags(-1),
|
||||||
|
m_dontSend(false)
|
||||||
{
|
{
|
||||||
DDebug(DebugAll,"SIPMessage::SIPMessage(%p,%p) [%p]",original,answer,this);
|
DDebug(DebugAll,"SIPMessage::SIPMessage(%p,%p) [%p]",original,answer,this);
|
||||||
if (!(original && original->isValid()))
|
if (!(original && original->isValid()))
|
||||||
|
|
|
@ -314,6 +314,19 @@ public:
|
||||||
inline int getFlags() const
|
inline int getFlags() const
|
||||||
{ return m_flags; }
|
{ return m_flags; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get value of flag that specifies the message is not to be sent on wire
|
||||||
|
* @return The value of the flag
|
||||||
|
*/
|
||||||
|
inline bool dontSend() const
|
||||||
|
{ return m_dontSend; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set flag that specifies the message is not to be sent on wire
|
||||||
|
* @param val Value of the flag to send
|
||||||
|
*/
|
||||||
|
inline void dontSend(bool val)
|
||||||
|
{ m_dontSend = val; }
|
||||||
/**
|
/**
|
||||||
* Find a header line by name
|
* Find a header line by name
|
||||||
* @param name Name of the header to locate
|
* @param name Name of the header to locate
|
||||||
|
@ -523,6 +536,7 @@ protected:
|
||||||
mutable DataBlock m_data;
|
mutable DataBlock m_data;
|
||||||
String m_authUser;
|
String m_authUser;
|
||||||
String m_authPass;
|
String m_authPass;
|
||||||
|
bool m_dontSend;
|
||||||
private:
|
private:
|
||||||
SIPMessage(); // no, thanks
|
SIPMessage(); // no, thanks
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,6 +31,9 @@ public:
|
||||||
~DumbDriver();
|
~DumbDriver();
|
||||||
virtual void initialize();
|
virtual void initialize();
|
||||||
virtual bool msgExecute(Message& msg, String& dest);
|
virtual bool msgExecute(Message& msg, String& dest);
|
||||||
|
protected:
|
||||||
|
bool canStopCall() const
|
||||||
|
{ return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
INIT_PLUGIN(DumbDriver);
|
INIT_PLUGIN(DumbDriver);
|
||||||
|
@ -71,6 +74,10 @@ bool DumbDriver::msgExecute(Message& msg, String& dest)
|
||||||
{
|
{
|
||||||
CallEndpoint *dd = YOBJECT(CallEndpoint,msg.userData());
|
CallEndpoint *dd = YOBJECT(CallEndpoint,msg.userData());
|
||||||
if (dd) {
|
if (dd) {
|
||||||
|
if (msg.getBoolValue(YSTRING("stop_call"),false)) {
|
||||||
|
msg.setParam(YSTRING("error"),"stopped_call");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
DumbChannel *c = new DumbChannel(dest,msg,true);
|
DumbChannel *c = new DumbChannel(dest,msg,true);
|
||||||
c->initChan();
|
c->initChan();
|
||||||
if (dd->connect(c)) {
|
if (dd->connect(c)) {
|
||||||
|
@ -111,6 +118,7 @@ bool DumbDriver::msgExecute(Message& msg, String& dest)
|
||||||
m.copyParam(msg,"callername");
|
m.copyParam(msg,"callername");
|
||||||
m.copyParam(msg,"maxcall");
|
m.copyParam(msg,"maxcall");
|
||||||
m.copyParam(msg,"timeout");
|
m.copyParam(msg,"timeout");
|
||||||
|
m.copyParam(msg,YSTRING("stop_call"));
|
||||||
m.copyParams(msg,msg.getValue("copyparams"));
|
m.copyParams(msg,msg.getValue("copyparams"));
|
||||||
|
|
||||||
const String& callto = msg["direct"];
|
const String& callto = msg["direct"];
|
||||||
|
|
|
@ -182,6 +182,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void statusModule(String& str);
|
void statusModule(String& str);
|
||||||
void statusParams(String& str);
|
void statusParams(String& str);
|
||||||
|
bool canStopCall() const
|
||||||
|
{ return true; }
|
||||||
private:
|
private:
|
||||||
AttachHandler* m_handler;
|
AttachHandler* m_handler;
|
||||||
};
|
};
|
||||||
|
@ -1109,6 +1111,10 @@ bool ToneGenDriver::msgExecute(Message& msg, String& dest)
|
||||||
{
|
{
|
||||||
CallEndpoint* ch = YOBJECT(CallEndpoint,msg.userData());
|
CallEndpoint* ch = YOBJECT(CallEndpoint,msg.userData());
|
||||||
if (ch) {
|
if (ch) {
|
||||||
|
if (msg.getBoolValue(YSTRING("stop_call"),false)) {
|
||||||
|
msg.setParam(YSTRING("error"),"stopped_call");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
ToneChan *tc = new ToneChan(dest,msg["lang"]);
|
ToneChan *tc = new ToneChan(dest,msg["lang"]);
|
||||||
tc->initChan();
|
tc->initChan();
|
||||||
tc->setChanParams(msg);
|
tc->setChanParams(msg);
|
||||||
|
@ -1130,6 +1136,7 @@ bool ToneGenDriver::msgExecute(Message& msg, String& dest)
|
||||||
m.clearParam(YSTRING("id"));
|
m.clearParam(YSTRING("id"));
|
||||||
m.setParam("module",name());
|
m.setParam("module",name());
|
||||||
m.setParam("cdrtrack",String::boolText(false));
|
m.setParam("cdrtrack",String::boolText(false));
|
||||||
|
m.copyParam(msg,YSTRING("stop_call"));
|
||||||
m.copyParam(msg,YSTRING("called"));
|
m.copyParam(msg,YSTRING("called"));
|
||||||
m.copyParam(msg,YSTRING("caller"));
|
m.copyParam(msg,YSTRING("caller"));
|
||||||
m.copyParam(msg,YSTRING("callername"));
|
m.copyParam(msg,YSTRING("callername"));
|
||||||
|
|
|
@ -123,6 +123,8 @@ public:
|
||||||
virtual bool msgExecute(Message& msg, String& dest);
|
virtual bool msgExecute(Message& msg, String& dest);
|
||||||
protected:
|
protected:
|
||||||
void statusParams(String& str);
|
void statusParams(String& str);
|
||||||
|
bool canStopCall() const
|
||||||
|
{ return true; }
|
||||||
private:
|
private:
|
||||||
AttachHandler* m_handler;
|
AttachHandler* m_handler;
|
||||||
};
|
};
|
||||||
|
@ -1130,6 +1132,10 @@ bool WaveFileDriver::msgExecute(Message& msg, String& dest)
|
||||||
unsigned int maxlen = msg.getIntValue("maxlen");
|
unsigned int maxlen = msg.getIntValue("maxlen");
|
||||||
CallEndpoint* ch = YOBJECT(CallEndpoint,msg.userData());
|
CallEndpoint* ch = YOBJECT(CallEndpoint,msg.userData());
|
||||||
if (ch) {
|
if (ch) {
|
||||||
|
if (msg.getBoolValue(YSTRING("stop_call"),false)) {
|
||||||
|
msg.setParam(YSTRING("error"),"stopped_call");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Debug(this,DebugInfo,"%s wave file '%s'", (meth ? "Record to" : "Play from"),
|
Debug(this,DebugInfo,"%s wave file '%s'", (meth ? "Record to" : "Play from"),
|
||||||
dest.matchString(2).c_str());
|
dest.matchString(2).c_str());
|
||||||
WaveChan *c = new WaveChan(dest.matchString(2),meth,maxlen,msg,msg.getParam("callto"));
|
WaveChan *c = new WaveChan(dest.matchString(2),meth,maxlen,msg,msg.getParam("callto"));
|
||||||
|
@ -1159,6 +1165,7 @@ bool WaveFileDriver::msgExecute(Message& msg, String& dest)
|
||||||
m.copyParam(msg,YSTRING("called"));
|
m.copyParam(msg,YSTRING("called"));
|
||||||
m.copyParam(msg,YSTRING("caller"));
|
m.copyParam(msg,YSTRING("caller"));
|
||||||
m.copyParam(msg,YSTRING("callername"));
|
m.copyParam(msg,YSTRING("callername"));
|
||||||
|
m.copyParam(msg,YSTRING("stop_call"));
|
||||||
String callto(msg.getValue(YSTRING("direct")));
|
String callto(msg.getValue(YSTRING("direct")));
|
||||||
if (callto.null()) {
|
if (callto.null()) {
|
||||||
const char *targ = msg.getValue(YSTRING("target"));
|
const char *targ = msg.getValue(YSTRING("target"));
|
||||||
|
|
|
@ -4288,6 +4288,10 @@ bool YJGDriver::received(Message& msg, int id)
|
||||||
String callto(msg.getValue("callto"));
|
String callto(msg.getValue("callto"));
|
||||||
if (!callto.startSkip("jabber/",false))
|
if (!callto.startSkip("jabber/",false))
|
||||||
return Driver::received(msg,id);
|
return Driver::received(msg,id);
|
||||||
|
if (msg.getBoolValue(YSTRING("stop_call"),false) && !canStopCall()) {
|
||||||
|
msg.setParam(YSTRING("error"),"stopped_call");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return msgExecute(msg,callto);
|
return msgExecute(msg,callto);
|
||||||
}
|
}
|
||||||
if (id == Halt) {
|
if (id == Halt) {
|
||||||
|
|
|
@ -1009,6 +1009,8 @@ public:
|
||||||
{ return callid == m_dialog &&
|
{ return callid == m_dialog &&
|
||||||
m_dialog.fromTag(isOutgoing()) == fromTag &&
|
m_dialog.fromTag(isOutgoing()) == fromTag &&
|
||||||
m_dialog.toTag(isOutgoing()) == toTag; }
|
m_dialog.toTag(isOutgoing()) == toTag; }
|
||||||
|
inline bool stopOCall() const
|
||||||
|
{ return m_stopOCall; }
|
||||||
// Build and add a callid parameter to a list
|
// Build and add a callid parameter to a list
|
||||||
static inline void addCallId(NamedList& nl, const String& dialog,
|
static inline void addCallId(NamedList& nl, const String& dialog,
|
||||||
const String& fromTag, const String& toTag) {
|
const String& fromTag, const String& toTag) {
|
||||||
|
@ -1099,6 +1101,7 @@ private:
|
||||||
// media parameters before we sent a reINVITE
|
// media parameters before we sent a reINVITE
|
||||||
NamedList m_revert;
|
NamedList m_revert;
|
||||||
bool m_silent; // Silently discard SIP dialog
|
bool m_silent; // Silently discard SIP dialog
|
||||||
|
bool m_stopOCall;
|
||||||
};
|
};
|
||||||
|
|
||||||
class YateSIPGenerate : public GenObject
|
class YateSIPGenerate : public GenObject
|
||||||
|
@ -1164,6 +1167,8 @@ protected:
|
||||||
// Setup a listener from config
|
// Setup a listener from config
|
||||||
void setupListener(const String& name, const NamedList& params, bool isGeneral,
|
void setupListener(const String& name, const NamedList& params, bool isGeneral,
|
||||||
const NamedList& defs = NamedList::empty());
|
const NamedList& defs = NamedList::empty());
|
||||||
|
bool canStopCall() const
|
||||||
|
{ return true; }
|
||||||
private:
|
private:
|
||||||
bool onHelp(Message& msg);
|
bool onHelp(Message& msg);
|
||||||
// Add status methods
|
// Add status methods
|
||||||
|
@ -3523,12 +3528,14 @@ int YateSIPTCPTransport::process()
|
||||||
SIPMessage* msg = static_cast<SIPMessage*>(o->get());
|
SIPMessage* msg = static_cast<SIPMessage*>(o->get());
|
||||||
if (s_printMsg && (o != first || m_sent < 0))
|
if (s_printMsg && (o != first || m_sent < 0))
|
||||||
printSendMsg(msg);
|
printSendMsg(msg);
|
||||||
if (o != first || m_sent <= 0)
|
if (!msg->dontSend()) {
|
||||||
buf += msg->getBuffer();
|
if (o != first || m_sent <= 0)
|
||||||
else {
|
buf += msg->getBuffer();
|
||||||
int remaining = msg->getBuffer().length() - m_sent;
|
else {
|
||||||
if (remaining > 0)
|
int remaining = msg->getBuffer().length() - m_sent;
|
||||||
buf.assign(((char*)msg->getBuffer().data()) + m_sent,remaining);
|
if (remaining > 0)
|
||||||
|
buf.assign(((char*)msg->getBuffer().data()) + m_sent,remaining);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buf.length()) {
|
if (buf.length()) {
|
||||||
|
@ -3812,10 +3819,12 @@ bool YateSIPTCPTransport::sendPending(const Time& time, bool& sent)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (msg->dontSend())
|
||||||
|
break;
|
||||||
const DataBlock& buf = msg->getBuffer();
|
const DataBlock& buf = msg->getBuffer();
|
||||||
sent = true;
|
sent = !msg->dontSend();
|
||||||
int len = buf.length();
|
int len = buf.length();
|
||||||
if (len > m_sent) {
|
if (sent && len > m_sent) {
|
||||||
char* b = (char*)(buf.data());
|
char* b = (char*)(buf.data());
|
||||||
len -= m_sent;
|
len -= m_sent;
|
||||||
int wr = m_sock->writeData(b + m_sent,len);
|
int wr = m_sock->writeData(b + m_sent,len);
|
||||||
|
@ -4398,6 +4407,11 @@ bool YateUDPParty::transmit(SIPEvent* event)
|
||||||
Lock lck(m_transport);
|
Lock lck(m_transport);
|
||||||
if (s_printMsg)
|
if (s_printMsg)
|
||||||
m_transport->printSendMsg(msg,&m_addr);
|
m_transport->printSendMsg(msg,&m_addr);
|
||||||
|
if (msg->dontSend()) {
|
||||||
|
if (event->getTransaction())
|
||||||
|
event->getTransaction()->setSilent();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return m_transport->send(msg->getBuffer().data(),msg->getBuffer().length(),m_addr);
|
return m_transport->send(msg->getBuffer().data(),msg->getBuffer().length(),m_addr);
|
||||||
}
|
}
|
||||||
String tmp;
|
String tmp;
|
||||||
|
@ -4485,8 +4499,12 @@ bool YateTCPParty::transmit(SIPEvent* event)
|
||||||
const SIPMessage* msg = event->getMessage();
|
const SIPMessage* msg = event->getMessage();
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return false;
|
return false;
|
||||||
if (m_transport)
|
if (m_transport) {
|
||||||
return m_transport->send(event);
|
bool ok = m_transport->send(event);
|
||||||
|
if (msg->dontSend() && event->getTransaction())
|
||||||
|
event->getTransaction()->setSilent();
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
String tmp;
|
String tmp;
|
||||||
getMsgLine(tmp,msg);
|
getMsgLine(tmp,msg);
|
||||||
Debug(&plugin,DebugWarn,"YateTCPParty no transport to send %s [%p]",
|
Debug(&plugin,DebugWarn,"YateTCPParty no transport to send %s [%p]",
|
||||||
|
@ -6049,7 +6067,7 @@ YateSIPConnection::YateSIPConnection(SIPEvent* ev, SIPTransaction* tr)
|
||||||
m_checkAllowInfo(s_checkAllowInfo), m_missingAllowInfoDefVal(s_missingAllowInfoDefVal),
|
m_checkAllowInfo(s_checkAllowInfo), m_missingAllowInfoDefVal(s_missingAllowInfoDefVal),
|
||||||
m_honorDtmfDetect(s_honorDtmfDetect),
|
m_honorDtmfDetect(s_honorDtmfDetect),
|
||||||
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0),
|
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0),
|
||||||
m_revert(""), m_silent(false)
|
m_revert(""), m_silent(false), m_stopOCall(false)
|
||||||
{
|
{
|
||||||
m_ipv6 = s_ipv6;
|
m_ipv6 = s_ipv6;
|
||||||
setSdpDebug(this,this);
|
setSdpDebug(this,this);
|
||||||
|
@ -6247,7 +6265,7 @@ YateSIPConnection::YateSIPConnection(Message& msg, const String& uri, const char
|
||||||
m_checkAllowInfo(s_checkAllowInfo), m_missingAllowInfoDefVal(s_missingAllowInfoDefVal),
|
m_checkAllowInfo(s_checkAllowInfo), m_missingAllowInfoDefVal(s_missingAllowInfoDefVal),
|
||||||
m_honorDtmfDetect(s_honorDtmfDetect),
|
m_honorDtmfDetect(s_honorDtmfDetect),
|
||||||
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0),
|
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0),
|
||||||
m_revert(""), m_silent(false)
|
m_revert(""), m_silent(false), m_stopOCall(msg.getBoolValue(YSTRING("stop_call")))
|
||||||
{
|
{
|
||||||
Debug(this,DebugAll,"YateSIPConnection::YateSIPConnection(%p,'%s') [%p]",
|
Debug(this,DebugAll,"YateSIPConnection::YateSIPConnection(%p,'%s') [%p]",
|
||||||
&msg,uri.c_str(),this);
|
&msg,uri.c_str(),this);
|
||||||
|
@ -6316,6 +6334,7 @@ YateSIPConnection::YateSIPConnection(Message& msg, const String& uri, const char
|
||||||
if (!m_party && sips() && !haveTransParams(msg,"o"))
|
if (!m_party && sips() && !haveTransParams(msg,"o"))
|
||||||
setParty(msg,true,"o",m_uri.getHost(),m_uri.getPort(),this);
|
setParty(msg,true,"o",m_uri.getHost(),m_uri.getPort(),this);
|
||||||
SIPMessage* m = new SIPMessage("INVITE",m_uri);
|
SIPMessage* m = new SIPMessage("INVITE",m_uri);
|
||||||
|
m->dontSend(m_stopOCall);
|
||||||
setSipParty(m,line,true,msg.getValue("host"),msg.getIntValue("port"));
|
setSipParty(m,line,true,msg.getValue("host"),msg.getIntValue("port"));
|
||||||
if (!m->getParty()) {
|
if (!m->getParty()) {
|
||||||
String tmp;
|
String tmp;
|
||||||
|
@ -6579,7 +6598,7 @@ void YateSIPConnection::hangup()
|
||||||
break;
|
break;
|
||||||
case Outgoing:
|
case Outgoing:
|
||||||
case Ringing:
|
case Ringing:
|
||||||
if (!m_silent && m_cancel && m_tr) {
|
if (!m_silent && !m_stopOCall && m_cancel && m_tr) {
|
||||||
SIPMessage* m = new SIPMessage("CANCEL",m_uri);
|
SIPMessage* m = new SIPMessage("CANCEL",m_uri);
|
||||||
setSipParty(m,plugin.findLine(m_line),true,m_host,m_port);
|
setSipParty(m,plugin.findLine(m_line),true,m_host,m_port);
|
||||||
if (!m->getParty())
|
if (!m->getParty())
|
||||||
|
@ -9289,6 +9308,10 @@ bool SIPDriver::msgExecute(Message& msg, String& dest)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
YateSIPConnection* conn = new YateSIPConnection(msg,dest,msg.getValue(YSTRING("id")));
|
YateSIPConnection* conn = new YateSIPConnection(msg,dest,msg.getValue(YSTRING("id")));
|
||||||
|
if (msg.getBoolValue(YSTRING("stop_call"),false)) {
|
||||||
|
conn->destruct();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
conn->initChan();
|
conn->initChan();
|
||||||
if (conn->getTransaction()) {
|
if (conn->getTransaction()) {
|
||||||
CallEndpoint* ch = YOBJECT(CallEndpoint,msg.userData());
|
CallEndpoint* ch = YOBJECT(CallEndpoint,msg.userData());
|
||||||
|
|
|
@ -2429,6 +2429,13 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void loadLimits();
|
virtual void loadLimits();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module is able to simulate a call without generating anything at protocol layer
|
||||||
|
* @return True if module is able
|
||||||
|
*/
|
||||||
|
virtual bool canStopCall() const
|
||||||
|
{ return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set if this driver is for dynamic (variable number) channels
|
* Set if this driver is for dynamic (variable number) channels
|
||||||
* @param variable True if the channels are dynamic, false for fixed
|
* @param variable True if the channels are dynamic, false for fixed
|
||||||
|
|
Loading…
Reference in New Issue