diff options
author | Richard Mudgett <rmudgett@digium.com> | 2011-04-04 16:17:58 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2011-04-04 16:17:58 +0000 |
commit | e1ceb52b5148d23ebeed76380944406c1b551d22 (patch) | |
tree | 2793f9493a7082ff514a1f21a57455203e9bdad6 /channels/chan_dahdi.c | |
parent | 6826b083ec4602637e367e41944946580888a1ee (diff) |
Merged revisions 312575 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8
................
r312575 | rmudgett | 2011-04-04 11:10:50 -0500 (Mon, 04 Apr 2011) | 52 lines
Merged revisions 312574 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
................
r312574 | rmudgett | 2011-04-04 11:00:02 -0500 (Mon, 04 Apr 2011) | 45 lines
Merged revisions 312573 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r312573 | rmudgett | 2011-04-04 10:49:30 -0500 (Mon, 04 Apr 2011) | 38 lines
Issues with ISDN calls changing B channels during call negotiations.
The handling of the PROCEEDING message was not using the correct call
structure if the B channel was changed. (The same for PROGRESS.) The call
was also not hungup if the new B channel is not provisioned or is busy.
* Made all call connection messages (SETUP_ACKNOWLEDGE, PROCEEDING,
PROGRESS, ALERTING, CONNECT, CONNECT_ACKNOWLEDGE) ensure that they are
using the correct structure and B channel. If there is any problem with
the operations then the call is now hungup with an appropriate cause code.
* Made miscellaneous messages (INFORMATION, FACILITY, NOTIFY) find the
correct structure by looking for the call and not using the channel ID.
NOTIFY is an exception with versions of libpri before v1.4.11 because a
call pointer is not available for Asterisk to use.
* Made all hangup messages (DISCONNECT, RELEASE, RELEASE_COMPLETE) find
the correct structure by looking for the call and not using the channel
ID.
(closes issue #18313)
Reported by: destiny6628
Tested by: rmudgett
JIRA SWP-2620
(closes issue #18231)
Reported by: destiny6628
Tested by: rmudgett
JIRA SWP-2924
(closes issue #18488)
Reported by: jpokorny
JIRA SWP-2929
JIRA AST-437 (The issues fixed here are most likely causing this JIRA issue.)
JIRA DAHDI-406
JIRA LIBPRI-33 (Stuck resetting flag likely fixed)
........
................
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@312579 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_dahdi.c')
-rw-r--r-- | channels/chan_dahdi.c | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 3f1d9e051..e1c4a26bc 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -3238,12 +3238,7 @@ static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri) if (pri->pvts[idx] && !pri->pvts[idx]->no_b_channel) { /* This is a B channel interface. */ ++num_b_chans; - if (pri->pvts[idx]->owner -#if defined(HAVE_PRI_SERVICE_MESSAGES) - /* Out-of-service B channels are "in-use". */ - || pri->pvts[idx]->service_status -#endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ - ) { + if (!sig_pri_is_chan_available(pri->pvts[idx])) { ++in_use; } if (!pri->pvts[idx]->inalarm) { @@ -6458,11 +6453,9 @@ hangup_out: p->cidspill = NULL; ast_mutex_unlock(&p->lock); - ast_module_unref(ast_module_info->self); ast_verb(3, "Hungup '%s'\n", ast->name); ast_mutex_lock(&iflock); - if (p->restartpending) { num_restart_pending--; } @@ -6471,6 +6464,8 @@ hangup_out: destroy_channel(p, 0); } ast_mutex_unlock(&iflock); + + ast_module_unref(ast_module_info->self); return 0; } @@ -8771,14 +8766,27 @@ static struct ast_frame *dahdi_exception(struct ast_channel *ast) static struct ast_frame *dahdi_read(struct ast_channel *ast) { - struct dahdi_pvt *p = ast->tech_pvt; + struct dahdi_pvt *p; int res; int idx; void *readbuf; struct ast_frame *f; + /* + * For analog channels, we must do deadlock avoidance because + * analog ports can have more than one Asterisk channel using + * the same private structure. + */ + p = ast->tech_pvt; while (ast_mutex_trylock(&p->lock)) { CHANNEL_DEADLOCK_AVOIDANCE(ast); + + /* + * For PRI channels, we must refresh the private pointer because + * the call could move to another B channel while the Asterisk + * channel is unlocked. + */ + p = ast->tech_pvt; } idx = dahdi_get_index(ast, p, 0); @@ -11317,7 +11325,9 @@ static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event) switch (i->sig) { #if defined(HAVE_PRI) case SIG_PRI_LIB_HANDLE_CASES: + ast_mutex_lock(&i->lock); sig_pri_chan_alarm_notify(i->sig_pvt, 1); + ast_mutex_unlock(&i->lock); break; #endif /* defined(HAVE_PRI) */ #if defined(HAVE_SS7) @@ -11335,7 +11345,9 @@ static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event) switch (i->sig) { #if defined(HAVE_PRI) case SIG_PRI_LIB_HANDLE_CASES: + ast_mutex_lock(&i->lock); sig_pri_chan_alarm_notify(i->sig_pvt, 0); + ast_mutex_unlock(&i->lock); break; #endif /* defined(HAVE_PRI) */ #if defined(HAVE_SS7) @@ -12745,7 +12757,9 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, switch (tmp->sig) { #ifdef HAVE_PRI case SIG_PRI_LIB_HANDLE_CASES: + ast_mutex_lock(&tmp->lock); sig_pri_chan_alarm_notify(tmp->sig_pvt, si.alarms); + ast_mutex_unlock(&tmp->lock); break; #endif #if defined(HAVE_SS7) @@ -13489,6 +13503,14 @@ static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap tmp = analog_request(p->sig_pvt, &callwait, requestor); #ifdef HAVE_PRI } else if (dahdi_sig_pri_lib_handles(p->sig)) { + /* + * We already have the B channel reserved for this call. We + * just need to make sure that dahdi_hangup() has completed + * cleaning up before continuing. + */ + ast_mutex_lock(&p->lock); + ast_mutex_unlock(&p->lock); + 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); @@ -13503,18 +13525,23 @@ static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap if (!tmp) { p->outgoing = 0; #if defined(HAVE_PRI) -#if defined(HAVE_PRI_CALL_WAITING) switch (p->sig) { case SIG_PRI_LIB_HANDLE_CASES: +#if defined(HAVE_PRI_CALL_WAITING) if (((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting) { ((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting = 0; ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); } +#endif /* defined(HAVE_PRI_CALL_WAITING) */ + /* + * This should be the last thing to clear when we are done with + * the channel. + */ + ((struct sig_pri_chan *) p->sig_pvt)->allocated = 0; break; default: break; } -#endif /* defined(HAVE_PRI_CALL_WAITING) */ #endif /* defined(HAVE_PRI) */ } else { snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", (char *) data); @@ -15194,6 +15221,9 @@ static char *dahdi_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli ast_cli(a->fd, "Resetting "); if (chan->call) ast_cli(a->fd, "Call "); + if (chan->allocated) { + ast_cli(a->fd, "Allocated "); + } ast_cli(a->fd, "\n"); if (tmp->logicalspan) ast_cli(a->fd, "PRI Logical Span: %d\n", tmp->logicalspan); |