--- chan_zap.c.orig Wed Nov 10 22:57:32 2004 +++ chan_zap.c Fri Nov 12 20:42:21 2004 @@ -264,6 +264,12 @@ static int ifcount = 0; +/* Whether we hang up on a Polarity Switch event */ +static int hanguponpolarityswitch = 0; + +/* How long (ms) to ignore Polarity Switch events after we answer a call */ +static int polarityonanswerdelay = 500; + /* Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. */ AST_MUTEX_DEFINE_STATIC(monlock); @@ -543,6 +549,9 @@ int dtmfrelax; /* whether to run in relaxed DTMF mode */ int fake_event; int zaptrcallerid; /* should we use the callerid from incoming call on zap transfer or not */ + int hanguponpolarityswitch; + int polarityonanswerdelay; + struct timeval polaritydelaytv; #ifdef ZAPATA_PRI struct zt_pri *pri; struct zt_pvt *bearer; @@ -2286,6 +2295,9 @@ case SIG_FXOKS: /* Pick up the line */ ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); + if(p->hanguponpolarityswitch) { + gettimeofday(&p->polaritydelaytv, NULL); + } res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); tone_zone_play_tone(p->subs[index].zfd, -1); p->dialing = 0; @@ -3659,6 +3671,33 @@ break; } break; + case ZT_EVENT_POLARITY: + /* + * If we get a Polarity Switch event, check to see + * if it should be ignored (the off-hook action seems + * to cause a Polarity Switch) or whether it is an + * indication of remote end disconnect, in which case + * we should hang up + */ + + if(p->hanguponpolarityswitch && + (p->polarityonanswerdelay > 0) && + (ast->_state == AST_STATE_UP)) { + + struct timeval tv; + gettimeofday(&tv, NULL); + + if((((tv.tv_sec - p->polaritydelaytv.tv_sec) * 1000) + ((tv.tv_usec - p->polaritydelaytv.tv_usec)/1000)) > p->polarityonanswerdelay) { + + ast_log(LOG_DEBUG, "Hangup due to Reverse Polarity on channel %d\n", p->channel); + ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); + } else { + ast_log(LOG_DEBUG, "Ignore Reverse Polarity (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state); + } + } else { + ast_log(LOG_DEBUG, "Ignore Reverse Polarity on channel %d, state %d\n", p->channel, ast->_state); + } + break; default: ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel); } @@ -6516,6 +6555,8 @@ if (si.alarms) tmp->inalarm = 1; } + tmp->polarityonanswerdelay = polarityonanswerdelay; + tmp->hanguponpolarityswitch = hanguponpolarityswitch; } if (tmp && !here) { /* nothing on the iflist */ @@ -9584,6 +9625,10 @@ cur_rxflash = atoi(v->value); } else if (!strcasecmp(v->name, "debounce")) { cur_debounce = atoi(v->value); + } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { + polarityonanswerdelay = atoi(v->value); + } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { + hanguponpolarityswitch = ast_true(v->value); } else ast_log(LOG_WARNING, "Ignoring %s\n", v->name); v = v->next; @@ -9726,6 +9771,8 @@ adsi = 0; memset(drings,0,sizeof(drings)); strncpy(accountcode, "", sizeof(accountcode)-1); + polarityonanswerdelay=0; + hanguponpolarityswitch=0; #ifdef ZAPATA_PRI strncpy(idleext, "", sizeof(idleext) - 1); strncpy(idledial, "", sizeof(idledial) - 1); @@ -9986,6 +10033,10 @@ } else if (!strcasecmp(v->name, "idledial")) { strncpy(idledial, v->value, sizeof(idledial) - 1); #endif + } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { + polarityonanswerdelay = atoi(v->value); + } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { + hanguponpolarityswitch = ast_true(v->value); } else ast_log(LOG_WARNING, "Ignoring %s\n", v->name); v = v->next;