Dear Matthew,

We detected 2 problems we tried to work around:

1) We were getting echo on SS7 calls (no matter the echo-canceler we
configured). I detected echo canceler was not activated during call setup.

2) Connecting same linkset to more than one DPC (different E1s), when
replying SS7 messages addressed to a CIC associated to one DPC, the
answer message included wrong PC address.

Attached my libss7 patches and chan_zap. These patches are running last
3 weeks with no problem.

Please validate them.

PS: sorry about my "DB" remarks but this helps me to keep track on
changes. I will remove it upon your validation.

[]'s

Daniel
--- channels/chan_zap.c.old.20071212	2007-12-13 17:25:33.465655976 +0000
+++ channels/chan_zap.c	2008-01-17 13:57:30.881114122 +0000
@@ -5419,12 +5419,16 @@
 			}
 #endif
 #ifdef HAVE_SS7
+			ast_debug(1,"******** DB PROGRESS SS7 %s\n",chan->name);
 			if (!p->progress && p->sig==SIG_SS7 && p->ss7 && !p->outgoing) {
 				if (p->ss7->ss7) {
 					ss7_grab(p, p->ss7);
 					isup_cpg(p->ss7->ss7, p->ss7call, CPG_EVENT_INBANDINFO);
 					p->progress = 1;
 					ss7_rel(p->ss7);
+					/* DB: echo */
+					ast_debug(1,"******** DB ECHO PROGRESS SS7 %s\n",chan->name);
+					zt_enable_ec(p);
 
 				}
 			}
@@ -7496,8 +7500,8 @@
 	else
 		return &linksets[linkset - 1];
 }
-#endif /* HAVE_SS7 */
 
+#endif /* HAVE_SS7 */
 static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading)
 {
 	/* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
@@ -8418,13 +8422,15 @@
 #ifdef HAVE_SS7
 static int zt_setlaw(int zfd, int law);
 
-static int ss7_find_cic(struct zt_ss7 *linkset, int cic)
+static int ss7_find_cic(struct zt_ss7 *linkset, int cic, unsigned int dpc)
 {
 	int i;
 	int winner = -1;
 	for (i = 0; i < linkset->numchans; i++) {
-		if (linkset->pvts[i] && (linkset->pvts[i]->cic == cic)) {
+		/* DB: fix opc */
+		if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && linkset->pvts[i]->cic == cic)) {
 			winner = i;
+			break;
 		}
 	}
 	return winner;
@@ -8680,7 +8686,7 @@
 				ast_debug(1, "MTP2 link up\n");
 				break;
 			case ISUP_EVENT_CPG:
-				chanpos = ss7_find_cic(linkset, e->cpg.cic);
+				chanpos = ss7_find_cic(linkset, e->cpg.cic, e->cpg.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "CPG on unconfigured CIC %d\n", e->cpg.cic);
 					break;
@@ -8709,7 +8715,7 @@
 				break;
 			case ISUP_EVENT_RSC:
 				ast_verbose("Resetting CIC %d\n", e->rsc.cic);
-				chanpos = ss7_find_cic(linkset, e->rsc.cic);
+				chanpos = ss7_find_cic(linkset, e->rsc.cic, e->rsc.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "RSC on unconfigured CIC %d\n", e->rsc.cic);
 					break;
@@ -8725,7 +8731,7 @@
 				break;
 			case ISUP_EVENT_GRS:
 				ast_debug(1, "Got Reset for CICs %d to %d: Acknowledging\n", e->grs.startcic, e->grs.endcic);
-				chanpos = ss7_find_cic(linkset, e->grs.startcic);
+				chanpos = ss7_find_cic(linkset, e->grs.startcic, e->grs.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "GRS on unconfigured CIC %d\n", e->grs.startcic);
 					break;
@@ -8741,7 +8747,7 @@
 				break;
 			case ISUP_EVENT_IAM:
  				ast_debug(1, "Got IAM for CIC %d and called number %s, calling number %s\n", e->iam.cic, e->iam.called_party_num, e->iam.calling_party_num);
-				chanpos = ss7_find_cic(linkset, e->iam.cic);
+				chanpos = ss7_find_cic(linkset, e->iam.cic, e->iam.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "IAM on unconfigured CIC %d\n", e->iam.cic);
 					isup_rel(ss7, e->iam.call, -1);
@@ -8809,7 +8815,7 @@
 				ast_mutex_unlock(&p->lock);
 				break;
 			case ISUP_EVENT_COT:
