--- chan_zap.c.orig Fri Nov 12 20:58:52 2004 +++ chan_zap.c Fri Nov 12 21:08:40 2004 @@ -268,6 +268,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 = 600; + /* 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); @@ -552,6 +558,8 @@ 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; #ifdef ZAPATA_PRI struct zt_pri *pri; struct zt_pvt *bearer; @@ -2296,6 +2304,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; @@ -3695,6 +3706,31 @@ 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); } @@ -6567,6 +6603,9 @@ if (si.alarms) tmp->inalarm = 1; } + tmp->polarityonanswerdelay = polarityonanswerdelay; + tmp->hanguponpolarityswitch = hanguponpolarityswitch; + } if (tmp && !here) { /* nothing on the iflist */ @@ -9689,6 +9728,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);