As a school project, I’m working on an Android real-time text (RFC 4103) app using the NIST JAIN SIP builds for Android. My professor pointed out that all the problems I was having are probably going to trip up somebody else later, so I should document them. So, internet, here is your first installment of problems I’ve faced that you hopefully won’t. I’m a number of weeks into this project already, so I’ll need to go back and write up everything I’ve already solved. Using JAIN SIP on Android certainly involves some contortions that don’t come up in standard JAIN tutorials.
AsteriskNOW is a handy all-inclusive open-source PBX package (SIP/RTP server). Install it in a VM and you instantly have a SIP server, not too much configuration required. The configuration you do have to do has a bit of a learning curve because it is so full-featured, but overall it seems pretty nice. The help tooltips of the many, many configuration options in the FreePBX web interface leave something to be desired, but I got a couple users working before too long (hint: most of what you need is under Applicatons > Extensions, and you will want to consult Reports > Asterisk Logfiles > fail2ban to see logging of REGISTER attemps).
Because Omnitor’s RTT reference implementation SIPCon1 doesn’t seem to understand 401 and digest authentication, it has trouble registering to a modern server. If there’s some way to force Basic authentication in Asterisk, I’m not sure how. A useful Stackoverflow post by one of the Asterisk developers, Olle E. Johansson, indicated that leaving blank the “secret” for an extension disables authentication entirely for that user, so that works to get SIPCon1 talking to Asterisk.
However, another problem with Asterisk stems from the fact that it is a back-to-back UA. Thanks to Omnitor and Olle E. Johansson (who apparently also happens to be from Sweden), Asterisk can speak T.140 (RFC 4103) in its role as a B2BUA, but a surely unintentional hearing bias shows through its design. As Gunnar Hellström pointed out on the development mailing list in May 2014, Asterisk will immediately drop any call that does not include a negotiated audio stream. I encountered this same issue myself this week when trying to offer a text-only session to SIPCon1 from my own app. Not having used SDP before, it took me a little while to get JAIN SDP to cooperate (more on that later), but eventually I did:
INVITE sip:firstname.lastname@example.org SIP/2.0
CSeq: 1 INVITE
Via: SIP/2.0/UDP 192.168.1.103:5060;branch=z9hG4bK-323734-97510ab0f8dfe28e37a44d62bc8a144c
Allow: ACK, BYE, INVITE, OPTIONS, CANCEL
o=201 2122197558 1 IN IP4 192.168.1.103
c=IN IP4 192.168.1.103
m=text 5061 RTP/AVP 100
I think this should be fine. I should also support t140 red, but I’ll worry about that later. I’m pretty sure SIPCon1 would accept this. But Asterisk never gives it the chance, because it assumes every call must have audio. It’s strange that it accepts the call and only then sends an immediate BYE, rather than simply responding 488 Not Acceptable. I think RFC 3261 says that when the original offer is sent with the 200 OK, and the offer is not acceptable, the caller should still send the ACK and then send an immediate BYE, which is similar to what is happening here, but not quite. If Asterisk doesn’t want to accept my text-only session, it should tell me so with 488. Whatever. Luckily Gunnar’s email helped me understand that I’m not crazy and my SDP actually was working correctly.
So Asterisk is out. Instead I tried sipXcom, which is a regular proxy. It’s pretty good so far, but is not without its own problems. Using VMWare Fusion 8.1, I got it running fairly quickly, faster than Asterisk, but ran into some quirks. It basically assumes you are using hardware phones, and when setting up a new extension, the only way around this is to say your new phone is “Jitsi”. In fact I have been using Jitsi for testing INVITEs, but to claim that all softphones must be Jitsi is a little silly. Anyway, a bigger problem is that after suspending and restoring the VM, all attempts to register got an immediate 408 Request Timeout. How could you issue 408 immediately? My Expires: header was 600, and the only 600 that could have passed in that time was maybe 600 microseconds. Rebooting fixed it.
The final problem with sipXcon for my purposes is that it doesn’t allow you to leave a user’s password blank, or otherwise disable authentication. This is a totally sensible security feature, but in this rare case, I actually do want the freedom to do this. Or at least, I’d like to use Basic authentication instead, since SIPCon1 can probably manage that. It might be possible to do at least one of these by editing a configuration file, but the web interface doesn’t seem to give an easy way. I’ll look into that later. For now I can call my app from SIPCon1, with SIPCon1 still connected to Asterisk and my app going through sipXcom.