[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