diff --git a/UPGRADE.txt b/UPGRADE.txt index d0db4dbcadde5f599475f6691425d48b3e48aaf6..9adf3052c27edb28c1fe9286122d9af34bcb9af7 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -40,6 +40,13 @@ CLI: by the CLI command is always the Asterisk version. This CLI command will be removed in Asterisk 14. +chan_dahdi: + - Added the force_restart_unavailable_chans compatibility option. When + enabled it causes Asterisk to restart the ISDN B channel if an outgoing + call receives cause 44 (Requested channel not available). The new option + is enabled by default in current release branches for backward + compatibility. + res_pjsip: - The dtmf_mode now supports a new option, 'auto'. This mode will attempt to detect if the device supports RFC4733 DTMF. If so, it will choose that diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 53899d8699b3acb65a351c06895f95a0cb66ed53..6958e5be540b781b5aabf79332266e7a5b9beb40 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -919,6 +919,7 @@ static struct dahdi_chan_conf dahdi_chan_conf_default(void) .privateprefix = "", .unknownprefix = "", .colp_send = SIG_PRI_COLP_UPDATE, + .force_restart_unavailable_chans = 1, .resetinterval = -1, }, #endif @@ -12346,6 +12347,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, #if defined(HAVE_PRI_MCID) pris[span].pri.mcid_send = conf->pri.pri.mcid_send; #endif /* defined(HAVE_PRI_MCID) */ + pris[span].pri.force_restart_unavailable_chans = conf->pri.pri.force_restart_unavailable_chans; #if defined(HAVE_PRI_DATETIME_SEND) pris[span].pri.datetime_send = conf->pri.pri.datetime_send; #endif /* defined(HAVE_PRI_DATETIME_SEND) */ @@ -18258,6 +18260,8 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct else ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n", v->value, v->lineno); + } else if (!strcasecmp(v->name, "force_restart_unavailable_chans")) { + confp->pri.pri.force_restart_unavailable_chans = ast_true(v->value); } else if (!strcasecmp(v->name, "minunused")) { confp->pri.pri.minunused = atoi(v->value); } else if (!strcasecmp(v->name, "minidle")) { diff --git a/channels/sig_pri.c b/channels/sig_pri.c index 395ae354ce158487ca88d850e061817f9cf66ba3..a66d16b536471c9883445c65dc4d11e789393bda 100644 --- a/channels/sig_pri.c +++ b/channels/sig_pri.c @@ -133,15 +133,6 @@ */ //#define ALWAYS_PICK_CHANNEL 1 -/*! - * Define to force a RESTART on a channel that returns a cause - * code of PRI_CAUSE_REQUESTED_CHAN_UNAVAIL(44). If the cause - * is because of a stuck channel on the peer and the channel is - * always the next channel we pick for an outgoing call then - * this can help. - */ -#define FORCE_RESTART_UNAVAIL_CHANS 1 - #if defined(HAVE_PRI_CCSS) struct sig_pri_cc_agent_prv { /*! Asterisk span D channel control structure. */ @@ -7170,9 +7161,9 @@ static void *pri_dchannel(void *vpri) pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); pri->pvts[chanpos]->call = NULL; } -#if defined(FORCE_RESTART_UNAVAIL_CHANS) if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL && pri->sig != SIG_BRI_PTMP && !pri->resetting + && pri->force_restart_unavailable_chans && pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) { ast_verb(3, "Span %d: Forcing restart of channel %d/%d since channel reported in use\n", @@ -7181,7 +7172,6 @@ static void *pri_dchannel(void *vpri) pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE; pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); } -#endif /* defined(FORCE_RESTART_UNAVAIL_CHANS) */ if (e->hangup.aoc_units > -1) ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); @@ -7319,9 +7309,9 @@ static void *pri_dchannel(void *vpri) pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); pri->pvts[chanpos]->call = NULL; } -#if defined(FORCE_RESTART_UNAVAIL_CHANS) if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL && pri->sig != SIG_BRI_PTMP && !pri->resetting + && pri->force_restart_unavailable_chans && pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) { ast_verb(3, "Span %d: Forcing restart of channel %d/%d since channel reported in use\n", @@ -7330,7 +7320,6 @@ static void *pri_dchannel(void *vpri) pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE; pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); } -#endif /* defined(FORCE_RESTART_UNAVAIL_CHANS) */ #ifdef SUPPORT_USERUSER if (!ast_strlen_zero(e->hangup.useruserinfo)) { diff --git a/channels/sig_pri.h b/channels/sig_pri.h index 12f3dcae70aad8af002d44048990cea390cdbe52..52e6c729db109fd15b322cf6a8305b1f3a9791ed 100644 --- a/channels/sig_pri.h +++ b/channels/sig_pri.h @@ -496,6 +496,8 @@ struct sig_pri_span { #if defined(HAVE_PRI_MCID) /*! \brief TRUE if allow sending MCID request on this span. */ unsigned int mcid_send:1; + /*! \brief TRUE if forcing RESTART when receive cause 44 on this span. */ + unsigned int force_restart_unavailable_chans:1; #endif /* defined(HAVE_PRI_MCID) */ #if defined(HAVE_PRI_DATETIME_SEND) /*! \brief Configured date/time ie send policy option. */ diff --git a/configs/samples/chan_dahdi.conf.sample b/configs/samples/chan_dahdi.conf.sample index 13691fcdf231e8c664fe5e37648f1a69bdd479d2..e027e64fac2e73317f9f4dcc2b129fee5d4a0926 100644 --- a/configs/samples/chan_dahdi.conf.sample +++ b/configs/samples/chan_dahdi.conf.sample @@ -196,6 +196,20 @@ context=public ; ;resetinterval = 3600 ; +; Enable per span to force a RESTART on a channel that returns a cause +; code of PRI_CAUSE_REQUESTED_CHAN_UNAVAIL(44). If the cause is because +; of a stuck channel on the peer and the channel is always the next +; channel we pick for an outgoing call then this might help. +; +; NOTE: Sending a RESTART in response to a cause 44 is not required +; (nor prohibited) by the standards and is likely a primitive chan_dahdi +; response to call collisions (glare) and buggy peers. However, there +; are telco switches out there that ignore the RESTART and continue to +; send calls to the channel in the restarting state. +; Default yes in current release branches for backward compatibility. +; +;force_restart_unavailable_chans=yes +; ; Assume inband audio may be present when a SETUP ACK message is received. ; Q.931 Section 5.1.3 says that in scenarios with overlap dialing, when a ; dialtone is sent from the network side, progress indicator 8 "Inband info