diff --git a/channels/chan_zap.c b/channels/chan_zap.c index f5ea1ff341b15a0d4206bee0bb983ee89fa0370c..77485290354d63d8155d24ff4a12f12838925626 100644 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -5729,6 +5729,8 @@ static int zt_indicate(struct ast_channel *chan, int condition, const void *data isup_cpg(p->ss7->ss7, p->ss7call, CPG_EVENT_INBANDINFO); p->progress = 1; ss7_rel(p->ss7); + /* enable echo canceler here on SS7 calls */ + zt_enable_ec(p); } } @@ -8943,26 +8945,27 @@ static int zt_setlaw(int zfd, int law) #ifdef HAVE_SS7 -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)) { + if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && linkset->pvts[i]->cic == cic)) { winner = i; + break; } } return winner; } -static void ss7_handle_cqm(struct zt_ss7 *linkset, int startcic, int endcic) +static void ss7_handle_cqm(struct zt_ss7 *linkset, int startcic, int endcic, unsigned int dpc) { unsigned char status[32]; struct zt_pvt *p = NULL; int i, offset; for (i = 0; i < linkset->numchans; i++) { - if (linkset->pvts[i] && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic))) { + if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) { p = linkset->pvts[i]; offset = p->cic - startcic; status[offset] = 0; @@ -8981,18 +8984,18 @@ static void ss7_handle_cqm(struct zt_ss7 *linkset, int startcic, int endcic) } if (p) - isup_cqr(linkset->ss7, startcic, endcic, p->dpc, status); + isup_cqr(linkset->ss7, startcic, endcic, dpc, status); else ast_log(LOG_WARNING, "Could not find any equipped circuits within CQM CICs\n"); } -static inline void ss7_block_cics(struct zt_ss7 *linkset, int startcic, int endcic, unsigned char state[], int block) +static inline void ss7_block_cics(struct zt_ss7 *linkset, int startcic, int endcic, unsigned int dpc, unsigned char state[], int block) { int i; for (i = 0; i < linkset->numchans; i++) { - if (linkset->pvts[i] && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic))) { + if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) { if (state) { if (state[i]) linkset->pvts[i]->remotelyblocked = block; @@ -9002,12 +9005,12 @@ static inline void ss7_block_cics(struct zt_ss7 *linkset, int startcic, int endc } } -static void ss7_inservice(struct zt_ss7 *linkset, int startcic, int endcic) +static void ss7_inservice(struct zt_ss7 *linkset, int startcic, int endcic, unsigned int dpc) { int i; for (i = 0; i < linkset->numchans; i++) { - if (linkset->pvts[i] && (linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)) + if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) linkset->pvts[i]->inservice = 1; } } @@ -9284,7 +9287,7 @@ static void *ss7_linkset(void *data) 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; @@ -9317,7 +9320,7 @@ static void *ss7_linkset(void *data) 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; @@ -9333,27 +9336,27 @@ static void *ss7_linkset(void *data) 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; } p = linkset->pvts[chanpos]; - isup_gra(ss7, e->grs.startcic, e->grs.endcic, p->dpc); - ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, NULL, 0); + isup_gra(ss7, e->grs.startcic, e->grs.endcic, e->grs.opc); + ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc, NULL, 0); break; case ISUP_EVENT_CQM: ast_debug(1, "Got Circuit group query message from CICs %d to %d\n", e->cqm.startcic, e->cqm.endcic); - ss7_handle_cqm(linkset, e->cqm.startcic, e->cqm.endcic); + ss7_handle_cqm(linkset, e->cqm.startcic, e->cqm.endcic, e->cqm.opc); break; case ISUP_EVENT_GRA: ast_verbose("Got reset acknowledgement from CIC %d to %d.\n", e->gra.startcic, e->gra.endcic); - ss7_inservice(linkset, e->gra.startcic, e->gra.endcic); - ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.status, 1); + ss7_inservice(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc); + ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc, e->gra.status, 1); 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); @@ -9429,7 +9432,7 @@ static void *ss7_linkset(void *data) 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); @@ -9443,7 +9446,7 @@ static void *ss7_linkset(void *data) 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; @@ -9458,7 +9461,7 @@ static void *ss7_linkset(void *data) 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; @@ -9480,7 +9483,7 @@ static void *ss7_linkset(void *data) 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); @@ -9504,27 +9507,27 @@ static void *ss7_linkset(void *data) } 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; } p = linkset->pvts[chanpos]; - ss7_block_cics(linkset, e->cgb.startcic, e->cgb.endcic, e->cgb.status, 1); - isup_cgba(linkset->ss7, e->cgb.startcic, e->cgb.endcic, p->dpc, e->cgb.status, e->cgb.type); + ss7_block_cics(linkset, e->cgb.startcic, e->cgb.endcic, e->cgb.opc, e->cgb.status, 1); + isup_cgba(linkset->ss7, e->cgb.startcic, e->cgb.endcic, e->cgb.opc, 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; } p = linkset->pvts[chanpos]; - ss7_block_cics(linkset, e->cgu.startcic, e->cgu.endcic, e->cgu.status, 0); - isup_cgua(linkset->ss7, e->cgu.startcic, e->cgu.endcic, p->dpc, e->cgu.status, e->cgu.type); + ss7_block_cics(linkset, e->cgu.startcic, e->cgu.endcic, e->cgu.opc, e->cgu.status, 0); + isup_cgua(linkset->ss7, e->cgu.startcic, e->cgu.endcic, e->cgu.opc, 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; @@ -9537,7 +9540,7 @@ static void *ss7_linkset(void *data) 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; @@ -9550,7 +9553,7 @@ static void *ss7_linkset(void *data) 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; @@ -9562,7 +9565,7 @@ static void *ss7_linkset(void *data) 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; @@ -9575,7 +9578,7 @@ static void *ss7_linkset(void *data) 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; @@ -9593,7 +9596,7 @@ static void *ss7_linkset(void *data) 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); @@ -9611,7 +9614,7 @@ static void *ss7_linkset(void *data) } 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; @@ -9626,7 +9629,7 @@ static void *ss7_linkset(void *data) } break; case ISUP_EVENT_FAA: - chanpos = ss7_find_cic(linkset, e->faa.cic); + chanpos = ss7_find_cic(linkset, e->faa.cic, e->faa.opc); if (chanpos < 0) { ast_log(LOG_WARNING, "FAA on unconfigured CIC %d\n", e->faa.cic); break;