Hi all,
This is not really a BRI(stuff)-thing, but in my opinion, it fits in very well
into BRIstuff's other Asterisk-Patches that enhance Interoperability between
(bristuffed) Asterisk and snom phones:
The attached small patch modifies Asterisk to send SIP CANCEL Messages with
Reason: SIP ;cause=200 ;text="Call completed elsewhere"
if someone "in" the same Dial command answered the call (according to RFC
3326, section 3.1). This signals snom phones not to show an unanswered call
on phones that received that CANCEL message. See also snom KB
http://kb.snom.com/kb/index.php?View=entry&CategoryID=17&EntryID=75
Maybe other phones implement this, too.
Patches for this have been around for quite a while, but some of them where
not really coded properly, IMHO.
So I sat down and tried to implement it in a proper way for the (pre-)latest
BRIstuff (Junghanns) version bristuff-0.4.0-RC3b (Asterisk 1.4.21.1).
Just apply it to Bristuff's asterisk folder after all patches have been
applied and make / make install asterisk.
Only briefly tested, so no warranties...
Maybe someone out there finds this patch useful, I guess it'll never make its
way into the official Bristuff dist anyway....
--
Philipp Walker
Binatec AG
Ingenieurbüro für Nachrichten- und Informationstechnik
Q4 Altdorf Ost
Hellgasse 23 / Postfach
6460 Altdorf
[EMAIL PROTECTED]
www.binatec.ch
diff -u -r asterisk-1.4.21.1/apps/app_dial.c asterisk-1.4.21.1_cae/apps/app_dial.c
--- asterisk-1.4.21.1/apps/app_dial.c 2008-09-26 10:13:45.000000000 +0200
+++ asterisk-1.4.21.1_cae/apps/app_dial.c 2008-09-26 14:02:48.000000000 +0200
@@ -326,14 +326,17 @@
};
-static void hanguptree(struct dial_localuser *outgoing, struct ast_channel *exception)
+static void hanguptree(struct dial_localuser *outgoing, struct ast_channel *exception, int answered_elsewhere)
{
/* Hang up a tree of stuff */
struct dial_localuser *oo;
while (outgoing) {
/* Hangup any existing lines we have open */
- if (outgoing->chan && (outgoing->chan != exception))
+ if (outgoing->chan && (outgoing->chan != exception)) {
+ if (answered_elsewhere)
+ ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
ast_hangup(outgoing->chan);
+ }
oo = outgoing;
outgoing=outgoing->next;
free(oo);
@@ -1366,7 +1369,7 @@
/* Ah ha! Someone answered within the desired timeframe. Of course after this
we will always return with -1 so that it is hung up properly after the
conversation. */
- hanguptree(outgoing, peer);
+ hanguptree(outgoing, peer, 1);
outgoing = NULL;
/* If appropriate, log that we have a destination channel */
if (chan->cdr)
@@ -1569,7 +1572,7 @@
ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
peer->priority = chan->priority + 2;
ast_pbx_start(peer);
- hanguptree(outgoing, NULL);
+ hanguptree(outgoing, NULL, 0);
if (continue_exec)
*continue_exec = 1;
res = 0;
@@ -1751,7 +1754,7 @@
ast_indicate(chan, -1);
}
ast_rtp_early_bridge(chan, NULL);
- hanguptree(outgoing, NULL);
+ hanguptree(outgoing, NULL, 0);
pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
if (option_debug)
ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
diff -u -r asterisk-1.4.21.1/channels/chan_sip.c asterisk-1.4.21.1_cae/channels/chan_sip.c
--- asterisk-1.4.21.1/channels/chan_sip.c 2008-09-26 10:13:45.000000000 +0200
+++ asterisk-1.4.21.1_cae/channels/chan_sip.c 2008-09-26 11:51:31.000000000 +0200
@@ -966,6 +966,10 @@
int lastinvite; /*!< Last Cseq of invite */
int lastnoninvite; /*!< Last Cseq of non-invite */
struct ast_flags flags[2]; /*!< SIP_ flags */
+
+ /* boolean or small integers that don't belong in flags */
+ char answered_elsewhere; /*!< This call is cancelled due to answer on another channel */
+
int timer_t1; /*!< SIP timer T1, ms rtt */
unsigned int sipoptions; /*!< Supported SIP options on the other end */
struct ast_codec_pref prefs; /*!< codec prefs */
@@ -3528,6 +3532,13 @@
return 0;
}
+ if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) {
+ if(option_debug)
+ ast_log(LOG_DEBUG, "This call was answered elsewhere\n");
+ append_history(p, "Cancel", "Call answered elsewhere");
+ p->answered_elsewhere = TRUE;
+ }
+
if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
if (option_debug && sipdebug)
@@ -7953,6 +7964,10 @@
p->invitestate = INV_CONFIRMED;
reqprep(&resp, p, sipmethod, seqno, newbranch);
+
+ if (sipmethod == SIP_CANCEL && p->answered_elsewhere)
+ add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
+
add_header_contentLength(&resp, 0);
return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
}
diff -u -r asterisk-1.4.21.1/include/asterisk/channel.h asterisk-1.4.21.1_cae/include/asterisk/channel.h
--- asterisk-1.4.21.1/include/asterisk/channel.h 2008-09-26 10:13:45.000000000 +0200
+++ asterisk-1.4.21.1_cae/include/asterisk/channel.h 2008-09-26 12:02:08.000000000 +0200
@@ -514,9 +514,12 @@
/*! This is set to tell the channel not to generate DTMF begin frames, and
* to instead only generate END frames. */
AST_FLAG_END_DTMF_ONLY = (1 << 14),
+ /*! Flag to show channels that this call is hangup due to the fact that the call
+ * was indeed anwered, but in another channel */
+ AST_FLAG_ANSWERED_ELSEWHERE = (1 << 15),
/*! This flag indicates that on a masquerade, an active stream should not
* be carried over */
- AST_FLAG_MASQ_NOSTREAM = (1 << 15),
+ AST_FLAG_MASQ_NOSTREAM = (1 << 16),
};
/*! \brief ast_bridge_config flags */
_______________________________________________
Bristuff-users mailing list
[email protected]
http://lists.three-dimensional.net/mailman/listinfo/bristuff-users