-				chanpos = ss7_find_cic(linkset, e->cot.cic);
+				chanpos = ss7_find_cic(linkset, e->cot.cic, e->cot.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "COT on unconfigured CIC %d\n", e->cot.cic);
 					isup_rel(ss7, e->cot.call, -1);
@@ -8823,7 +8829,7 @@
 				break;
 			case ISUP_EVENT_CCR:
 				ast_debug(1, "Got CCR request on CIC %d\n", e->ccr.cic);
-				chanpos = ss7_find_cic(linkset, e->ccr.cic);
+				chanpos = ss7_find_cic(linkset, e->ccr.cic, e->ccr.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "CCR on unconfigured CIC %d\n", e->ccr.cic);
 					break;
@@ -8838,7 +8844,7 @@
 				isup_lpa(linkset->ss7, e->ccr.cic, p->dpc);
 				break;
 			case ISUP_EVENT_REL:
-				chanpos = ss7_find_cic(linkset, e->rel.cic);
+				chanpos = ss7_find_cic(linkset, e->rel.cic, e->rel.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "REL on unconfigured CIC %d\n", e->rel.cic);
 					break;
@@ -8860,7 +8866,7 @@
 				ast_mutex_unlock(&p->lock);
 				break;
 			case ISUP_EVENT_ACM:
-				chanpos = ss7_find_cic(linkset, e->acm.cic);
+				chanpos = ss7_find_cic(linkset, e->acm.cic, e->acm.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "ACM on unconfigured CIC %d\n", e->acm.cic);
 					isup_rel(ss7, e->acm.call, -1);
@@ -8880,7 +8886,7 @@
 				}
 				break;
 			case ISUP_EVENT_CGB:
- 				chanpos = ss7_find_cic(linkset, e->cgb.startcic);
+ 				chanpos = ss7_find_cic(linkset, e->cgb.startcic, e->cgb.opc);
  				if (chanpos < 0) {
  					ast_log(LOG_WARNING, "CGB on unconfigured CIC %d\n", e->cgb.startcic);
  					break;
@@ -8890,7 +8896,7 @@
  				isup_cgba(linkset->ss7, e->cgb.startcic, e->cgb.endcic, p->dpc, e->cgb.status, e->cgb.type);
 				break;
 			case ISUP_EVENT_CGU:
- 				chanpos = ss7_find_cic(linkset, e->cgu.startcic);
+ 				chanpos = ss7_find_cic(linkset, e->cgu.startcic, e->cgu.opc);
  				if (chanpos < 0) {
  					ast_log(LOG_WARNING, "CGU on unconfigured CIC %d\n", e->cgu.startcic);
  					break;
@@ -8900,7 +8906,7 @@
  				isup_cgua(linkset->ss7, e->cgu.startcic, e->cgu.endcic, p->dpc, e->cgu.status, e->cgu.type);
 				break;
 			case ISUP_EVENT_UCIC:
-				chanpos = ss7_find_cic(linkset, e->ucic.cic);
+				chanpos = ss7_find_cic(linkset, e->ucic.cic, e->ucic.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "UCIC on unconfigured CIC %d\n", e->ucic.cic);
 					break;
@@ -8913,7 +8919,7 @@
 				ast_mutex_unlock(&p->lock);			//doesn't require a SS7 acknowledgement
 				break;
 			case ISUP_EVENT_BLO:
-				chanpos = ss7_find_cic(linkset, e->blo.cic);
+				chanpos = ss7_find_cic(linkset, e->blo.cic, e->blo.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "BLO on unconfigured CIC %d\n", e->blo.cic);
 					break;
@@ -8926,7 +8932,7 @@
 				isup_bla(linkset->ss7, e->blo.cic, p->dpc);
 				break;
 			case ISUP_EVENT_BLA:
-				chanpos = ss7_find_cic(linkset, e->bla.cic);
+				chanpos = ss7_find_cic(linkset, e->bla.cic, e->bla.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "BLA on unconfigured CIC %d\n", e->bla.cic);
 					break;
@@ -8938,7 +8944,7 @@
 				ast_mutex_unlock(&p->lock);
 				break;
 			case ISUP_EVENT_UBL:
-				chanpos = ss7_find_cic(linkset, e->ubl.cic);
+				chanpos = ss7_find_cic(linkset, e->ubl.cic, e->ubl.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "UBL on unconfigured CIC %d\n", e->ubl.cic);
 					break;
@@ -8951,7 +8957,7 @@
 				isup_uba(linkset->ss7, e->ubl.cic, p->dpc);
 				break;
 			case ISUP_EVENT_UBA:
-				chanpos = ss7_find_cic(linkset, e->uba.cic);
+				chanpos = ss7_find_cic(linkset, e->uba.cic, e->uba.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "UBA on unconfigured CIC %d\n", e->uba.cic);
 					break;
@@ -8969,7 +8975,7 @@
 				else
 					cic = e->anm.cic;
 
-				chanpos = ss7_find_cic(linkset, cic);
+				chanpos = ss7_find_cic(linkset, cic, (e->e == ISUP_EVENT_ANM) ? e->anm.opc : e->con.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "ANM/CON on unconfigured CIC %d\n", cic);
 					isup_rel(ss7, (e->e == ISUP_EVENT_ANM) ? e->anm.call : e->con.call, -1);
@@ -8983,7 +8989,7 @@
 				}
 				break;
 			case ISUP_EVENT_RLC:
-				chanpos = ss7_find_cic(linkset, e->rlc.cic);
+				chanpos = ss7_find_cic(linkset, e->rlc.cic, e->rlc.opc);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "RLC on unconfigured CIC %d\n", e->rlc.cic);
 					break;
