Summary:ASTERISK-02798: [patch] - Code to allow reverse polarity to indicate a hangup on the channel
Reporter:marty (marty)Labels:
Date Opened:2004-11-12 14:43:39.000-0600Date Closed:2008-01-15 15:24:43.000-0600
Versions:Frequency of
Environment:Attachments:( 0) 20050109-answeronpolarity.diff
( 1) 20050110-answeronpolarity.diff
( 2) chan_zap.c.HEAD-patch2
( 3) chan_zap.c.patch
( 4) chan_zap.c.patch2
( 5) chan_zap.c.patch-HEAD
( 6) chan_zap.c.patch-HEAD
Description:This patch adds code the chan_zap.c file, to allow it to pick up the Polarity Reversal events and process them to indicate the remote end has disconnected.

The code is controlled by two new options in the zapata.conf file, and by default, it is disabled.


One of my PSTN lines uses a Polarity Reversal to indicate that the remote end has disconnected. A TDM400P FXO module reports the Event to chan_zap.c, where it is prompty ignored.

The line also does a Polarity Reversal as the line goes off hook, so this code stores the time of the off hook event and when the polarity reversal event triggers, the timestamps are compared. If the duration is greater than the (configurable) allowed period, the signal is assumed to be a remote end disconnect and the channel is then hungup.
Comments:By: Brian West (bkw918) 2004-11-12 14:46:39.000-0600

Can you do one for CVS-HEAD? and do you have a disclaimer on file?

By: marty (marty) 2004-11-12 15:10:57.000-0600

HEAD patch added and no, I've no idea what the disclaimer is!

By: Clod Patry (junky) 2004-11-12 16:33:38.000-0600

then it's probably cause you didn't read the Bugs Guidelines document ( http://www.digium.com/bugguidelines.html ). Please read it.

By: Mark Spencer (markster) 2004-11-12 17:41:51.000-0600

Looks good, all we need is a disclaimer and maybe an example in zapata.conf.sample but I can make that for you if not.

By: marty (marty) 2004-11-13 02:51:15.000-0600

I must admit, I skimmed the bug guidelines file, and the disclaimer bit was overlooked - I've now got it printed out and will fax it when I get access to a fax machine.

If there is any other way of sending you the disclaimer other than fax, let me know - I'm more than happy to scan it in and email the image etc - I just don't own a fax machine!



By: Mark Spencer (markster) 2004-11-13 11:15:14.000-0600

You can e-mail me a scan, no problem (m a r k s t e r    a  t     d i g i u m   d o t   c o m)

By: richard (richard) 2004-11-13 12:32:46.000-0600

Hi Marty,

Thanks for this patch, it'll be very useful on one of my systems.

Just a thought for possible modification. On my lines, the polarity change is 1 -> -1 on going off hook and -1 -> 1 on hangup. Do you see this behaviour also?

I just wondered if this could be used to remove the delay/timestamp comparison. Currently although unlikely, it is possible for a call to be answered and the remote end to hangup inside the polarity answer delay, leaving the channel permanently off hook.



By: marty (marty) 2004-11-14 13:38:56.000-0600

Richard, due to my unfamiliarity with the source code of Asterisk and things telco related, I didn't even consider that it could be a +ve to -ve transition, or that the wcfxs driver would be passing that information into asterisk.

if someone can point me at where that info would be in the structures, I'll try it here and see what results I get.

BTW Richard/Mark, I pretty much dislocated my shoulder over the weekend in a mountain biking accident - as a result, typing is one handed and not high on my priority list as it just hurts!

Forgive me if I drop off the net for a day or so, it's not because I'm ignoring people, just because I'm in pain!



By: richard (richard) 2004-11-14 14:37:00.000-0600

Hi Marty,

As a fellow biker, I feel your pain ;)

Unfortunately I am no coder, but if you look at the function wctdm_voicedaa_check_hook() in zaptel/wctdm.c, there is this section of code:

