Version 9 (modified by bennylp, 16 years ago) (diff) |
---|
IP Address change and Symbian Access Point Reconnection Issues
Table of Contents
This article describes some issues and their corresponding solutions related to access point disconnection, reconnection, and change in your PJSIP applications. The general issues related to the discussion will be explained, along with some specific issues to Symbian applications.
Problem description
Access point disconnection and reconnection are scenarios that need to be handled in mobile applications. Few issues or scenarios related to this for example are:
- user moves outside the range of a Wi-Fi access point (AP) and lost the connection
- user moves outside the range of one AP and reconnect to another
- the handset may get new IP address if user reconnects to different AP
Each of the scenarios above may need different handling in the application.
Issues and solution related to IP address change
When the connection is reconnected, the handset may get different IP address than what it previously got. There are few ramifications of this, for example if PJSUA-LIB is used:
- the SIP registration needs to be updated with a new Contact URI
- the account URI also needs to be updated
- media addresses need to be updated
- if there is ongoing dialog, the remote party needs to be informed with new Contact URI as well as new media (RTP/RTCP) addresses.
Note that at this time of writing (2009/02/25, PJSIP v1.1), PJSIP does not have the capability to monitor the status of the underlying IP connection used by the application, so the application must implement the detection itself (for example using connection progress monitor in Symbian). Having said that, PJSIP does have some capability to detect some IP address change scenarios, for example by monitoring the IP address in SIP REGISTER response or in STUN Binding response when ICE transport is used and STUN is enabled.
Once the application has detected that the IP interface address has changed, there are two solutions to inform PJSIP about this.
Restart everything
The most straightforward solution is of course to restart everything, which means in pjsua terms to call pjsua_destroy() and followed by pjsua_create(), pjsua_init(), and so on. While this solution may sound crude, it is the easiest to do and as will be explained later it is not considerably worse then the more refined alternative.
Selective update
Alternatively there may be a way to allow the stack to continue to run, updating the address information when necessary. This approach will require some specific features to be used, as well as some actions by the application when it detects that the IP address has changed.
The specific configuration and tasks will be explained below. Note we assume that the SIP and media sockets are bound to INADDR_ANY (0.0.0.0) and not to a specific interface IP address (this is the default behavior).
Account Contact URI update
- Task:
- The account URI needs to be updated with the new address, and re-registration is necessary to inform the registrar about the new URI.
- Description:
- PJSUA-LIB has the capability to detect the (SIP) IP address change based on the response of REGISTER request and automatically update the registration with the correct IP if it detects that the IP/port seen by the server is different than the address specified in the Contact URI. This feature is enabled by default, via the pjsua_acc_config.allow_contact_rewrite setting.
So the solution is simply to trigger the re-registration by calling pjsua_acc_set_registration() function (after the new connection is up of course). The PJSUA-LIB will send re-REGISTER request, check the IP address/port in the response, and re-REGISTER again and update the account URI as necessary.
Media addresses update
- Task:
- The media (RTP/RTCP) addresses in PJSUA-LIB are normally determined during PJSUA-LIB startup, hence they need to be updated with the new address.
- Description:
- If ICE media transport is used, and STUN is enabled on the media transport, then the media transport will automatically update its publicly mapped IP address from the STUN Binding response. The transport should send STUN Binding request periodically (approximately every 15 seconds) as NAT keep-alive mechanism, so the address change will be detected by the transport automatically during this operation.
Note that at present there is no API to explicitly request the ICE media transport to initiate STUN Binding request immediately.
If ICE is not used, then at present there is no mechanism to update the IP address of media transport, nor the media transport will update its address even when STUN is used. The only solution would be to recreate the media transports and supply them to PJSUA-LIB with pjsua_media_transports_attach().
Call in progress issues
- Task:
- Dialog's Contact URI needs to be updated.
- Description:
- The dialog's Contact URI is set initially when the dialog is created, from the account's Contact URI. While at the PJSIP level the pjsip_inv_reinvite() allows changing of Contact URI via the new_contact argument, currently this feature is not used by PJSUA-LIB, i.e. the pjsua_call_reinvite() does not allow the application to change the Contact URI.
So this is an open issue.
- Task:
- Changing of RTP/RTCP media addresses of ongoing call
- Description:
-
If ICE is used, then new STUN srflx address will be signaled in updated SDP offer, as long as:
- ICE media transport has detected that the IP address has changed (via the keep-alive above), and
- the media was previously inactive, since if media has been active (hence ICE session is active), the SDP will contain only the used candidates and not all the list of candidates.
Alternatively, we may not need to inform the new RTP/RTCP address at all. If the remote media endpoint has the capability to switch its RTP/RTCP transmission to the source address of the RTP/RTCP packets (note: PJMEDIA has this capability), then it should automatically switch its destination address to our new address.
Symbian specific issues
Socket call get stucked after reconnecting to different access point (AP)
- Symptom:
- The library gets stucked in pjsua_destroy() when the application tries to destroy the stack when it detects that the AP connection is down.
This is a problem with the socket in general and not PJSIP. Below are steps to reproduce with a plain UDP socket:
- Create RConnection, call Start() to connect to AP
- Create UDP socket, call SendTo() to send a packet
- Disconnect the AP (Menu -> Connectivity -> Conn. mgr. -> Active data connections -> (highlight the AP) -> Options (menu) -> Disconnect).
- Call udp.SendTo() again
- AP selection dialog appears, select different AP
- WaitForRequest() to the udp.SendTo() operation now will get stuck for 1-2 minutes before tcpip6_error_NoRoute error (-5105) is returned.
- Now if you call udp.SendTo() again, now WaitForRequest() will get stuck indefinitely
The problem above does not occur if:
- the user selects the same AP. In this case the udp.SendTo() should complete successfully
- the user cancels the AP selection dialog. In this case the udp.SendTo() will fail immediately with KErrCancel without blocking the application.
- the socket is closed and re-opened. In this case the udp.SendTo() should complete successfully
As additional info:
- the problem still persists even if the RConnection is restarted (RConnection.Start() is called to select new AP) in between step 3 and 4 above.
Currently we don't have a solution for this, except to only use one AP (perhaps to select the AP when PJSIP is started and lock the RConnection that is assigned to PJLIB to this AP).