Restore SIP DTMF overlap dialing method.

The recent fix for ASTERISK-17288 to get RFC3578 SIP overlap support
working correctly removed a long standing ability to do overlap dialing
using DTMF in the early media phase of a call.

See ASTERISK-18702 it has a very good description of the issue.

I started with Pavel Troller's chan_sip.diff patch on issue
ASTERISK-18702.

* Added 'dtmf' enum value to sip.conf allowoverlap config option.  The new
option value causes the Incomplte application to not send anything with
chan_sip so the caller can supply more digits via DTMF.

* Renames SIP_GET_DEST_PICKUP_EXTEN_FOUND to SIP_GET_DEST_EXTEN_MATCHMORE
since that is what it really means.

* Fixed get_destination() inconsistency with the pickup extension
matching.

* Fixed initialization of PAGE3 of global_flags in reload_config().

(closes issue ASTERISK-18702)
Reported by: Pavel Troller

Review: https://reviewboard.asterisk.org/r/1517/

Review: https://reviewboard.asterisk.org/r/1582/
........

Merged revisions 345273 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 345275 from http://svn.asterisk.org/svn/asterisk/branches/10


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@345276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
certified/11.2
Richard Mudgett 14 years ago
parent 1cef6cf8cd
commit 113612b9d6

@ -20,6 +20,10 @@
From 1.6.2 to 1.8:
* chan_sip no longer sets HASH(SIP_CAUSE,<chan name>) on channels by default.
This must now be enabled by setting 'sipstorecause' to 'yes' in sip.conf.
This carries a performance penalty.
* Asterisk now requires libpri 1.4.11+ for PRI support.
* A couple of CLI commands in res_ais were changed back to their original form:
@ -92,8 +96,8 @@ From 1.6.2 to 1.8:
* ExternalIVR will now send Z events for invalid or missing files, T events
now include the interrupted file and bugs in argument parsing have been
fixed so there may be arguments specified in incorrect ways that were
working that will no longer work.
Please see doc/externalivr.txt for details.
working that will no longer work. Please see
https://wiki.asterisk.org/wiki/display/AST/External+IVR+Interface for details.
* OSP lookup application changes following variable names:
OSPPEERIP to OSPINPEERIP
@ -155,6 +159,13 @@ From 1.6.2 to 1.8:
changes to the files will not be detected. You can revert to polling the
directory by specifying --without-inotify to configure before compiling.
* The 'sipusers' realtime table has been removed completely. Use the 'sippeers'
table with type 'user' for user type objects.
* The sip.conf allowoverlap option now accepts 'dtmf' as a value. If you
are using the early media DTMF overlap dialing method you now need to set
allowoverlap=dtmf.
From 1.6.1 to 1.6.2:
* SIP no longer sends the 183 progress message for early media by
@ -250,6 +261,11 @@ From 1.6.1 to 1.6.2:
* The cdr.conf file must exist and be configured correctly in order for CDR
records to be written.
* cdr_pgsql now assumes the encoding of strings it is handed are in LATIN9,
which should cover most uses of the extended ASCII set. If your strings
use a different encoding in Asterisk, the "encoding" parameter may be set
to specify the correct character set.
From 1.6.0.1 to 1.6.1:
* The ast_agi_register_multiple() and ast_agi_unregister_multiple()
@ -311,6 +327,3 @@ From 1.6.0.x to 1.6.1:
which should be a char(8) or larger. This field specifies whether or not a
message has been designated to be "Urgent", "PRIORITY", or not.
* The 'sipusers' realtime table has been removed completely. Use the 'sippeers'
table with type 'user' for user type objects.

