From d92b2f375435748f82ad6d4788f3cbcf0ed7cd47 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 12 Jul 2013 22:35:50 +0000 Subject: Fix a longstanding issue with MFC-R2 configuration that prevented users from mixing different variants or general MFC-R2 settings within the same E1 line. Most users do not have a problem with this since MFC-R2 lines are usually fractional E1s, or the whole E1 has the same country variant and R2 settings. In Venezuela however is common to have inbound MFC-R2 and outbound DTMF-R2 within the same E1. This fix now properly parses the chan_dahdi.conf file to generate a new openr2 context every time a new channel => section is found and the configuration was changed. (closes issue ASTERISK-21117) Reported by: Rafael Angulo Related Elastix issue: http://bugs.elastix.org/view.php?id=1612 ........ Merged revisions 394106 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 394173 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@394263 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_dahdi.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'channels/chan_dahdi.c') diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 8cabc79c8..28fd65f4d 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -652,14 +652,6 @@ static int cur_defaultdpc = -1; #endif /* defined(HAVE_SS7) */ #ifdef HAVE_OPENR2 -struct dahdi_mfcr2 { - pthread_t r2master; /*!< Thread of master */ - openr2_context_t *protocol_context; /*!< OpenR2 context handle */ - struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */ - int numchans; /*!< Number of channels in this R2 block */ - int monitored_count; /*!< Number of channels being monitored */ -}; - struct dahdi_mfcr2_conf { openr2_variant_t variant; int mfback_timeout; @@ -694,6 +686,15 @@ struct dahdi_mfcr2_conf { openr2_calling_party_category_t category; }; +/* MFC-R2 pseudo-link structure */ +struct dahdi_mfcr2 { + pthread_t r2master; /*!< Thread of master */ + openr2_context_t *protocol_context; /*!< OpenR2 context handle */ + struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */ + int numchans; /*!< Number of channels in this R2 block */ + struct dahdi_mfcr2_conf conf; /*!< Configuration used to setup this pseudo-link */ +}; + /* malloc'd array of malloc'd r2links */ static struct dahdi_mfcr2 **r2links; /* how many r2links have been malloc'd */ @@ -12588,14 +12589,20 @@ static void dahdi_r2_destroy_links(void) r2links_count = 0; } -#define R2_LINK_CAPACITY 10 -static struct dahdi_mfcr2 *dahdi_r2_get_link(void) +/* This is an artificial convenient capacity, to keep at most a full E1 of channels in a single thread */ +#define R2_LINK_CAPACITY 30 +static struct dahdi_mfcr2 *dahdi_r2_get_link(const struct dahdi_chan_conf *conf) { struct dahdi_mfcr2 *new_r2link = NULL; struct dahdi_mfcr2 **new_r2links = NULL; - /* this function is called just when starting up and no monitor threads have been launched, - no need to lock monitored_count member */ - if (!r2links_count || (r2links[r2links_count - 1]->monitored_count == R2_LINK_CAPACITY)) { + + /* Only create a new R2 link if + 1. This is the first link requested + 2. Configuration changed + 3. We got more channels than supported per link */ + if (!r2links_count || + memcmp(&conf->mfcr2, &r2links[r2links_count - 1]->conf, sizeof(conf->mfcr2)) || + (r2links[r2links_count - 1]->numchans == R2_LINK_CAPACITY)) { new_r2link = ast_calloc(1, sizeof(**r2links)); if (!new_r2link) { ast_log(LOG_ERROR, "Cannot allocate R2 link!\n"); @@ -12667,7 +12674,8 @@ static int dahdi_r2_set_context(struct dahdi_mfcr2 *r2_link, const struct dahdi_ ast_log(LOG_ERROR, "Failed to configure r2context from advanced configuration file %s\n", conf->mfcr2.r2proto_file); } } - r2_link->monitored_count = 0; + /* Save the configuration used to setup this link */ + memcpy(&r2_link->conf, conf, sizeof(r2_link->conf)); return 0; } #endif @@ -12898,7 +12906,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, #ifdef HAVE_OPENR2 if (chan_sig == SIG_MFCR2) { struct dahdi_mfcr2 *r2_link; - r2_link = dahdi_r2_get_link(); + r2_link = dahdi_r2_get_link(conf); if (!r2_link) { ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n"); destroy_dahdi_pvt(tmp); @@ -12940,7 +12948,6 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, tmp->mfcr2call = 0; tmp->mfcr2_dnis_index = 0; tmp->mfcr2_ani_index = 0; - r2_link->monitored_count++; } #endif #ifdef HAVE_PRI -- cgit v1.2.3