Use keepalive for device status instead of qualify?

I am using Asterisk (13) to provide SIP/Voice for an app running on iPhones - they are all connected via wifi and TCP as transport, and in general this works great.

But wifi is not always reliable, and when someone walks out of coverage I like asterisk to find out reasonably fast, Today I am using qualify for this, in the dialplan it fails nicely to CHANUNAVAIL without any issues, and I can use ${DEVICE_STATE(SIP/xxx) to check status programmatically.

iPhones are slow when an app is background and screen off - we often see a TCP packet taking 1 to 2 seconds to go from “the air” to the App, we assume this is some iPhone power saving mechanism in the OS - by adjusting qualify=yes to qualify=4000 we have overcome the majority of the iphone-latency stuff.

One of the other issues is that qualify creates is overhead - with a few thousand registered peers it will add up.

I have been reading about and experimenting with turning qualify off and using keepalive - but the issue is that it doesnt affect the dialplan that I can see, and I can’t find a way to find a “bad” status without actually parsing logs.

In the logs/console I see this when a device App gets killed (meaning socket closed without deregister):
[2016-02-16 13:48:02] WARNING[31258]: chan_sip.c:29304 sip_send_keepalive: sip_send_keepalive to 172.16.254.167:49231 returned 0: Success

If i try a call to this user i see this message:
[2016-02-16 13:48:18] WARNING[10939][C-00000003]: chan_sip.c:3740 __sip_xmit: sip_xmit of 0x7f3e8400c780 (len 914) to 172.16.254.167:49231 returned -2: Broken pipe

but it still rings for the Ringtimer timeout.

So the first thing that is weird is that what should be a broken tcp is actually “success” but shown as a warning - if the device app is alive it shows nothing.

So it appears that keepalive is purely for NAT helping - but I wonder if there would be a fairly simple way to figure out a way to “grab the keepalive status” in the dialplan?

Or if perhaps there are some other options I dont know about - basically It would be awesome to get something to work the way CUCM does, it does not qualify, but it knows quite quickly if a wifi phone goes offline…

I am not a C programmer btw - but if there are some patches out there that can do this kind of stuff I’ll try it out :slightly_smiling:

guessing silence mean there is no such stuff widely known…

does developers visit this forum? wondering if such a change is trivial, I may be able to fund someones work to implement something, but I need to have an idea from asterisk-experienced devs on what kind of effort it would take so I can ask for project funding and make a scope contract etc…

i haven’t tried PJSIP - i wonder if I would have more options there…

Both chan_sip and chan_pjsip don’t treat the existence of the TCP connection as proof that the other side is unreachable. In chan_sip the TCP connection is directly associated with the peer so it’s easier to potentially add said functionality but I haven’t been in that area in awhile. chan_pjsip however is different in that area. It has a proper transport layer and doesn’t directly associate things. The way you associate them there is by looking at the target SIP URI and seeing that the IP address+port match an active connection. That being said PJSIP provides the ability to insert yourself to know when connections are opened and dropped[1]. The functionality could be extended to take that into account, but it probably wouldn’t be a good idea to change behavior and have it as the default.

[1] http://www.pjsip.org/pjsip/docs/html/group__PJSIP__TRANSPORT.htm#ga6e78c2f74cf0813dbe2a3af73ebf11ee

Thank you jcolp - so if I understand it correctly - with pjsip it sounds like it would be possible to plug in a custom “module-or-something” or perhaps a patch to pjsip with a callback function that could maintain some stateflag within asterisk accessible from the dialplan in some fashion - hopefully in a manner useful to others as well.
we have developers in house but none of them are experienced with asterisk development - i may try write some scope like stuff and inquery for some options/guestimates

I’d expect most people would want it as an extra option to extend the normal qualify support. There should be no changes required to PJSIP itself, it’d be extra functionality in Asterisk.

Great - so it should be doable to make a patch that would conform to Asterisk-standard and possibly make it in to the asterisk code base eventually.

This may be the wrong forum for this discussion now, thinking of how to write this scope - would it be appropriate to have the event handling mechanism maintain the same flags where DEVICE_STATE function gets its data from? (To me that makes sense but there may be reasons not to do that which I dont know about) or should it be a separate something?
If so, should it also have some config option somewhere - like “device_state_source=qualify” as default or similar

You don’t need to mess with stuff like that. The qualify support is self contained in res/res_pjsip/pjsip_options.c and provided you use the same interface to update the Contact status it will automatically flow through to everything else and be reflected there.