if (wc->mod.fxo.polaritydebounce[card]) {
               if (wc->mod.fxo.polaritydebounce[card] < 1) {
                   if (wc->mod.fxo.lastpol[card] != wc->mod.fxo.polarity[card])
                       if (debug)
                               printk("%lu Polarity reversed (%d -> %d)\n", jif
                       if (wc->mod.fxo.polarity[card])
                           zt_qevent_lock(&wc->chans[card], ZT_EVENT_POLARITY);
                       wc->mod.fxo.polarity[card] = wc->mod.fxo.lastpol[card];

Hopefully this helps. My observations above were based on what I saw in my logs, when Mark initially added the polarity reversal code and I started seeing this in syslog:

Aug  5 11:32:44 pbxak kernel: 195829448 Polarity reversed (1 -> -1)
Aug  5 11:32:51 pbxak kernel: 195830194 Polarity reversed (-1 -> 1)
Aug  5 12:34:20 pbxak kernel: 196199038 Polarity reversed (1 -> -1)
Aug  5 12:34:27 pbxak kernel: 196199736 Polarity reversed (-1 -> 1)



By: richard (richard) 2004-11-14 14:58:41.000-0600

I have just realised I have been misinterpreting the CDR information in my situation; I get the the first reversal on call start and the second reversal on call answer - not hangup as I initially thought.

By: petersv (petersv) 2004-11-14 15:24:56.000-0600

The polarity is not really fixed since you don't know which wire is the A and B wire (tip and ring in the US?). I suspect the use of the polarity varies between countries.

As an example the Swedish pstn network uses polarity reversals to singnal the start of the caller id transmission (for incomming), remote answer supervision (for outgoing calls) and remote disconnects for both directions. These are defined in terms of "idle state" and "communications state".

I have included to show the kinds of information Asterisk ideally could handle.

For an incoming call:
 in idle state
 incoming call starts
 reverse to communcations state
 send caller id
 reverse back to idle state
 wait for pickup of the line
 reverse to communications state
 when the caller hangs up, reverse back to ilde olarity.

For an outgoing call:
 in idle state
 pickup handset
 wait for answer
 reverse to communications state on remote answer
 wait for remote hangup
 reverse to idle state on remote disconnect
See http://www.skanova.se/apps/file.asp?Path=2&ID=402&File=1%2D1551%2DLZBA+505+457+revB.pdf
for a reference to the swedish standard. Section 6.2 defines the states etc.

By: Mark Spencer (markster) 2004-11-16 07:41:47.000-0600

Hrm, if I apply the "head" patch on CVS head, it doesn't compile -- apparently because the declaration of polaritydelaytv is missing.  Is that the only thing missing from the patch?  Do you want to make a new one for CVS head just to be safe?

By: marty (marty) 2004-11-16 08:12:29.000-0600

Mark- fixed the missing definition in the patch - typo on my part when translating from the 1.0.2 version to the head version.

By: Mark Spencer (markster) 2004-11-17 01:18:06.000-0600

Added to CVS, thank you very much for your contribution!

By: marty (marty) 2004-11-18 04:51:37.000-0600

Problems with outgoing calls - sometimes I also get a polarity reversal when the remote end picks up, so I've added an extra clause to the if statement, to not try to remote end disconnection for outgoing calls.

new patches for stable and CVS ready to be uploaded.

By: marty (marty) 2004-11-18 04:52:47.000-0600

Problems with outgoing calls - sometimes I also get a polarity reversal when the remote end picks up, so I've added an extra clause to the if statement, to not try to remote end disconnection for outgoing calls.

new patches for stable and CVS ready to be uploaded.

By: marty (marty) 2004-11-18 04:54:15.000-0600

files *.patch2 for stable and HEAD uploaded - all they do is add an extra line to check to see if the channel is outgoing or not.

By: petersv (petersv) 2004-11-18 05:41:28.000-0600

This is normal, if you have answer supervision enabled. The handling of polarity reversals should be dependant on the state of the channel. If the channel is ringing (outgoing) it is (or may be) an answer supervision. If the channel is answered it is a disconnect supervision signal.

If the line is idle it is (or may be) the start of a caller id spill. If the caller id has been received it is (or may be) the end of the caller id transmission.

By: Mark Spencer (markster) 2004-12-04 19:32:59.000-0600

Is there always polarity reversal before answer?  and is there a difference between the polarity reversal for answer and hangup?

By: petersv (petersv) 2004-12-05 02:32:18.000-0600

There is a difference in as far as the changes are in opposite direction, from idle to communications state for the answer supervision and from comm. state to idle for hangup. These are defined in terms of "a-wire" and "b-wire" but which is which is allowed to change and so cannot be relied on. However, this is not a problem since the signal is unambigous anyway, see below. I have listed the actual polarity events as well.

These conditions should be applicable to all analoge pstn lines from the incumbent provider in Sweden (Telia).

If the line on hook (we are high ohmic) and we are not currently receiving CallerID and we have not just hung up the line the reversal can only signal the start of CallerID. (idle to comm)

If the line on hook and we are receiving CallerID the reversal can only signal the end of CallerID. (comm to idle)

If the line is off hook (low ohmic loop) and we are dialing out a polarity reversal means the other end has answered. (idle to comm)

If the line is off hook and we are answering an incoming call the revesal indivates that call is connected. (the other side did _not_ hangup before we answered). (idle to comm)

If the line is (off hook or on hook after a local hangup) and answered (answer supervision received) a reversal signals a remote hangup. (comm to idle)

By: marty (marty) 2004-12-05 10:24:03.000-0600


I get a polarity reversal whenever the call is answered - every time. If my initial patch is applied and the code enabled, you get call disconnect supervision when people hang up before you pick up, but if you try to pick up, it also drops the line!

What isn't clear is how those two events happen at the same time; I pick up just as the remote caller disconnects. What is clear, is that this is no worse than having no remote disconnect supervision. If I have no remote disconnect supervision, my line keeps ringing after the remote caller hangs up.

Patches above have been in production since they were posted here, and I've had no issues at all.



By: Olle Johansson (oej) 2004-12-19 07:44:37.000-0600

Where are we with this patch? Still needed for CVS head? Does it still apply?


By: marty (marty) 2004-12-19 07:58:32.000-0600

Yes, the patch still needs to be applied. Checked out latest CVS HEAD and it hasn't made it yet.

Without the 2nd patch, the polarity reversal on pick up will cause the line to
be hung up - not what the punters want.



By: Mark Spencer (markster) 2004-12-19 12:30:26.000-0600

Can you explain how this does not prevent a polarity reversal from hanging up an outbound call?  For example, If I make an outbound call which then gets dumped into a queue, for example, and then the person we called hangs up, how do we ever detect the hangup?

By: egnarf (egnarf) 2004-12-21 12:24:14.000-0600

I'm having the same problem, that outbound calls hang up when the called party answers..
What's the status on getting the fix into cvs?

By: marty (marty) 2004-12-21 14:00:49.000-0600

Mark, it's not a scenario I've thought about or tested; I don't know what Asterisk would do normally in this scenario, but the patch submitted wouldn't change the default behaviour.

While I understand you would like patches that consider all eventualities, all I can offer is that this patch adds the remote disconnect supervision for incoming calls and doesn't change the behaviour for outgoing calls - that is, providing this additional patch2 is applied.

If I get more time in the New Year, I'll look at the other scenario, but for now, with Christmas fast approaching, it's not high on the priorty list.

Sorry I can't be more supportive at the moment!



By: Mark Spencer (markster) 2004-12-21 18:29:02.000-0600

I appreciate your taking the time to try to work through this with me.

Are we talking about the same patch?  The patch I'm looking at (chan_zap.c.patch2) appears to just prevent polarity reversal from being viewed as a hangup on an outbound call, am I missing something?

By: egnarf (egnarf) 2004-12-22 01:17:00.000-0600

Every spec for polarity-reversal signalling i've read (all 3 of them =)) have some notion of "idle"-polarity and "reversed"-polarity.
Idle-polarity is when there is no active call, or callerid information sent.
reversed-polarity is during cid-transfer or an active call.

Couldn't we just make asterisk keep track of the polarity-state, and only hang up a channel if polarity switches from reversed to idle?
This should solve the outgoing-call problem since the first reversal would change the state to reversed-polarity. It should also work on incoming calls, since a local "pick-up" will result in a polarity-reversal thus moving us to reversed-polarity. It should also work with your (markster) queue-scenario, since it will detect remote hangups on outgoing calls also.

By: petersv (petersv) 2004-12-22 01:49:56.000-0600

One has to be careful since moste specs say that what actually is the idle polarity can change over time at the whim of the phone company. I think one can get by with using the old polarity at the first polarity event during a call as the idle polarity and use that as the idle polarity for the duration of the call.

If the phone company changes polarity in the middle of the night then we would see a false cidstart and timeout (if using polarity cidstart) or a idle->communication polarity switch without any ringing and again timeout. The next actual call would then get the correct idle polarity.

By: egnarf (egnarf) 2004-12-22 02:20:53.000-0600

Actually my switches DO that =)
Well, not switch polarity actually, but the line-test has a nasty habit of triggering the polarity-detector so I see it at least daily.
The cid times out properly though so it is a non-issue.

As per my suggestion, it is as you say that asterisk shouldn't care about the actual polarity. Only to keep track of the state right now. So if we are idle and detect a reversal we are reversed. After the next reversal we are idle again, and after the call is completed the state is forced to idle for that channel, so we never have asterisk believing we are in reversed-state if we are not actually in a call.
So if some telco wants to annoy me by changing polarity to break my pbx (they are evil. EVIL i tell you!! =)) it won't work.

Now, I actually have a patch for it that I wrote some months ago, but didn't submit due to lack of time and lack of knowlege about chan_zap.
It doesn't work with cvs-head, but if anyone wants to adapt it it's at "http://evil.gnarf.org/creativity/asterisk/20040831-polarity_disconnect.diff"

I can do it myself if markster finds it to be a worthy approach. But I'll be busy for 2-3weeks so it won't be done before that.

By: petersv (petersv) 2004-12-22 02:28:42.000-0600

I think some heurustics are needed to determine which polarity is the idle polarity. I can think of two situations in which Asterisk could get it wrong:

* the telco exchanges the A and B lines (tip, ring in the US)
* asterisk is started when a cid spill is in progress

I think a good rule would be that if asterisk thinks it is idle, it should pick up the current polarity as the idle polarity. If nothing else then the next ring will set things straight.

If this is deemed to invasive in the current code then perhaps a new signalling form should be added, similar to the currenct fxs_* ?

By: marty (marty) 2004-12-22 03:37:12.000-0600

Mark, yes that is what this additional patch2 does - I didn't know the spec's of what a polarity reversal indicated on an outgoing call, so just ignored it.

As I said before, without the patches I've submitted, Asterisk would ignore it anyway, so you are no worse off!

From the information added to the bug by the other folks, it's clear that my simplistic approach isn't the final solution; it does give us remote end supervision for incoming calls, but not outgoing.

Are we better off getting this one closed and opening a new one for outgoing polarity reversal events ? Sounds like there are knowledgeable people about
who could make this happen.


By: egnarf (egnarf) 2004-12-22 03:41:11.000-0600

The first problem (exchange a/b) isn't a problem with the approach I have in mind, because that will cause the CID-code to timeout and when it has timed out it destroys the channel and resets to idle-polarity.

If asterisk is started during a cid-spill the following will happen:
When the cidspill ends a polarity-reversal,marking the end of the spill, will trigger the cid-detector. Directly after that the ring-signal will end the cid-detector and start the simple_switch and run your exten => s, thus the call is received as it should be but without cid. The only thing is that we need to ensure that we reset the polarity-state to idle when we receive the ring, or else the reversal marking that the call has been established will hangup asterisk. But even in this case asterisk should just drop this call, and then "get it right" later, because when the call is disconnected another reversal will be detected, causing the cid-detector to start and time out and after this asterisk should again be in sync with the pstn.

Your case 1 has been tested with my old patch, case 2 hasn't though.

By: Mark Spencer (markster) 2004-12-28 17:53:35.000-0600

How about a "answeronpolarityswitch" option which considers the line to be answered when there is a polarity switch?  then hungup on the next one?

By: egnarf (egnarf) 2004-12-29 04:14:09.000-0600

I tried that method when I wrote my old patch a couple of months ago.
There were some problems with it though:
* You must have busydetect=on, or else you never know when it was busy. This is not really a problem since busydetect seems to work flawlessly here.
* When dialing a GSM-phone that was turned off or out of range the PSTN plays you a message saying that the number cannot be reached at this time. Unfortunately this does not trigger a polarity-reversal, so asterisk just kept indicating ringing. So the channels should still be bridged immediately, and we could use the polarity-reversal to indicate an answer for CDR-purposes, and for keeping track of which reversal indicates hangup.

By: petersv (petersv) 2004-12-29 05:36:12.000-0600

The problem with missing in band progress messages should be orthogonal to if polarity reversals are used for answer supervision. In band progress messages are used on isdn lines as well.

I think Asterisk passes audio while dialing unless asked to provide ringing itself, or musiconhold. At least it already is for isdn lines. There should be no difference in this respect between an isdn line and a pots line with answer supervision.

By: Mark Spencer (markster) 2004-12-29 07:29:32.000-0600

We pass audio anyway even before we detect answer condition.  I'd definitely like to see an option to have polarity reversal = answer as well!

By: egnarf (egnarf) 2004-12-30 03:45:31.000-0600

Then you shall have it! =)
In 2 weeks or so when I have spare time again...
Unless someone beats me to it.