--- libss7-trunk.old/isup.c	2007-10-26 00:00:43.000000000 +0000
+++ libss7-trunk/isup.c	2007-12-13 17:53:19.276585130 +0000
@@ -2128,11 +2128,15 @@
 			e->iam.charge_num_plan = c->charge_num_plan;
 			e->iam.oli_ani2 = c->oli_ani2;
 			e->iam.call = c;
+			/* DB: fix OPC */
+			e->iam.opc = opc;
 			return 0;
 		case ISUP_GRS:
 			e->e = ISUP_EVENT_GRS;
 			e->grs.startcic = cic;
 			e->grs.endcic = cic + c->range;
+			/* DB: fix OPC */
+			e->grs.opc = opc;
 			isup_free_call(ss7, c); /* Won't need this again */
 			return 0;
 		case ISUP_GRA:
@@ -2141,6 +2145,8 @@
 			e->gra.endcic = cic + c->range;
 			for (i = 0; i < (c->range + 1); i++)
 				e->gra.status[i] = c->status[i];
+			/* DB: fix OPC */
+			e->gra.opc = opc;
 
 			isup_free_call(ss7, c); /* Won't need this again */
 			return 0;
@@ -2148,31 +2154,43 @@
 			e->e = ISUP_EVENT_RSC;
 			e->rsc.cic = cic;
 			e->rsc.call = c;
+			/* DB: fix OPC */
+			e->rsc.opc = opc;
 			return 0;
 		case ISUP_REL:
 			e->e = ISUP_EVENT_REL;
 			e->rel.cic = c->cic;
 			e->rel.call = c;
 			e->rel.cause = c->cause;
+			/* DB: fix OPC */
+			e->rel.opc = opc;
 			return 0;
 		case ISUP_ACM:
 			e->e = ISUP_EVENT_ACM;
 			e->acm.cic = c->cic;
 			e->acm.call = c;
+			/* DB: fix OPC */
+			e->acm.opc = opc;
 			return 0;
 		case ISUP_CON:
 			e->e = ISUP_EVENT_CON;
 			e->con.cic = c->cic;
 			e->con.call = c;
+			/* DB: fix OPC */
+			e->con.opc = opc;
 			return 0;
 		case ISUP_ANM:
 			e->e = ISUP_EVENT_ANM;
 			e->anm.cic = c->cic;
 			e->anm.call = c;
+			/* DB: fix OPC */
+			e->anm.opc = opc;
 			return 0;
 		case ISUP_RLC:
 			e->e = ISUP_EVENT_RLC;
 			e->rlc.cic = c->cic;
+			/* DB: fix OPC */
+			e->rlc.opc = opc;
 			isup_free_call(ss7, c);
 			return 0;
 		case ISUP_COT:
@@ -2180,35 +2198,49 @@
 			e->cot.cic = c->cic;
 			e->cot.passed = c->cot_check_passed;
 			e->cot.call = c;
+			/* DB: fix OPC */
+			e->cot.opc = opc;
 			return 0;
 		case ISUP_CCR:
 			e->e = ISUP_EVENT_CCR;
 			e->ccr.cic = c->cic;
