Prevent deadlock if chan_dahdi attempts to change PRI channel names.
authorRichard Mudgett <rmudgett@digium.com>
Thu, 1 Oct 2009 19:48:58 +0000 (19:48 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 1 Oct 2009 19:48:58 +0000 (19:48 +0000)
The PRI channels can no longer change the channel name if a different B
channel is selected during call negotiation.  To prevent using the channel
name to infer what B channel a call is using and to avoid name collisions,
the channel name format is changed.

The new channel naming for PRI channels is:
DAHDI/ISDN-<span>-<sequence-number>

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@221701 65c4cc65-6c06-0410-ace0-fbb531ad65f3

CHANGES
channels/chan_dahdi.c
channels/sig_pri.h

diff --git a/CHANGES b/CHANGES
index 5062283..96d4be6 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -205,6 +205,12 @@ libpri channel driver (chan_dahdi) DAHDI changes
    LibPRI).
  * Added the ability to ignore calls that are not in a Multiple Subscriber
    Number (MSN) list for PTMP CPE interfaces.
+ * The PRI channels can no longer change the channel name if a different B
+   channel is selected during call negotiation.  To prevent using the channel
+   name to infer what B channel a call is using and to avoid name collisions,
+   the channel name format is changed.
+   The new channel naming for PRI channels is:
+   DAHDI/ISDN-<span>-<sequence-number>
 
 Asterisk Manager Interface
 --------------------------
index c38e253..33d17d6 100644 (file)
@@ -2588,17 +2588,10 @@ static void my_pri_fixup_chans(void *chan_old, void *chan_new)
 {
        struct dahdi_pvt *old_chan = chan_old;
        struct dahdi_pvt *new_chan = chan_new;
-       struct sig_pri_chan *pchan = new_chan->sig_pvt;
-       struct sig_pri_pri *pri = pchan->pri;
 
        new_chan->owner = old_chan->owner;
        old_chan->owner = NULL;
        if (new_chan->owner) {
-               char newname[AST_CHANNEL_NAME];
-
-               snprintf(newname, sizeof(newname), "DAHDI/%d:%d-%d", pri->trunkgroup, new_chan->channel, 1);
-               ast_change_name(new_chan->owner, newname);
-
                new_chan->owner->tech_pvt = new_chan;
                new_chan->owner->fds[0] = new_chan->subs[SUB_REAL].dfd;
                new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner;
@@ -8200,23 +8193,36 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
        struct ast_str *chan_name;
        struct ast_variable *v;
        struct dahdi_params ps;
+
        if (i->subs[idx].owner) {
                ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]);
                return NULL;
        }
-       y = 1;
+
+       /* Create the new channel name tail. */
        chan_name = ast_str_alloca(32);
-       do {
-               if (i->channel == CHAN_PSEUDO)
-                       ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random());
-               else
+       if (i->channel == CHAN_PSEUDO) {
+               ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random());
+#if defined(HAVE_PRI)
+       } else if (i->pri) {
+               ast_mutex_lock(&i->pri->lock);
+               ast_str_set(&chan_name, 0, "ISDN-%d-%d", i->pri->span, ++i->pri->new_chan_seq);
+               ast_mutex_unlock(&i->pri->lock);
+#endif /* defined(HAVE_PRI) */
+       } else {
+               y = 1;
+               do {
                        ast_str_set(&chan_name, 0, "%d-%d", i->channel, y);
-               for (x = 0; x < 3; x++) {
-                       if ((idx != x) && i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name), i->subs[x].owner->name + 6))
-                               break;
-               }
-               y++;
-       } while (x < 3);
+                       for (x = 0; x < 3; ++x) {
+                               if (i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name),
+                                       i->subs[x].owner->name + 6)) {
+                                       break;
+                               }
+                       }
+                       ++y;
+               } while (x < 3);
+       }
+
        tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
        if (!tmp)
                return NULL;
index fb46680..41bd53c 100644 (file)
@@ -211,6 +211,7 @@ struct sig_pri_pri {
        int resetting;                                                  /*!< true if span is being reset/restarted */
        int resetpos;                                                   /*!< current position during a reset (-1 if not started) */
        int sig;                                                                /*!< ISDN signalling type (SIG_PRI, SIG_BRI, SIG_BRI_PTMP, etc...) */
+       int new_chan_seq;                                               /*!< New struct ast_channel sequence number */
 
        /* Everything after here is internally set */
        struct pri *dchans[NUM_DCHANS];                         /*!< Actual d-channels */