Fix problem on digital channels due to digital flag not getting set
authorJeff Peeler <jpeeler@digium.com>
Tue, 24 Nov 2009 17:12:25 +0000 (17:12 +0000)
committerJeff Peeler <jpeeler@digium.com>
Tue, 24 Nov 2009 17:12:25 +0000 (17:12 +0000)
Changed areas in sig_pri to set the digital flag using a callback that will
also set the corresponding flag in chan_dahdi. Modified dahdi_request slightly
so that if a bearer is marked as digital, that information is available when
creating the new channel.

(closes issue #16151)
Reported by: alecdavis
Patch based on bug_16151.diff.txt uploaded by alecdavis (license 585)

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

channels/chan_dahdi.c
channels/sig_pri.c
channels/sig_pri.h

index e71f2ed..0da2ded 100644 (file)
@@ -2069,6 +2069,14 @@ static void my_set_dialing(void *pvt, int flag)
        p->dialing = flag;
 }
 
+#if defined(HAVE_PRI)
+static void my_set_digital(void *pvt, int flag)
+{
+       struct dahdi_pvt *p = pvt;
+       p->digital = flag;
+}
+#endif
+
 static void my_set_ringtimeout(void *pvt, int ringt)
 {
        struct dahdi_pvt *p = pvt;
@@ -2780,6 +2788,7 @@ static struct sig_pri_callback dahdi_pri_callbacks =
        .new_ast_channel = my_new_pri_ast_channel,
        .fixup_chans = my_pri_fixup_chans,
        .set_dialing = my_set_dialing,
+       .set_digital = my_set_digital,
        .set_callerid = my_pri_set_callerid,
        .set_dnid = my_pri_set_dnid,
        .set_rdnis = my_pri_set_rdnis,
@@ -8696,7 +8705,7 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
        tmp->cid.cid_pres = i->callingpres;
        tmp->cid.cid_ton = i->cid_ton;
        tmp->cid.cid_ani2 = i->cid_ani2;
-#if defined(HAVE_PRI) || defined(HAVE_SS7)
+#if defined(HAVE_SS7)
        tmp->transfercapability = transfercapability;
        pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
        if (transfercapability & AST_TRANS_CAP_DIGITAL)
@@ -12009,6 +12018,7 @@ static struct ast_channel *dahdi_request(const char *type, format_t format, cons
        struct dahdi_pvt *exitpvt;
        int channelmatched = 0;
        int groupmatched = 0;
+       int transcapdigital = 0;
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(group);     /* channel/group token */
                //AST_APP_ARG(ext);     /* extension token */
@@ -12124,21 +12134,6 @@ static struct ast_channel *dahdi_request(const char *type, format_t format, cons
                                        break;
                                }
                        }
-                       p->outgoing = 1;
-                       if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
-                               tmp = analog_request(p->sig_pvt, &callwait, requestor);
-#ifdef HAVE_PRI
-                       } else if (dahdi_sig_pri_lib_handles(p->sig)) {
-                               sig_pri_extract_called_num_subaddr(p->sig_pvt, data, p->dnid,
-                                       sizeof(p->dnid));
-                               tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, requestor);
-#endif
-                       } else {
-                               tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0, requestor ? requestor->linkedid : "");
-                       }
-                       if (!tmp) {
-                               p->outgoing = 0;
-                       }
 
                        /* Make special notes */
                        if (res > 1) {
@@ -12153,13 +12148,27 @@ static struct ast_channel *dahdi_request(const char *type, format_t format, cons
                                                p->distinctivering = y;
                                } else if (opt == 'd') {
                                        /* If this is an ISDN call, make it digital */
-                                       p->digital = 1;
-                                       if (tmp)
-                                               tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
+                                       transcapdigital = AST_TRANS_CAP_DIGITAL;
                                } else {
                                        ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
                                }
                        }
+
+                       p->outgoing = 1;
+                       if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
+                               tmp = analog_request(p->sig_pvt, &callwait, requestor);
+#ifdef HAVE_PRI
+                       } else if (dahdi_sig_pri_lib_handles(p->sig)) {
+                               sig_pri_extract_called_num_subaddr(p->sig_pvt, data, p->dnid,
+                                       sizeof(p->dnid));
+                               tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, requestor, transcapdigital);
+#endif
+                       } else {
+                               tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, transcapdigital, requestor ? requestor->linkedid : "");
+                       }
+                       if (!tmp) {
+                               p->outgoing = 0;
+                       }
                        /* Note if the call is a call waiting call */
                        if (tmp && callwait)
                                tmp->cdrflags |= AST_CDR_CALLWAIT;
