From 1900a766f78e4ef82cfe18ce7f28ebb12175d013 Mon Sep 17 00:00:00 2001 From: jpeeler Date: Tue, 24 Nov 2009 17:12:25 +0000 Subject: [PATCH] Fix problem on digital channels due to digital flag not getting set 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: http://svn.digium.com/svn/asterisk/trunk@231058 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_dahdi.c | 47 ++++++++++++++++++++++++++----------------- channels/sig_pri.c | 24 ++++++++++++++++------ channels/sig_pri.h | 3 ++- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index e71f2ed91..0da2ded8c 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -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; diff --git a/channels/sig_pri.c b/channels/sig_pri.c index 99be5a49b..0a285e2e3 100644 --- a/channels/sig_pri.c +++ b/channels/sig_pri.c @@ -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)) { diff --git a/channels/sig_pri.h b/channels/sig_pri.h index fa2767500..b1b1884a4 100644 --- a/channels/sig_pri.h +++ b/channels/sig_pri.h @@ -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);