[svn-commits] rmudgett: branch rmudgett/call_waiting r251399 - /team/rmudgett/call_waiting/...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Mon Mar 8 18:58:12 CST 2010
Author: rmudgett
Date: Mon Mar 8 18:58:08 2010
New Revision: 251399
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=251399
Log:
1) Resolve the channel to use for call waiting when the CONNECT message
comes in.
2) Track the number of outstanding PRI call waiting calls.
3) Simplified channel selection failed reason/cause code.
Modified:
team/rmudgett/call_waiting/channels/chan_dahdi.c
team/rmudgett/call_waiting/channels/sig_pri.c
team/rmudgett/call_waiting/channels/sig_pri.h
Modified: team/rmudgett/call_waiting/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/call_waiting/channels/chan_dahdi.c?view=diff&rev=251399&r1=251398&r2=251399
==============================================================================
--- team/rmudgett/call_waiting/channels/chan_dahdi.c (original)
+++ team/rmudgett/call_waiting/channels/chan_dahdi.c Mon Mar 8 18:58:08 2010
@@ -12202,7 +12202,7 @@
int res;
pvt_chan = p->sig_pvt;
- res = sig_pri_available(&pvt_chan, reason, is_specific_channel);
+ res = sig_pri_available(&pvt_chan, is_specific_channel);
*pvt = pvt_chan->chan_pvt;
return res;
}
@@ -12570,14 +12570,6 @@
&& available(&p, &unavailreason, channelmatched)) {
ast_debug(1, "Using channel %d\n", p->channel);
- switch (p->sig) {
- case SIG_PRI_LIB_HANDLE_CASES:
- callwait = ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel;
- break;
- default:
- callwait = (p->owner != NULL);
- break;
- }
#ifdef HAVE_OPENR2
if (p->mfcr2) {
ast_mutex_lock(&p->lock);
@@ -12595,6 +12587,13 @@
if (!p) {
break;
}
+ }
+ switch (p->sig) {
+ case SIG_PRI_LIB_HANDLE_CASES:
+ break;
+ default:
+ callwait = (p->owner != NULL);
+ break;
}
/* Make special notes */
@@ -12633,6 +12632,18 @@
}
if (!tmp) {
p->outgoing = 0;
+#if defined(HAVE_PRI_CALL_WAITING)
+ switch (p->sig) {
+ case SIG_PRI_LIB_HANDLE_CASES:
+ 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);
+ }
+ break;
+ default:
+ break;
+ }
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
} else {
snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", (char *) data);
}
@@ -12656,14 +12667,10 @@
}
ast_mutex_unlock(&iflock);
restart_monitor();
- if (callwait)
+ if (!tmp) {
*cause = AST_CAUSE_BUSY;
- else if (!tmp) {
- if (channelmatched) {
- if (unavailreason)
- *cause = AST_CAUSE_BUSY;
- } else if (groupmatched) {
- *cause = (unavailreason) ? unavailreason : AST_CAUSE_CONGESTION;
+ if (!callwait && groupmatched) {
+ *cause = AST_CAUSE_CONGESTION;
}
}
Modified: team/rmudgett/call_waiting/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/call_waiting/channels/sig_pri.c?view=diff&rev=251399&r1=251398&r2=251399
==============================================================================
--- team/rmudgett/call_waiting/channels/sig_pri.c (original)
+++ team/rmudgett/call_waiting/channels/sig_pri.c Mon Mar 8 18:58:08 2010
@@ -928,15 +928,17 @@
int x;
int span;
int principle;
+ int prioffset;
if (channel < 0) {
/* Channel is not picked yet. */
return -1;
}
- if (channel & PRI_HELD_CALL) {
+ prioffset = PRI_CHANNEL(channel);
+ if (!prioffset || (channel & PRI_HELD_CALL)) {
if (!call) {
- /* Cannot find a held call without a call. */
+ /* Cannot find a call waiting call or held call without a call. */
return -1;
}
principle = -1;
@@ -961,11 +963,10 @@
span = pri->dchan_logical_span[index];
}
- channel = PRI_CHANNEL(channel);
principle = -1;
for (x = 0; x < pri->numchans; x++) {
if (pri->pvts[x]
- && pri->pvts[x]->prioffset == channel
+ && pri->pvts[x]->prioffset == prioffset
&& pri->pvts[x]->logicalspan == span
&& !pri->pvts[x]->no_b_channel) {
principle = x;
@@ -1033,6 +1034,10 @@
new_chan->setup_ack = old_chan->setup_ack;
new_chan->outgoing = old_chan->outgoing;
new_chan->digital = old_chan->digital;
+#if defined(HAVE_PRI_CALL_WAITING)
+ new_chan->is_call_waiting = old_chan->is_call_waiting;
+ old_chan->is_call_waiting = 0;
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
old_chan->alerting = 0;
old_chan->alreadyhungup = 0;
old_chan->isidlecall = 0;
@@ -1207,9 +1212,6 @@
&& pri->pvts[idx]->no_b_channel
&& !pri->pvts[idx]->inalarm
&& !pri->pvts[idx]->owner) {
-#if defined(HAVE_PRI_CALL_WAITING)
- pri->pvts[idx]->is_call_waiting = 0;
-#endif /* defined(HAVE_PRI_CALL_WAITING) */
ast_debug(1, "Found empty available no B channel interface\n");
return idx;
}
@@ -3064,10 +3066,20 @@
e->ring.call);
break;
}
- if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF)
+ if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
+ /* Any channel requested. */
chanpos = pri_find_empty_chan(pri, 1);
- else
+ } else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
+ /*
+ * No channel specified.
+ * We will not accept incoming call waiting calls.
+ */
+ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
+ break;
+ } else {
+ /* A channel is specified. */
chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
+ }
/* if no channel specified find one empty */
if (chanpos < 0) {
ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n",
@@ -3581,47 +3593,93 @@
if (chanpos < 0) {
ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
+ break;
+ }
+ chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n",
+ PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
+ break;
+ }
+#if defined(HAVE_PRI_CALL_WAITING)
+ if (pri->pvts[chanpos]->is_call_waiting) {
+ if (pri->pvts[chanpos]->no_b_channel) {
+ int new_chanpos;
+
+ /*
+ * Need to find a free channel now or
+ * kill the call with PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION.
+ */
+ new_chanpos = pri_find_empty_chan(pri, 1);
+ if (new_chanpos < 0) {
+ sig_pri_lock_private(pri->pvts[chanpos]);
+ sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
+ e->answer.subcmds, e->answer.call);
+ sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
+ pri->pvts[chanpos]->alreadyhungup = 1;
+ pri_hangup(pri->pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
+ if (pri->pvts[chanpos]->owner) {
+ pri->pvts[chanpos]->owner->hangupcause = PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION;
+ switch (pri->pvts[chanpos]->owner->_state) {
+ case AST_STATE_BUSY:
+ case AST_STATE_UP:
+ ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
+ break;
+ default:
+ pri_queue_control(pri->pvts[chanpos], AST_CONTROL_CONGESTION, pri);
+ break;
+ }
+ } else {
+ pri->pvts[chanpos]->is_call_waiting = 0;
+ pri->pvts[chanpos]->call = NULL;
+ ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1);
+ }
+ sig_pri_unlock_private(pri->pvts[chanpos]);
+ break;
+ }
+ chanpos = pri_fixup_principle(pri, new_chanpos, e->answer.call);
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING,
+ "Unable to move call waiting call channel on span %d\n",
+ pri->span);
+ break;
+ }
+ }
+ pri_connect_ack(pri->pri, e->answer.call, PVT_TO_CHANNEL(pri->pvts[chanpos]));
} else {
-#if defined(HAVE_PRI_CALL_WAITING)
-/* BUGBUG need to handle the channel indication as in a SETUP: Specified, no alternative; specified, alternate acceptable; any channel; not present. */
- if (PRI_CHANNEL(e->answer.channel)) {
- /* We already have a channel so do normal CONNECT_ACKNOWLEDGE. */
- pri_connect_ack(pri->pri, e->answer.call, 0);
- } else {
-/* BUGBUG need to find a free channel now or kill the call with PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION. */
+ /* Call is normal so do normal CONNECT_ACKNOWLEDGE. */
+ pri_connect_ack(pri->pri, e->answer.call, 0);
+ }
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
+ sig_pri_lock_private(pri->pvts[chanpos]);
+
+ if (pri->pvts[chanpos]->is_call_waiting) {
+ pri->pvts[chanpos]->is_call_waiting = 0;
+ ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1);
+ sig_pri_span_devstate_changed(pri);
+ }
+ sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
+ e->answer.subcmds, e->answer.call);
+ pri_queue_control(pri->pvts[chanpos], AST_CONTROL_ANSWER, pri);
+ /* Enable echo cancellation if it's not on already */
+ sig_pri_set_dialing(pri->pvts[chanpos], 0);
+ sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
+
+#ifdef SUPPORT_USERUSER
+ if (!ast_strlen_zero(e->answer.useruserinfo)) {
+ struct ast_channel *owner;
+
+ sig_pri_lock_owner(pri, chanpos);
+ owner = pri->pvts[chanpos]->owner;
+ if (owner) {
+ pbx_builtin_setvar_helper(owner, "USERUSERINFO",
+ e->answer.useruserinfo);
+ ast_channel_unlock(owner);
}
-#endif /* defined(HAVE_PRI_CALL_WAITING) */
- chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n",
- PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
- } else {
- sig_pri_lock_private(pri->pvts[chanpos]);
-
- sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
- e->answer.subcmds, e->answer.call);
- pri_queue_control(pri->pvts[chanpos], AST_CONTROL_ANSWER, pri);
- /* Enable echo cancellation if it's not on already */
- sig_pri_set_dialing(pri->pvts[chanpos], 0);
- sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
-
-#ifdef SUPPORT_USERUSER
- if (!ast_strlen_zero(e->answer.useruserinfo)) {
- struct ast_channel *owner;
-
- sig_pri_lock_owner(pri, chanpos);
- owner = pri->pvts[chanpos]->owner;
- if (owner) {
- pbx_builtin_setvar_helper(owner, "USERUSERINFO",
- e->answer.useruserinfo);
- ast_channel_unlock(owner);
- }
- }
+ }
#endif
- sig_pri_unlock_private(pri->pvts[chanpos]);
- }
- }
+ sig_pri_unlock_private(pri->pvts[chanpos]);
break;
case PRI_EVENT_HANGUP:
if (sig_pri_is_cis_call(e->hangup.channel)) {
@@ -4055,6 +4113,12 @@
p->owner = NULL;
p->outgoing = 0;
sig_pri_set_digital(p, 0); /* push up to parent for EC*/
+#if defined(HAVE_PRI_CALL_WAITING)
+ if (p->is_call_waiting) {
+ p->is_call_waiting = 0;
+ ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
+ }
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
p->proceeding = 0;
p->progress = 0;
p->alerting = 0;
@@ -4845,7 +4909,7 @@
cw = pri->pvts[idx];
cw->is_call_waiting = 1;
sig_pri_init_config(cw, pri);
- ++pri->num_call_waiting_calls;
+ ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, 1);
}
}
ast_mutex_unlock(&pri->lock);
@@ -4853,7 +4917,7 @@
}
#endif /* defined(HAVE_PRI_CALL_WAITING) */
-int sig_pri_available(struct sig_pri_chan **pvt, int *reason, int is_specific_channel)
+int sig_pri_available(struct sig_pri_chan **pvt, int is_specific_channel)
{
struct sig_pri_chan *p = *pvt;
@@ -4875,11 +4939,6 @@
sig_pri_available_check(p)) {
return 1;
}
-#if defined(HAVE_PRI_SERVICE_MESSAGES)
- if (p->service_status) {
- *reason = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
- }
-#endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
#if defined(HAVE_PRI_CALL_WAITING)
if (!is_specific_channel) {
Modified: team/rmudgett/call_waiting/channels/sig_pri.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/call_waiting/channels/sig_pri.h?view=diff&rev=251399&r1=251398&r2=251399
==============================================================================
--- team/rmudgett/call_waiting/channels/sig_pri.h (original)
+++ team/rmudgett/call_waiting/channels/sig_pri.h Mon Mar 8 18:58:08 2010
@@ -384,7 +384,7 @@
int sig_pri_answer(struct sig_pri_chan *p, struct ast_channel *ast);
-int sig_pri_available(struct sig_pri_chan **pvt, int *reason, int is_specific_channel);
+int sig_pri_available(struct sig_pri_chan **pvt, int is_specific_channel);
void sig_pri_init_pri(struct sig_pri_pri *pri);
More information about the svn-commits
mailing list