[svn-commits] moy: branch moy/dahdi-tap-1.6.2 r229280 - /team/moy/dahdi-tap-1.6.2/channels/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue Nov 10 13:43:35 CST 2009
Author: moy
Date: Tue Nov 10 13:43:31 2009
New Revision: 229280
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=229280
Log:
fixed crv calculation and ignored multiple progress messages
Modified:
team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c
Modified: team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c?view=diff&rev=229280&r1=229279&r2=229280
==============================================================================
--- team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c (original)
+++ team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c Tue Nov 10 13:43:31 2009
@@ -511,6 +511,7 @@
char callingani[AST_MAX_EXTENSION];
char callingname[AST_MAX_EXTENSION];
char callednum[AST_MAX_EXTENSION];
+ int proceeding:1;
};
struct dahdi_pri {
@@ -12399,7 +12400,7 @@
#if defined(HAVE_PRI)
/* Not thread-safe, we assume nobody else is looking for a passive call slot at the same time in this pri */
-static struct dahdi_pcall *pri_get_pcall(struct dahdi_pri *pri, void *callref)
+static struct dahdi_pcall *dahdi_pri_get_pcall(struct dahdi_pri *pri, void *callref)
{
int i;
for (i = 0; i < ARRAY_LEN(pri->pcalls); i++) {
@@ -12410,12 +12411,22 @@
return NULL;
}
-static struct dahdi_pcall *pri_get_crv_pcall(struct dahdi_pri *pri, int crv)
+int dahdi_pri_get_crv(struct pri *ctrl, q931_call *call);
+int dahdi_pri_get_crv(struct pri *ctrl, q931_call *call)
+{
+ int callmode = 0;
+ int crv = pri_get_crv(ctrl, call, &callmode);
+ crv <<= 3;
+ crv |= (callmode & 0x7);
+ return crv;
+}
+
+static struct dahdi_pcall *dahdi_pri_get_pcall_bycrv(struct dahdi_pri *pri, int crv)
{
int i;
int tstcrv;
for (i = 0; i < ARRAY_LEN(pri->pcalls); i++) {
- tstcrv = pri->pcalls[i].callref ? pri_get_crv(pri->pri, pri->pcalls[i].callref, NULL) : 0;
+ tstcrv = pri->pcalls[i].callref ? dahdi_pri_get_crv(pri->pri, pri->pcalls[i].callref) : 0;
if (pri->pcalls[i].callref && tstcrv == crv) {
return &pri->pcalls[i];
}
@@ -12436,6 +12447,8 @@
static void handle_pri_passive_event(struct dahdi_pri *pri, pri_event *e)
{
int chanpos, peerpos, law, layer1, transcap, res, fd;
+ int crv = 0;
+ int eventcrv = 0;
struct dahdi_pcall *pcall = NULL;
struct ast_channel *c = NULL;
struct dahdi_pvt *peerpvt = NULL;
@@ -12451,10 +12464,16 @@
switch (e->e) {
case PRI_EVENT_RING:
- ast_log(LOG_DEBUG, "Ring on channel %d of span %d with callref %d\n", e->ring.channel, pri->span, e->ring.cref);
/* we cannot use any pri->pvts data structure because we still dont know which channel will be used and therefore cant get
* chanpos (ie, flexible channel was requested), thus, we need our own list of call references */
- pcall = pri_get_pcall(pri, NULL);
+ crv = dahdi_pri_get_crv(pri->pri, e->ring.call);
+ ast_log(LOG_DEBUG, "Ring on channel %d of span %d with callref %d\n", e->ring.channel, pri->span, crv);
+ pcall = dahdi_pri_get_pcall_bycrv(pri, crv);
+ if (pcall) {
+ ast_log(LOG_WARNING, "There is a call with call reference %d already, ignoring duplicated RING msg\n", crv);
+ break;
+ }
+ pcall = dahdi_pri_get_pcall(pri, NULL);
if (!pcall) {
ast_log(LOG_ERROR, "Failed to get a free PRI passive call slot, this is a bug!\n");
break;
@@ -12467,24 +12486,31 @@
break;
case PRI_EVENT_PROGRESS:
- ast_log(LOG_DEBUG, "Progress on channel %d of span %d\n", e->proceeding.channel, pri->span);
+ crv = dahdi_pri_get_crv(pri->pri, e->proceeding.call);
+ ast_log(LOG_DEBUG, "Progress on channel %d of span %d with call reference %d\n", e->proceeding.channel, pri->span, crv);
break;
case PRI_EVENT_PROCEEDING:
- ast_log(LOG_DEBUG, "Proceed on channel %d of span %d\n", e->proceeding.channel, pri->span);
+ crv = dahdi_pri_get_crv(pri->pri, e->proceeding.call);
+ ast_log(LOG_DEBUG, "Proceed on channel %d of span %d with call reference %d\n", e->proceeding.channel, pri->span, crv);
/* at this point we should know the real b chan that will be used and can therefore proceed to setup the ast channels, but
* only if a couple of call tests are passed */
/* check that we already know about this call in the peer PRI (which was the one receiving the PRI_EVENT_RING event) */
- if (!(pcall = pri_get_crv_pcall(peerpri, pri_get_crv(pri->pri, e->proceeding.call, NULL)))) {
+ if (!(pcall = dahdi_pri_get_pcall_bycrv(peerpri, crv))) {
ast_log(LOG_ERROR,
- "BUG, we got proceeding in channel number %d/%d on span %d for call reference %d "
+ "we got proceeding in channel number %d/%d on span %d for call reference %d "
"but we never got PRI_EVENT_RING for that call on peer span %d?\n",
PRI_SPAN(e->proceeding.channel),
PRI_CHANNEL(e->proceeding.channel),
- pri->span, e->proceeding.cref, peerpri->span);
+ pri->span, crv, peerpri->span);
break;
}
+ if (pcall->proceeding) {
+ ast_log(LOG_DEBUG, "Ignoring duplicated proceeding with call reference value %d\n", crv);
+ break;
+ }
+ pcall->proceeding = 1;
/* check that the layer 1 and trans capability are supported */
layer1 = pri_get_layer1(peerpri->pri, pcall->callref);
transcap = pri_get_transcap(peerpri->pri, pcall->callref);
@@ -12577,13 +12603,13 @@
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set law on channel %d: %s\n", masterpvt->channel, strerror(errno));
}
- res = set_actual_gain(masterpvt->subs[SUB_REAL].dfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
+ res = set_actual_gain(masterpvt->subs[SUB_REAL].dfd, 0, masterpvt->rxgain, masterpvt->txgain, law);
if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set gains on channel %d: %s\n", pri->pvts[chanpos]->channel, strerror(errno));
+ ast_log(LOG_WARNING, "Unable to set gains on channel %d: %s\n", masterpvt->channel, strerror(errno));
}
res = ioctl(masterpvt->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &law);
if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", pri->pvts[chanpos]->channel, law, strerror(errno));
+ ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", masterpvt->channel, law, strerror(errno));
}
res = dahdi_setlaw(peerpvt->subs[SUB_REAL].dfd, law);
@@ -12699,8 +12725,12 @@
break;
}
/* first put back the passive call slot, if any was used, since
- * regardless of whethere there is owner or not, this resource must be freed */
+ * regardless of whethere there is owner or not, this resource must be freed
+ * we dont know if the same side with the callref will hangup, so we need to try to put the call
+ * back in both pri and peerpri
+ */
pri_put_pcall(pri, e->hangup.call);
+ pri_put_pcall(peerpri, e->hangup.call);
/* now try to hangup if needed */
masterpvt = pri->pvts[chanpos];
@@ -12715,6 +12745,17 @@
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
break;
}
+ /* dont try to hangup if this is not our call (can this ever happen?) */
+ crv = dahdi_pri_get_crv(pri->pri, masterpvt->call);
+ eventcrv = dahdi_pri_get_crv(pri->pri, e->hangup.call);
+ if (crv != eventcrv) {
+ ast_channel_unlock(masterpvt->owner);
+ ast_mutex_unlock(&masterpvt->lock);
+ /* this may be a valid condition if the user hangup the ast channel before the tapped line is terminated */
+ ast_log(LOG_NOTICE, "Ignoring hangup in tapped channel number %d/%d on span %d, our call %d != hangup call %d\n",
+ PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, crv, eventcrv);
+ break;
+ }
ast_queue_hangup(masterpvt->owner);
ast_channel_unlock(masterpvt->owner);
ast_mutex_unlock(&masterpvt->lock);
@@ -12723,12 +12764,13 @@
case PRI_EVENT_HANGUP_ACK:
ast_log(LOG_DEBUG, "Hangup ack on channel %d of span %d\n", e->hangup.channel, pri->span);
- /* put back the passive call slot, if any was used */
+ /* put back the passive call slot, if any was used, not sure if this do any good, PRI_EVENT_HANGUP does this */
pri_put_pcall(pri, e->hangup.call);
+ pri_put_pcall(peerpri, e->hangup.call);
break;
default:
- ast_log(LOG_NOTICE, "Ignoring passive event %s on span %d\n", pri_event2str(e->gen.e), pri->span);
+ ast_log(LOG_DEBUG, "Ignoring passive event %s on span %d\n", pri_event2str(e->gen.e), pri->span);
break;
}
}
More information about the svn-commits
mailing list