Search code examples
iosobjective-cvoippjsip

Incoming cellular call interrupting a VoIP call in my iOS App


I am using PJSIP (with the help of PJSUA) to implement some VoIP functionality in my app. When a VoIP call in my app is in progress, I can easily hold the call and then unhold it with no problems at all, everything is fine. I have used CoreTelephony to identify an incoming cellular (normal) call, when a call comes I hold my VoIP call in applicationWillResignActive and when that ends I unhold (reinvite) my VoIP call in applicationDidBecomeActive. Everything seems to be working fine (Since I have logs almost everywhere) but my call after coming back from cellular call has no longer any media transmitting, so the call is going on but I can hear no sound on any end. After 30 seconds I get disconnected (I configured a 30 seconds timeout for not having a media on my server which gets called here.). I would really appreciate any possible info or maybe something I'm missing. Thank you all in advance.


Solution

  • As this wiki:

    http://trac.pjsip.org/repos/wiki/Getting-Started/iPhone?format=pdf

    of pjsip explains, with iOS7 onwards pjsua is using high level APIs of AVAudioSession to manage opening and closing of sound streams which doesn't allow the older methods of (automatically) reconnecting your media streams after GSM call (or any other sound) interruptions. So to make it work you need to do following:

    • Your application should be configured to receive interruption events, which will already be the case if you are using sound or VOIP as your UIBackgroundModes. If not then use the following to receive interruptions:

      [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

    • forcefully shutdown the sound device when interruption begins. Use pjsua_set_no_snd_dev() for pjsua, or AudDevManager.setNoDev() for pjsua2

    • When interruption ends set your AVAudioSession to active and then restart the sound device using pjsua_set_snd_dev() for pjsua, or AudDevManager.setPlaybackDev()+setCaptureDev() for pjsua2

    The parameters needed to send to pjsua_set_snd_dev() can be extracted using the method pjsua_get_snd_dev().

    One thing to keep in mind here is that once you shutdown the device forcefully it will not start automatically (even if a new call starts) unless you call pjsua_set_snd_dev() to restart it again