By: Mark Spencer (markster) 2005-01-06 00:45:30.000-0600

Just thought I'd see how it was going :)

By: egnarf (egnarf) 2005-01-06 05:47:13.000-0600

Still busy.
I'll try to get it done this weekend though. =)

By: egnarf (egnarf) 2005-01-09 14:18:56.000-0600

Uploaded a patch against CVS HEAD implementing more or less what I promised =)
It does the following:
* Keeps track of the "state" of the polarity. We can be in IDLE or REVERSED polarity. The patch keeps track of the switches, and also resets the polarity to idle when a channel is destroyed, thus ensuring that we are always in sync with the PSTN. It should handle the case when the PSTN switches polarity on us by invoking the CID-detector, timing out and then reseting to IDLE when the channel is destroyed.
* Uses a switch from IDLE-polarity to REVERSED to indicate that the call has been answered if 'answeronpolarityswitch=yes' is in zapata.conf

NOTE! This patch has not been heavily tested.
Please test it alot!

Disclaimer is on file.

By: Mark Spencer (markster) 2005-01-09 14:33:09.000-0600

I would think that polarity should be in zt_pvt, not zt_subchannel since there is really only one per actual channel.  Other than that this *looks* great.  Would like to get some more testing feedback if possible before committing.

By: egnarf (egnarf) 2005-01-10 12:57:41.000-0600