index 99be5a4..0a285e2 100644 (file)
@@ -113,6 +113,13 @@ static void sig_pri_set_dialing(struct sig_pri_chan *p, int flag)
                p->calls->set_dialing(p->chan_pvt, flag);
 }
 
+static void sig_pri_set_digital(struct sig_pri_chan *p, int flag)
+{
+       p->digital = flag;
+       if (p->calls->set_digital)
+               p->calls->set_digital(p->chan_pvt, flag);
+}
+
 /*!
  * \internal
  * \brief Set the caller id information in the parent module.
@@ -726,18 +733,23 @@ static struct ast_channel *sig_pri_new_ast_channel(struct sig_pri_chan *p, int s
                p->owner = c;
        p->isidlecall = 0;
        p->alreadyhungup = 0;
+       if (transfercapability & AST_TRANS_CAP_DIGITAL) {
+               c->transfercapability = transfercapability;
+               pbx_builtin_setvar_helper(c, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
+               sig_pri_set_digital(p, 1);
+       }
 
        return c;
 }
 
-struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor)
+struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability)
 {
        struct ast_channel *ast;
 
        ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
 
        p->outgoing = 1;
-       ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, 0, law, 0, p->exten, requestor);
+       ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, 0, law, transfercapability, p->exten, requestor);
        if (!ast) {
                p->outgoing = 0;
        }
@@ -1951,7 +1963,7 @@ static void *pri_dchannel(void *vpri)
                                if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
                                        /* Don't create a new idle call more than once per second */
                                        snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
-                                       idle = sig_pri_request(pri->pvts[nextidle], AST_FORMAT_ULAW, NULL);
+                                       idle = sig_pri_request(pri->pvts[nextidle], AST_FORMAT_ULAW, NULL, 0);
                                        if (idle) {
                                                pri->pvts[nextidle]->isidlecall = 1;
                                                if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
@@ -3194,7 +3206,7 @@ int sig_pri_hangup(struct sig_pri_chan *p, struct ast_channel *ast)
 
        p->owner = NULL;
        p->outgoing = 0;
-       p->digital = 0;
+       sig_pri_set_digital(p, 0);      /* push up to parent for EC*/
        p->proceeding = 0;
        p->progress = 0;
        p->alerting = 0;
@@ -3451,7 +3463,7 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, i
                return -1;
        }
 
-       p->digital = IS_DIGITAL(ast->transfercapability);
+       sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability));    /* push up to parent for EC */
 
        /* Should the picked channel be used exclusively? */
        if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
@@ -3742,7 +3754,7 @@ int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condi
                break;
        case AST_CONTROL_PROGRESS:
                ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
-               p->digital = 0; /* Digital-only calls isn't allowing any inband progress messages */
+               sig_pri_set_digital(p, 0);      /* Digital-only calls isn't allowing any inband progress messages */
                if (!p->progress && p->pri && !p->outgoing) {
                        if (p->pri->pri) {
                                if (!pri_grab(p, p->pri)) {
index fa27675..b1b1884 100644 (file)
@@ -72,6 +72,7 @@ struct sig_pri_callback {
        /* Note: Called with PRI lock held */
        void (* const handle_dchan_exception)(struct sig_pri_pri *pri, int index);
        void (* const set_dialing)(void *pvt, int flag);
+       void (* const set_digital)(void *pvt, int flag);
        void (* const set_callerid)(void *pvt, const struct ast_party_caller *caller);
        void (* const set_dnid)(void *pvt, const char *dnid);
        void (* const set_rdnis)(void *pvt, const char *rdnis);
@@ -272,7 +273,7 @@ void pri_event_alarm(struct sig_pri_pri *pri, int index, int before_start_pri);
 
 void pri_event_noalarm(struct sig_pri_pri *pri, int index, int before_start_pri);
 
-struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor);
+struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability);
 
 struct sig_pri_chan *sig_pri_chan_new(void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_pri *pri, int logicalspan, int channo, int trunkgroup);
 void sig_pri_chan_delete(struct sig_pri_chan *doomed);