Enabling Application Level Roaming

Application-level roaming (ALR) enables your application to roam to use the best available data connection while operational.

Context

To use application-level roaming:

Steps

  1. Initiate an Internet connection using the Connection Manager API and the Internet destination network. In this example it is assumed that the best available access point for Internet is GPRS.

    RConnection handle is returned to the application.

  2. Register for mobility API sending NewL(RConnection handle, MMobilityProtocolResp&) to the Connection Manager API.

  3. Use Sockets Client API to open RSockets with RConnection handle.

    RSocket handle is returned to the application.

  4. Initiate normal socket communication to the Sockets Client API. This data transfer uses GPRS. A WLAN access point becomes available. The Connection Manager API sends PreferredCarrierAvailable(old access point, new access point, is upgrade, not seamless) to the application. The application decides to switch to the better access point. It closes the old socket using the Sockets Client API.

  5. Send MigrateToPreferredCarrier() to the Connection Manager API. Note: The application can also IgnorePreferredCarrier(). In that case it would just keep using the existing socket. The connection is moved in the Connection Manager API. The WLAN access point is activated and RConnection handle is moved from the GPRS interface to WLAN. NewCarrierActive(new IAP) is returned to the application. The WLAN access point is now ready to be used.

  6. Use Sockets Client API to open RSockets with RConnection handle. This data transfer uses WLAN.

  7. Transfer data using the Sockets Client API to confirm that the connection works.

  8. Send NewCarrierAccepted() to the Connection Manager API. This is the point of no return.

  9. Continue transferring data using the Sockets Client API. This data transfer uses WLAN.

Results

ALR is enabled.

Example

class CALRApplication : public CActive, public MMobilityProtocolResp
    {
...
    public: // From MMobilityProtocolResp
    void PreferredCarrierAvailable( TAccessPointInfo aOldAPInfo,
                                        TAccessPointInfo aNewAPInfo,
                                        TBool aIsUpgrade,
                                        TBool aIsSeamless );
  void NewCarrierActive( TAccessPointInfo aNewAPInfo, TBool aIsSeamless );
  void Error( TInt aError );
  private:    // Data
  RConnection  iConnection;
  CActiveCommsMobilityApiExt*   iMobility;
    };
// When the connection starts, iMobility is created and it registers the connection to receive mobility messages.
iMobility = CActiveCommsMobilityApiExt::NewL( iConnection, *this );When apreferred access point becomes available, the implementation of CALRApplication::PreferredCarrierAvailable is called. MigrateToPreferredCarrier Mobility message is sent to the middleware in order to roam to this preferred access point.
void CALRApplication::PreferredCarrierAvailable( TAccessPointInfo aOldAPInfo,TAccessPointInfo aNewAPInfo,TBool aIsUpgrade,TBool aIsSeamless ){
    // aOldAPInfo contains the current IAP used by the connection.
    // aNewAPInfo contains the newly available IAP that can be used by the connection.
 if ( aIsSeamless )
        {
        // It is Seamless. E.g. Mobile IP enabled.
        }
    else
        {
        // sockets used by the connection should be closed here.
        // We ask to migrate to the Preferred Carrier.
        iMobility->MigrateToPreferredCarrier();
        }
    }
Once the connection roamed to the new access point, the implementation ofCALRApplication::NewCarrierActive is called. The application reopens its sockets on the connection. If the socket connection is fine, the application sends the NewCarrierAccepted Mobility message to the middleware.

void CALRApplication::NewCarrierActive( TAccessPointInfo aNewAPInfo, TBool aIsSeamless )
    {
    // aNewAPInfo contains the newly started IAP used now by the connection.
    if ( aIsSeamless )
        {
        // It is Seamless. E.g. Mobile IP enabled.
        }
    else
        {
        // sockets used by the connection should be reopened here.
        // We accept the new IAP.
        iMobility->NewCarrierAccepted();
        }
    }