chan_dahdi/sig_pri: Prevent unnecessary PROGRESS events when overlap dialing is enabled.

When overlap dialing is enabled, the lack of inband audio available
information in the SETUP_ACKNOWLEDGE events causes an interoperability
problem with SIP.  sig_pri doesn't know if there is dialtone present when
a SETUP_ACKNOWLEDGE is received so it assumes it is there and posts an
AST_CONTROL_PROGRESS frame.  The SIP channel driver then sends out a 183
Session Progress and blocks the desired 180 Ringing message when the
ALERTING message comes in.

* Made the configure script detect if the installed version of libpri
supports the SETUP_ACKNOWLEDGE enhancements.

* Using the new API, made generate an AST_CONTROL_PROGRESS frame on an
incoming SETUP_ACKNOWLEDGE message when the message indicates inband audio
is present instead of assuming that dialtone is present.

* Using the new API, made SETUP_ACKNOWLEDGE send out an inband audio
available indication only if dialtone is expected.  The change also makes
the fallback behaviour of sending the PROGRESS message better by sending
it only if dialtone is expected.

* Changed receiving a PROCEEDING message to not generate an
AST_CONTROL_PROGRESS frame if the progress indication ie indicates
non-end-to-end-ISDN.  This helps interoperability with SIP.

* Changed sending a PROCEEDING message in response to an
AST_CONTROL_PROCEEDING frame to not indicate inband audio available.  It
was silly to do so anyway because the channel driver doesn't know if
inband audio is even available.  This helps interoperability with SIP.

This patch and a corresponding change in libpri work together to allow
Asterisk to control the inband audio available progress indication ie on
the SETUP_ACKNOWLEDGE message when dialtone is present.

AST-1338 #close
Reported by: Tyler Stewart

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

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

Merged revisions 413765 from http://svn.asterisk.org/svn/asterisk/branches/11
........

Merged revisions 413771 from http://svn.asterisk.org/svn/asterisk/branches/12


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@413772 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Richard Mudgett
2014-05-13 00:35:31 +00:00
parent 552dbe531e
commit 8b6ab4782a
4 changed files with 432 additions and 280 deletions

View File