Patch updated according to marksters wishes.

Please test it and post success stories and problems here.

By: Mark Spencer (markster) 2005-01-13 00:00:04.000-0600

Okay looks good to me, just waiting for feedback on the testing.  If I don't hear anything negative (or if i don't hear anything at all) I guess we'll try it out in head and see what happens :)

By: egnarf (egnarf) 2005-01-14 04:10:47.000-0600

This patch has been running on my system for almost a week now without any problems.
Could someone else try it and report success/failure?

Markster, give it another week or so and if nothing comes up I think it should be tried out in HEAD.

By: egnarf (egnarf) 2005-01-26 08:22:24.000-0600

There are no problems reported so far.
I've been running it for a little over 2 weeks without problems.
I think it is ready for head now.

Disclaimer is on file.

By: Mark Spencer (markster) 2005-02-08 01:49:15.000-0600

New part merged in CVS, thanks!

By: Digium Subversion (svnbot) 2008-01-15 15:14:06.000-0600

Repository: asterisk
Revision: 4275

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

r4275 | markster | 2008-01-15 15:14:06 -0600 (Tue, 15 Jan 2008) | 2 lines

Merge polarity reversal hangup patch (bug ASTERISK-2798)



By: Digium Subversion (svnbot) 2008-01-15 15:24:43.000-0600

Repository: asterisk
Revision: 4985

U   trunk/channels/chan_agent.c
U   trunk/channels/chan_zap.c
U   trunk/configs/zapata.conf.sample

r4985 | markster | 2008-01-15 15:24:43 -0600 (Tue, 15 Jan 2008) | 2 lines

quicky agent formatting fix, merge polarity/answer patch (bug ASTERISK-2798)