+			/* DB: fix OPC */
+			e->ccr.opc = opc;
 			isup_free_call(ss7, c);
 			return 0;
 		case ISUP_BLO:
 			e->e = ISUP_EVENT_BLO;
 			e->blo.cic = c->cic;
+			/* DB: fix OPC */
+			e->blo.opc = opc;
 			isup_free_call(ss7, c);
 			return 0;
 		case ISUP_UBL:
 			e->e = ISUP_EVENT_UBL;
 			e->ubl.cic = c->cic;
+			/* DB: fix OPC */
+			e->ubl.opc = opc;
 			isup_free_call(ss7, c);
 			return 0;
 		case ISUP_BLA:
 			e->e = ISUP_EVENT_BLA;
 			e->bla.cic = c->cic;
+			/* DB: fix OPC */
+			e->bla.opc = opc;
 			isup_free_call(ss7, c);
 			return 0;
 		case ISUP_LPA:
 			e->e = ISUP_EVENT_LPA;
 			e->lpa.cic = c->cic;
+			/* DB: fix OPC */
+			e->lpa.opc = opc;
 			isup_free_call(ss7, c);
 			return 0;
 		case ISUP_UBA:
 			e->e = ISUP_EVENT_UBA;
 			e->uba.cic = c->cic;
+			/* DB: fix OPC */
+			e->uba.opc = opc;
 			isup_free_call(ss7, c);
 			return 0;
 		case ISUP_CGB:
@@ -2219,6 +2251,8 @@
 
 			for (i = 0; i < (c->range + 1); i++)
 				e->cgb.status[i] = c->status[i];
+			/* DB: fix OPC */
+			e->cgb.opc = opc;
 
 			isup_free_call(ss7, c);
 			return 0;
@@ -2230,17 +2264,23 @@
 
 			for (i = 0; i < (c->range + 1); i++)
 				e->cgu.status[i] = c->status[i];
+			/* DB: fix OPC */
+			e->cgu.opc = opc;
 
 			isup_free_call(ss7, c);
 			return 0;
 		case ISUP_CPG:
 			e->e = ISUP_EVENT_CPG;
 			e->cpg.cic = c->cic;
+			/* DB: fix OPC */
+			e->cpg.opc = opc;
 			e->cpg.event = c->event_info;
 			return 0;
 		case ISUP_UCIC:
 			e->e = ISUP_EVENT_UCIC;
 			e->ucic.cic = c->cic;
+			/* DB: fix OPC */
+			e->ucic.opc = opc;
 			isup_free_call(ss7, c);
 			return 0;
 		default:
--- libss7-trunk.old/libss7.h	2007-10-26 00:00:43.000000000 +0000
+++ libss7-trunk/libss7.h	2007-12-13 17:54:40.921237794 +0000
@@ -109,6 +109,8 @@
 	unsigned char charge_nai;
 	unsigned char charge_num_plan;
 	int oli_ani2;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 	struct isup_call *call;
 } ss7_event_iam;
 
@@ -116,35 +118,47 @@
 	int e;
 	int cic;
 	int cause;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 	struct isup_call *call;
 } ss7_event_rel;
 
 typedef struct {
 	int e;
 	int cic;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 } ss7_event_ciconly;
 
 typedef struct {
 	int e;
 	int cic;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 	struct isup_call *call;
 } ss7_event_con;
 
 typedef struct {
 	int e;
 	int cic;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 	struct isup_call *call;
 } ss7_event_rsc;
 
 typedef struct {
 	int e;
 	int cic;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 	struct isup_call *call;
 } ss7_event_anm;
 
 typedef struct {
 	int e;
 	int cic;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 	struct isup_call *call;
 } ss7_event_acm;
 
@@ -153,6 +167,8 @@
 	int startcic;
 	int endcic;
 	int type;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 	unsigned char status[255];
 } ss7_event_cicrange;
 
@@ -160,6 +176,8 @@
 	int e;
 	int cic;
 	int passed;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 	struct isup_call *call;
 } ss7_event_cot;
 
@@ -171,6 +189,8 @@
 typedef struct {
 	int e;
 	int cic;
+	/* DB: fix OPC data on GRS,GRA,BLO,UBL,etc. */
+	unsigned int opc;
 	unsigned char event;
 } ss7_event_cpg;
 
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--

asterisk-ss7 mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-ss7

Reply via email to