@@ -2137,10 +2137,10 @@ static void *pri_ss_thread(void *data)
/* Start the real PBX */ /* Start the real PBX */
ast_channel_exten_set(chan, exten); ast_channel_exten_set(chan, exten);
sig_pri_dsp_reset_and_flush_digits(p); sig_pri_dsp_reset_and_flush_digits(p);
#if defined(ISSUE_16789) #if defined(JIRA_ASTERISK_15594)
/* /*
* Conditionaled out this code to effectively revert the Mantis * Conditionaled out this code to effectively revert the JIRA
* issue 16789 change. It breaks overlap dialing through * ASTERISK-15594 change. It breaks overlap dialing through
* Asterisk. There is not enough information available at this * Asterisk. There is not enough information available at this
* point to know if dialing is complete. The * point to know if dialing is complete. The
* ast_exists_extension(), ast_matchmore_extension(), and * ast_exists_extension(), ast_matchmore_extension(), and
@@ -2163,7 +2163,7 @@ static void *pri_ss_thread(void *data)
} }
sig_pri_unlock_private(p); sig_pri_unlock_private(p);
} }
#endif /* defined(ISSUE_16789) */ #endif /* defined(JIRA_ASTERISK_15594) */
sig_pri_set_echocanceller(p, 1); sig_pri_set_echocanceller(p, 1);
ast_channel_lock(chan); ast_channel_lock(chan);
@@ -6435,6 +6435,9 @@ static void *pri_dchannel(void *vpri)
/* Make sure extension exists (or in overlap dial mode, can exist) */ /* Make sure extension exists (or in overlap dial mode, can exist) */
if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) || if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
int could_match_more;
int need_dialtone;
/* Select audio companding mode. */ /* Select audio companding mode. */
switch (e->ring.layer1) { switch (e->ring.layer1) {
case PRI_LAYER_1_ALAW: case PRI_LAYER_1_ALAW:
@@ -6449,6 +6452,23 @@ static void *pri_dchannel(void *vpri)
break; break;
} }
could_match_more = !e->ring.complete
&& (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
&& ast_matchmore_extension(NULL, pri->pvts[chanpos]->context,
pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num);
need_dialtone = could_match_more
/*
* Must explicitly check the digital capability this
* way instead of checking the pvt->digital flag
* because the flag hasn't been set yet.
*/
&& !(e->ring.ctype & AST_TRANS_CAP_DIGITAL)
&& !pri->pvts[chanpos]->no_b_channel
&& (!strlen(pri->pvts[chanpos]->exten)
|| ast_ignore_pattern(pri->pvts[chanpos]->context,
pri->pvts[chanpos]->exten));
if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
/* Just announce proceeding */ /* Just announce proceeding */
pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
@@ -6458,13 +6478,17 @@ static void *pri_dchannel(void *vpri)
pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
} else { } else {
pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP; pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP;
pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); #if defined(HAVE_PRI_SETUP_ACK_INBAND)
pri_setup_ack(pri->pri, e->ring.call,
PVT_TO_CHANNEL(pri->pvts[chanpos]), 1, need_dialtone);
#else /* !defined(HAVE_PRI_SETUP_ACK_INBAND) */
pri_need_more_info(pri->pri, e->ring.call,
PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
#endif /* !defined(HAVE_PRI_SETUP_ACK_INBAND) */
} }
/* Start PBX */ /* Start PBX */
if (!e->ring.complete if (could_match_more) {
&& (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
&& ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
/* /*
* Release the PRI lock while we create the channel so other * Release the PRI lock while we create the channel so other
* threads can send D channel messages. We must also release * threads can send D channel messages. We must also release
@@ -6549,12 +6573,9 @@ static void *pri_dchannel(void *vpri)
sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds, sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds,
e->ring.call); e->ring.call);
if (!pri->pvts[chanpos]->digital #if !defined(HAVE_PRI_SETUP_ACK_INBAND)
&& !pri->pvts[chanpos]->no_b_channel) { if (need_dialtone) {
/* /* Indicate that we are providing dialtone. */
* Call has a channel.
* Indicate that we are providing dialtone.
*/
pri->pvts[chanpos]->progress = 1;/* No need to send plain PROGRESS again. */ pri->pvts[chanpos]->progress = 1;/* No need to send plain PROGRESS again. */
#ifdef HAVE_PRI_PROG_W_CAUSE #ifdef HAVE_PRI_PROG_W_CAUSE
pri_progress_with_cause(pri->pri, e->ring.call, pri_progress_with_cause(pri->pri, e->ring.call,
@@ -6564,6 +6585,7 @@ static void *pri_dchannel(void *vpri)
PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
#endif #endif
} }
#endif /* !defined(HAVE_PRI_SETUP_ACK_INBAND) */
ast_channel_stage_snapshot_done(c); ast_channel_stage_snapshot_done(c);
} }
if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) { if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) {
@@ -6866,8 +6888,15 @@ static void *pri_dchannel(void *vpri)
if (!pri->pvts[chanpos]->progress if (!pri->pvts[chanpos]->progress
&& !pri->pvts[chanpos]->no_b_channel && !pri->pvts[chanpos]->no_b_channel
#ifdef PRI_PROGRESS_MASK #ifdef PRI_PROGRESS_MASK
&& (e->proceeding.progressmask /*
& (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE)) * We only care about PRI_PROG_INBAND_AVAILABLE to open the
* voice path.
*
* We explicitly DO NOT want to check PRI_PROG_CALL_NOT_E2E_ISDN
* because it will mess up ISDN to SIP interoperability for
* the ALERTING message.
*/
&& (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
#else #else
&& e->proceeding.progress == 8 && e->proceeding.progress == 8
#endif #endif
@@ -6878,6 +6907,12 @@ static void *pri_dchannel(void *vpri)
sig_pri_set_dialing(pri->pvts[chanpos], 0); sig_pri_set_dialing(pri->pvts[chanpos], 0);
sig_pri_open_media(pri->pvts[chanpos]); sig_pri_open_media(pri->pvts[chanpos]);
} else if (pri->inband_on_proceeding) { } else if (pri->inband_on_proceeding) {
/*
* XXX This is to accomodate a broken switch that sends a
* PROCEEDING without any progress indication ie for
* inband audio. This should be part of the conditional
* test above to bring the voice path up.
*/
sig_pri_set_dialing(pri->pvts[chanpos], 0); sig_pri_set_dialing(pri->pvts[chanpos], 0);
} }
sig_pri_unlock_private(pri->pvts[chanpos]); sig_pri_unlock_private(pri->pvts[chanpos]);
@@ -7496,7 +7531,19 @@ static void *pri_dchannel(void *vpri)
if (!pri->pvts[chanpos]->progress if (!pri->pvts[chanpos]->progress
&& (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) && (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)
&& !pri->pvts[chanpos]->digital && !pri->pvts[chanpos]->digital
&& !pri->pvts[chanpos]->no_b_channel) { && !pri->pvts[chanpos]->no_b_channel
#if defined(HAVE_PRI_SETUP_ACK_INBAND)
/*
* We only care about PRI_PROG_INBAND_AVAILABLE to open the
* voice path.
*
* We explicitly DO NOT want to check PRI_PROG_CALL_NOT_E2E_ISDN
* because it will mess up ISDN to SIP interoperability for
* the ALERTING message.
*/
&& (e->setup_ack.progressmask & PRI_PROG_INBAND_AVAILABLE)
#endif /* defined(HAVE_PRI_SETUP_ACK_INBAND) */
) {
/* /*
* Call has a channel. * Call has a channel.
* Indicate for overlap dialing that dialtone may be present. * Indicate for overlap dialing that dialtone may be present.
@@ -8374,11 +8421,7 @@ int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condi
p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
if (p->pri && p->pri->pri) { if (p->pri && p->pri->pri) {
pri_grab(p, p->pri); pri_grab(p, p->pri);
pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 0);
p->no_b_channel || p->digital ? 0 : 1);
if (!p->no_b_channel && !p->digital) {
sig_pri_set_dialing(p, 0);
}
pri_rel(p->pri); pri_rel(p->pri);
} }
} }

614
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -437,6 +437,7 @@ AST_EXT_LIB_SETUP_OPTIONAL([PJ_TRANSACTION_GRP_LOCK], [PJSIP Transaction Group L
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_REPLACE_MEDIA_STREAM], [PJSIP Media Stream Replacement Support], [PJPROJECT], [pjsip]) AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_REPLACE_MEDIA_STREAM], [PJSIP Media Stream Replacement Support], [PJPROJECT], [pjsip])
AST_EXT_LIB_SETUP([PORTAUDIO], [PortAudio], [portaudio]) AST_EXT_LIB_SETUP([PORTAUDIO], [PortAudio], [portaudio])
AST_EXT_LIB_SETUP([PRI], [ISDN PRI], [pri]) AST_EXT_LIB_SETUP([PRI], [ISDN PRI], [pri])
AST_EXT_LIB_SETUP_OPTIONAL([PRI_SETUP_ACK_INBAND], [ISDN PRI progress inband ie in SETUP ACK], [PRI], [pri])
AST_EXT_LIB_SETUP_OPTIONAL([PRI_L2_PERSISTENCE], [ISDN Layer 2 persistence option], [PRI], [pri]) AST_EXT_LIB_SETUP_OPTIONAL([PRI_L2_PERSISTENCE], [ISDN Layer 2 persistence option], [PRI], [pri])
AST_EXT_LIB_SETUP_OPTIONAL([PRI_DATETIME_SEND], [ISDN PRI Date/time ie send policy], [PRI], [pri]) AST_EXT_LIB_SETUP_OPTIONAL([PRI_DATETIME_SEND], [ISDN PRI Date/time ie send policy], [PRI], [pri])
AST_EXT_LIB_SETUP_OPTIONAL([PRI_MWI_V2], [ISDN PRI Message Waiting Indication (Fixed)], [PRI], [pri]) AST_EXT_LIB_SETUP_OPTIONAL([PRI_MWI_V2], [ISDN PRI Message Waiting Indication (Fixed)], [PRI], [pri])
@@ -2048,6 +2049,7 @@ AST_EXT_LIB_CHECK([POPT], [popt], [poptStrerror], [popt.h])
AST_EXT_LIB_CHECK([PORTAUDIO], [portaudio], [Pa_GetDeviceCount], [portaudio.h]) AST_EXT_LIB_CHECK([PORTAUDIO], [portaudio], [Pa_GetDeviceCount], [portaudio.h])
AST_EXT_LIB_CHECK([PRI], [pri], [pri_connected_line_update], [libpri.h]) AST_EXT_LIB_CHECK([PRI], [pri], [pri_connected_line_update], [libpri.h])
AST_EXT_LIB_CHECK([PRI_SETUP_ACK_INBAND], [pri], [pri_setup_ack], [libpri.h])
AST_EXT_LIB_CHECK([PRI_L2_PERSISTENCE], [pri], [pri_persistent_layer2_option], [libpri.h]) AST_EXT_LIB_CHECK([PRI_L2_PERSISTENCE], [pri], [pri_persistent_layer2_option], [libpri.h])
AST_EXT_LIB_CHECK([PRI_DATETIME_SEND], [pri], [pri_date_time_send_option], [libpri.h]) AST_EXT_LIB_CHECK([PRI_DATETIME_SEND], [pri], [pri_date_time_send_option], [libpri.h])
AST_EXT_LIB_CHECK([PRI_MWI_V2], [pri], [pri_mwi_indicate_v2], [libpri.h]) AST_EXT_LIB_CHECK([PRI_MWI_V2], [pri], [pri_mwi_indicate_v2], [libpri.h])

View File

@@ -654,6 +654,10 @@
/* Define to 1 if PRI has the ISDN service messages feature. */ /* Define to 1 if PRI has the ISDN service messages feature. */
#undef HAVE_PRI_SERVICE_MESSAGES #undef HAVE_PRI_SERVICE_MESSAGES
/* Define to 1 if PRI has the ISDN PRI progress inband ie in SETUP ACK
feature. */
#undef HAVE_PRI_SETUP_ACK_INBAND
/* Define to 1 if PRI has the ISDN PRI keypad facility in SETUP feature. */ /* Define to 1 if PRI has the ISDN PRI keypad facility in SETUP feature. */
#undef HAVE_PRI_SETUP_KEYPAD #undef HAVE_PRI_SETUP_KEYPAD
@@ -1282,11 +1286,6 @@
/* Define to 1 if running on Darwin. */ /* Define to 1 if running on Darwin. */
#undef _DARWIN_UNLIMITED_SELECT #undef _DARWIN_UNLIMITED_SELECT
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */ /* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS #undef _FILE_OFFSET_BITS