@ -1384,6 +1384,7 @@ static void print_group(int fd, ast_group_t group, int crlf);
static const char *dtmfmode2str(int mode) attribute_const;
static int str2dtmfmode(const char *str) attribute_unused;
static const char *insecure2str(int mode) attribute_const;
static const char *allowoverlap2str(int mode) attribute_const;
static void cleanup_stale_contexts(char *new, char *old);
static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
static const char *domain_mode_to_text(const enum domain_mode mode);
@ -6837,17 +6838,25 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
break;
case AST_CONTROL_INCOMPLETE:
if (ast->_state != AST_STATE_UP) {
if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
case SIP_PAGE2_ALLOWOVERLAP_YES:
transmit_response_reliable(p, "484 Address Incomplete", &p->initreq);
} else {
p->invitestate = INV_COMPLETED;
sip_alreadygone(p);
ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
break;
case SIP_PAGE2_ALLOWOVERLAP_DTMF:
/* Just wait for inband DTMF digits */
break;
default:
/* it actually means no support for overlap */
transmit_response_reliable(p, "404 Not Found", &p->initreq);
}
p->invitestate = INV_COMPLETED;
sip_alreadygone(p);
ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
break;
}
res = 0;
}
break;
case AST_CONTROL_PROCEEDING:
if ((ast->_state != AST_STATE_UP) &&
@ -15506,18 +15515,23 @@ static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_re
}
} else {
struct ast_cc_agent *agent;
int which = 0;
/* Check the dialplan for the username part of the request URI,
the domain will be stored in the SIPDOMAIN variable
Return 0 if we have a matching extension */
if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) ||
(ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) && (which = 1)) ||
!strcmp(decoded_uri, ast_pickup_ext())) {
if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) {
if (!oreq) {
ast_string_field_set(p, exten, which ? decoded_uri : uri);
ast_string_field_set(p, exten, uri);
}
return SIP_GET_DEST_EXTEN_FOUND;
}
if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
|| !strcmp(decoded_uri, ast_pickup_ext())) {
if (!oreq) {
ast_string_field_set(p, exten, decoded_uri);
}
return SIP_GET_DEST_EXTEN_FOUND;
} else if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) {
}
if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) {
struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
/* This is a CC recall. We can set p's extension to the exten from
* the original INVITE
@ -15536,11 +15550,12 @@ static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_re
}
}
/* Return 1 for pickup extension or overlap dialling support (if we support it) */
if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) &&
ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) ||
!strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) {
return SIP_GET_DEST_PICKUP_EXTEN_FOUND;
if (ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)
&& (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))
|| ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
|| !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri)))) {
/* Overlap dialing is enabled and we need more digits to match an extension. */
return SIP_GET_DEST_EXTEN_MATCHMORE;
}
return SIP_GET_DEST_EXTEN_NOT_FOUND;
@ -17150,6 +17165,19 @@ static const char *insecure2str(int mode)
return map_x_s(insecurestr, mode, "<error>");
}
static const struct _map_x_s allowoverlapstr[] = {
{ SIP_PAGE2_ALLOWOVERLAP_YES, "Yes" },
{ SIP_PAGE2_ALLOWOVERLAP_DTMF, "DTMF" },
{ SIP_PAGE2_ALLOWOVERLAP_NO, "No" },
{ -1, NULL }, /* terminator */
};
/*! \brief Convert AllowOverlap setting to printable string */
static const char *allowoverlap2str(int mode)
{
return map_x_s(allowoverlapstr, mode, "<error>");
}
/*! \brief Destroy disused contexts between reloads
Only used in reload_config so the code for regcontext doesn't get ugly
*/
@ -17696,7 +17724,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
ast_cli(fd, " Trust RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID)));
ast_cli(fd, " Send RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID)));
ast_cli(fd, " Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
ast_cli(fd, " Overlap dial : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP)));
ast_cli(fd, " Overlap dial : %s\n", allowoverlap2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP)));
if (peer->outboundproxy)
ast_cli(fd, " Outb. proxy : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name,
peer->outboundproxy->force ? "(forced)" : "");
@ -18253,7 +18281,7 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
ast_cli(a->fd, " Match Auth Username: %s\n", AST_CLI_YESNO(global_match_auth_username));
ast_cli(a->fd, " Allow unknown access: %s\n", AST_CLI_YESNO(sip_cfg.allowguest));
ast_cli(a->fd, " Allow subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
ast_cli(a->fd, " Allow overlap dialing: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)));
ast_cli(a->fd, " Allow overlap dialing: %s\n", allowoverlap2str(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)));
ast_cli(a->fd, " Allow promisc. redir: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR)));
ast_cli(a->fd, " Enable call counters: %s\n", AST_CLI_YESNO(global_callcounter));
ast_cli(a->fd, " SIP domain support: %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list)));
@ -21546,10 +21574,13 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
break;
case 484: /* Address Incomplete */
if (owner && sipmethod != SIP_BYE) {
if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
case SIP_PAGE2_ALLOWOVERLAP_YES:
ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp));
} else {
break;
default:
ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(404));
break;
}
}
break;
@ -22262,7 +22293,7 @@ static int handle_request_options(struct sip_pvt *p, struct sip_request *req, st
case SIP_GET_DEST_INVALID_URI:
msg = "416 Unsupported URI scheme";
break;
case SIP_GET_DEST_PICKUP_EXTEN_FOUND:
case SIP_GET_DEST_EXTEN_MATCHMORE:
case SIP_GET_DEST_REFUSED:
case SIP_GET_DEST_EXTEN_NOT_FOUND:
//msg = "404 Not Found";
@ -22983,12 +23014,21 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
case SIP_GET_DEST_INVALID_URI:
transmit_response_reliable(p, "416 Unsupported URI scheme", req);
break;
case SIP_GET_DEST_PICKUP_EXTEN_FOUND:
if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
case SIP_GET_DEST_EXTEN_MATCHMORE:
if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)
== SIP_PAGE2_ALLOWOVERLAP_YES) {
transmit_response_reliable(p, "484 Address Incomplete", req);
break;
}
/* INTENTIONAL FALL THROUGH */
/*
* XXX We would have to implement collecting more digits in
* chan_sip for any other schemes of overlap dialing.
*
* For SIP_PAGE2_ALLOWOVERLAP_DTMF it is better to do this in
* the dialplan using the Incomplete application rather than
* having the channel driver do it.
*/
/* Fall through */
case SIP_GET_DEST_EXTEN_NOT_FOUND:
case SIP_GET_DEST_REFUSED:
default:
@ -27244,7 +27284,12 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask
res = 1;
} else if (!strcasecmp(v->name, "allowoverlap")) {
ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
ast_clear_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP);
if (ast_true(v->value)) {
ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_YES);
} else if (!strcasecmp(v->value, "dtmf")){
ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_DTMF);
}
} else if (!strcasecmp(v->name, "allowsubscribe")) {
ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
@ -28459,6 +28504,7 @@ static int reload_config(enum channelreloadreason reason)
sipdebug &= sip_debug_console;
ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
ast_clear_flag(&global_flags[2], AST_FLAGS_ALL);
/* Reset IP addresses */
ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
@ -28534,7 +28580,7 @@ static int reload_config(enum channelreloadreason reason)
sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */
sip_cfg.rtautoclear = 120;
ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for all devices: TRUE */
ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for all devices: TRUE */
ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */
sip_cfg.peer_rtupdate = TRUE;
global_dynamic_exclude_static = 0; /* Exclude static peers */
sip_cfg.tcp_enabled = FALSE;

@ -316,33 +316,39 @@
#define SIP_PAGE2_VIDEOSUPPORT (1 << 10) /*!< DP: Video supported if offered? */
#define SIP_PAGE2_TEXTSUPPORT (1 << 11) /*!< GDP: Global text enable */
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 12) /*!< GP: Allow subscriptions from this peer? */
#define SIP_PAGE2_ALLOWOVERLAP (1 << 13) /*!< DP: Allow overlap dialing ? */
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 14) /*!< GP: Only issue MWI notification if subscribed to */
#define SIP_PAGE2_IGNORESDPVERSION (1 << 15) /*!< GDP: Ignore the SDP session version number we receive and treat all sessions as new */
#define SIP_PAGE2_T38SUPPORT (3 << 16) /*!< GDP: T.38 Fax Support */
#define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 16) /*!< GDP: T.38 Fax Support (no error correction) */
#define SIP_PAGE2_T38SUPPORT_UDPTL_FEC (2 << 16) /*!< GDP: T.38 Fax Support (FEC error correction) */
#define SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY (3 << 16) /*!< GDP: T.38 Fax Support (redundancy error correction) */
#define SIP_PAGE2_CALL_ONHOLD (3 << 18) /*!< D: Call hold states: */
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 18) /*!< D: Active hold */
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 18) /*!< D: One directional hold */
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 18) /*!< D: Inactive hold */
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 20) /*!< DP: Compensate for buggy RFC2833 implementations */
#define SIP_PAGE2_BUGGY_MWI (1 << 21) /*!< DP: Buggy CISCO MWI fix */
#define SIP_PAGE2_DIALOG_ESTABLISHED (1 << 22) /*!< 29: Has a dialog been established? */
#define SIP_PAGE2_FAX_DETECT (3 << 23) /*!< DP: Fax Detection support */
#define SIP_PAGE2_FAX_DETECT_CNG (1 << 23) /*!< DP: Fax Detection support - detect CNG in audio */
#define SIP_PAGE2_FAX_DETECT_T38 (2 << 23) /*!< DP: Fax Detection support - detect T.38 reinvite from peer */
#define SIP_PAGE2_FAX_DETECT_BOTH (3 << 23) /*!< DP: Fax Detection support - detect both */
#define SIP_PAGE2_UDPTL_DESTINATION (1 << 25) /*!< DP: Use source IP of RTP as destination if NAT is enabled */
#define SIP_PAGE2_VIDEOSUPPORT_ALWAYS (1 << 26) /*!< DP: Always set up video, even if endpoints don't support it */
#define SIP_PAGE2_HAVEPEERCONTEXT (1 << 27) /*< Are we associated with a configured peer context? */
#define SIP_PAGE2_USE_SRTP (1 << 28) /*!< DP: Whether we should offer (only) SRTP */
#define SIP_PAGE2_ALLOWOVERLAP (3 << 13) /*!< DP: Allow overlap dialing ? */
#define SIP_PAGE2_ALLOWOVERLAP_NO (0 << 13) /*!< No, terminate with 404 Not found */
#define SIP_PAGE2_ALLOWOVERLAP_YES (1 << 13) /*!< Yes, using the 484 Address Incomplete response */
#define SIP_PAGE2_ALLOWOVERLAP_DTMF (2 << 13) /*!< Yes, using the DTMF transmission through Early Media */
#define SIP_PAGE2_ALLOWOVERLAP_SPARE (3 << 13) /*!< Spare (reserved for another dialling transmission mechanisms like KPML) */
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 15) /*!< GP: Only issue MWI notification if subscribed to */
#define SIP_PAGE2_IGNORESDPVERSION (1 << 16) /*!< GDP: Ignore the SDP session version number we receive and treat all sessions as new */
#define SIP_PAGE2_T38SUPPORT (3 << 17) /*!< GDP: T.38 Fax Support */
#define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 17) /*!< GDP: T.38 Fax Support (no error correction) */
#define SIP_PAGE2_T38SUPPORT_UDPTL_FEC (2 << 17) /*!< GDP: T.38 Fax Support (FEC error correction) */
#define SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY (3 << 17) /*!< GDP: T.38 Fax Support (redundancy error correction) */
#define SIP_PAGE2_CALL_ONHOLD (3 << 19) /*!< D: Call hold states: */
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 19) /*!< D: Active hold */
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 19) /*!< D: One directional hold */
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 19) /*!< D: Inactive hold */
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 21) /*!< DP: Compensate for buggy RFC2833 implementations */
#define SIP_PAGE2_BUGGY_MWI (1 << 22) /*!< DP: Buggy CISCO MWI fix */
#define SIP_PAGE2_DIALOG_ESTABLISHED (1 << 23) /*!< 29: Has a dialog been established? */
#define SIP_PAGE2_FAX_DETECT (3 << 24) /*!< DP: Fax Detection support */
#define SIP_PAGE2_FAX_DETECT_CNG (1 << 24) /*!< DP: Fax Detection support - detect CNG in audio */
#define SIP_PAGE2_FAX_DETECT_T38 (2 << 24) /*!< DP: Fax Detection support - detect T.38 reinvite from peer */
#define SIP_PAGE2_FAX_DETECT_BOTH (3 << 24) /*!< DP: Fax Detection support - detect both */
#define SIP_PAGE2_UDPTL_DESTINATION (1 << 26) /*!< DP: Use source IP of RTP as destination if NAT is enabled */
#define SIP_PAGE2_VIDEOSUPPORT_ALWAYS (1 << 27) /*!< DP: Always set up video, even if endpoints don't support it */
#define SIP_PAGE2_HAVEPEERCONTEXT (1 << 28) /*< Are we associated with a configured peer context? */
#define SIP_PAGE2_USE_SRTP (1 << 29) /*!< DP: Whether we should offer (only) SRTP */
#define SIP_PAGE2_FLAGS_TO_COPY \
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_IGNORESDPVERSION | \
@ -466,7 +472,7 @@ enum sip_auth_type {
/*! \brief Result from get_destination function */
enum sip_get_dest_result {
SIP_GET_DEST_PICKUP_EXTEN_FOUND = 1,
SIP_GET_DEST_EXTEN_MATCHMORE = 1,
SIP_GET_DEST_EXTEN_FOUND = 0,
SIP_GET_DEST_EXTEN_NOT_FOUND = -1,
SIP_GET_DEST_REFUSED = -2,

@ -122,6 +122,13 @@ context=default ; Default context for incoming calls
; 'username' field from the authentication line
; instead of the From: field.
allowoverlap=no ; Disable overlap dialing support. (Default is yes)
;allowoverlap=yes ; Enable RFC3578 overlap dialing support.
; Can use the Incomplete application to collect the
; needed digits from an ambiguous dialplan match.
;allowoverlap=dtmf ; Enable overlap dialing support using DTMF delivery
; methods (inband, RFC2833, SIP INFO) in the early
; media phase. Uses the Incomplete application to
; collect the needed digits.
;allowtransfer=no ; Disable all transfers (unless enabled in peers or users)
; Default is enabled. The Dial() options 't' and 'T' are not
; related as to whether SIP transfers are allowed or not.

Loading…
Cancel
Save