summaryrefslogtreecommitdiff
path: root/channels/chan_dahdi.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2011-04-04 16:17:58 +0000
committerRichard Mudgett <rmudgett@digium.com>2011-04-04 16:17:58 +0000
commite1ceb52b5148d23ebeed76380944406c1b551d22 (patch)
tree2793f9493a7082ff514a1f21a57455203e9bdad6 /channels/chan_dahdi.c
parent6826b083ec4602637e367e41944946580888a1ee (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.c52
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);