Merge polarity reversal hangup patch (bug #2847)
authorMark Spencer <markster@digium.com>
Wed, 17 Nov 2004 06:18:33 +0000 (06:18 +0000)
committerMark Spencer <markster@digium.com>
Wed, 17 Nov 2004 06:18:33 +0000 (06:18 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4275 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_zap.c
configs/zapata.conf.sample

index 06b6599..3f0f7e6 100755 (executable)
@@ -268,6 +268,12 @@ AST_MUTEX_DEFINE_STATIC(iflock);
 
 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,9 @@ static struct zt_pvt {
        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;
@@ -2296,6 +2305,9 @@ static int zt_answer(struct ast_channel *ast)
        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 +3707,31 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                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);
        }
@@ -6589,6 +6626,9 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
                        if (si.alarms) tmp->inalarm = 1;
                }
 
+               tmp->polarityonanswerdelay = polarityonanswerdelay;
+               tmp->hanguponpolarityswitch = hanguponpolarityswitch;
+
        }
        if (tmp && !here) {
                /* nothing on the iflist */
@@ -9711,6 +9751,10 @@ static int setup_zap(int reload)
                                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);
index aef8df6..5e87cd7 100755 (executable)
@@ -310,6 +310,12 @@ immediate=no
 ;
 ;busycount=4
 ;
+; In some countries, a polarity reversal is used to signal the disconnect
+; of a phone line.  If the hanguponpolarityswitch option is selected, the
+; call will be considered "hung up" on a polarity reversal
+;
+;hanguponpolarityswitch
+;
 ; On trunk interfaces (FXS) it can be useful to attempt to follow the progress
 ; of a call through RINGING, BUSY, and ANSWERING.   If turned on, call
 ; progress attempts to determine answer, busy, and ringing on phone lines.