Skip to main content

Workflows

Initialization

In order to use the Cloudonix Mobile SDK in your application, it must first be initialized with the license key (which you receive from Cloudonix, either a trial or a production license key). The application would load the license key into the Cloudonix Mobile SDK in order to retrieve an instance to the Cloudonix Mobile SDK control object (commonly called “cxClient” in this guide). This process will verify the license, configure the SDK for the device by utilizing Cloudonix on-line device configuration service and will eventually issue the onLicense event, which can be monitored by the application to check if the licensing process completed successfully. If the licensing process failed - for example if the license key is corrupt or has expired - then the SDK will not be operational.

After initializing the SDK, it needs to be configured with configuration parameters such as allowed codecs and transports, in addition to setting the SIP account details that will be used for calling and receiving calls.

After receiving the SDK client instance, the application should perform these additional steps:

  1. Call addEventsListener() to be able to receive events from the SDK using callbacks on a IVoIPObserver instance.
  2. Use setConfig() to set up the SDK.
  3. Call bind() to create (if needed) and connect to the SDK service. After that process is complete, the SDK will fire the onLicense() event with LicensingState set to LICENSING_SUCCESS to let the application know that the service is ready and licensed correctly.
  4. Use setConfiguration() to setup the SIP account registration information.
  5. The setConfiguration() call will instruct the SDK to setup the SIP stack and when the process is complete, the SDK will fire the onSipStarted() event.
  6. Once onSipStarted() is called, the application can start communication flows such as registering and dialing.
Example Initialization
public void initCloudonixSDK(Context ctx) {
InputStream lic = ctx.getResources()
.openRawResource(R.raw.cloudonix_license_key);
try (BufferedReader buffer = new BufferedReader(
new InputStreamReader(lic))) {
cxClient = CloudonixSDKClient.getInstance(buffer.lines()
.collect(Collectors.joining("")));
cxClient.addEventsListener(this);
cxClient.setConfig(ConfigurationKey.USER_AGENT, "MyApp/1.0");
cxClient.bind(ctx); // will cause onSipStarted to be called
} catch (IOException e) {
return;
}
}

@Override
public void onLicense(LicensingState licensingState, String description){
If (licensingState != LicensingState.LICENSING_SUCCESS) {
Log.e("AppName", "License error: " + description);
return;
}
cxClient.setConfiguration(new RegistrationData() {{
setServerUrl("sip.cloudonix.io");
setPort(5060);
setTransportType(TRANSPORT_TYPE_UDP);
setDomain("example.com");
setUsername("rowdy");
setPassword("rawhide");
setDisplayName("Rowdy Rawhide");
}});
}

Registration Modes Setup

The Cloudonix Mobile SDK supports both classic SIP accounts using periodic REGISTER messages to maintain a “connection” to the server, as well as Cloudonix Registration-Free mode.

Registration Mode

In a classic SIP registration use case, the application should:

  1. Make sure the RegistrationData contains the correct username, password and domain during the configuration step.
  2. In order to receive calls, call registerAccount() after the Cloudonix Mobile SDK notifies the application that the SIP stack has started through the onSipStarted() event.

After calling registerAccount() the Cloudonix Mobile SDK will fire the onRegisterState() event whenever the registration state changes. The application can also call isRegistered() to check the registration status.

Please note that for the registerAccount() call to succeed, the user authorization credentials should have already been set using the setConfiguration() call.

Regardless if the application has called registerAccount() or not, after the SIP stack was started, the application may call dial() or dialWithHeaders() to start a call using the configured user authorization credentials.

Example Registration

@Override
public void onLicense(LicensingState licensingState, String description) {
cxClient.setConfiguration(new RegistrationData() {{
setDomain("example.com");
setUsername("rowdy");
setPassword("rawhide");
// …
}});
}

@Override
public void onSipStarted() {
cxClient.registerAccount();
}

@Override
public void onRegisterState(RegisterState result, int expiry) {
switch(result) {
case REGISTRATION_SUCCESS:
Log.d("AppName", "registered");
break;
case REGISTRATION_ERROR_CREDENTIALS:
Log.d("AppName", "auth error");
break;
case REGISTRATION_UNREGISTERED:
Log.d("AppName", "No longer registered");
break;
}
}

Registration-Free mode

In a Registration-Free use case, there is no need for the application to perform SIP registration as call reception is handled by the application backend using push notifications, and there is also no need to set user authorization credentials as the application will be authorizing each call separately using a Cloudonix session token.

During initialization, make sure that the CloudonixRegistrationData object contains the correct SIP account details (including SIP domain name and transport details, though username and password should not be set) and send it to the CloudonixSDKClient using the setConfiguration().

At any point after the Cloudonix Mobile SDK fires the onSipStarted() event. The application can dial or receive calls, using the dialRegistrationFree(number, token) method.

Dialing Workflows

Dialing In Classic Registration Mode

After the application completes setting up the SDK and configuring the SIP account details, the application may use the dial() command to start a SIP session.

The dial command will start the calling process and will cause the Cloudonix SDK to issue onCallState() events for each stage in the calling process.

Example Dial in Registration Mode

public boolean dial(String number) {
Log.d(TAG, "dial: " + number);
if (!cxClient.isRegistered()) {
return false;
}
cxClient.dial(number);
return false;
}

@Override
public void onCallState(String key, CallState callState, String contactUrl) {
switch (callState) {
case CALL_STATE_STARTING:
Log.d(TAG, "Starting call " + key + " to number: " + contactUrl);
break;
case CALL_STATE_CONNECTING:
Log.d(TAG, "Connecting call " + key + " to number: " + contactUrl);
break;
case CALL_STATE_CALLING:
Log.d(TAG, "Calling call " + key + " to number: " + contactUrl);
break;
case CALL_STATE_RINGING:
Log.d(TAG, "Ringing call " + key + " to number: " + contactUrl);
break;
case CALL_STATE_CONFIRMED:
Log.d(TAG, "Connected call " + key + " to number: " + contactUrl);
break;
case CALL_STATE_DISCONNECTED:
case CALL_STATE_DISCONNECTEDDUETOBUSY:
case CALL_STATE_DISCONNECTEDMEDIACHANGED:
case CALL_STATE_DISCONNECTEDDUETONETWORKCHANGE:
case CALL_STATE_DISCONNECTEDDUETONOMEDIA:
case CALL_STATE_DISCONNECTEDDUETOTIMEOUT:
Log.d(TAG, "Hanged up call " + key + " to number: " + contactUrl);
break;
default:
break;
}
}

Dialing in Registration-Free Mode

After the application completes setting up the SDK and configuring the SIP account details (usually just the SIP server address and domain name), the application may start a Registration-Free dial by obtaining a session token from application backend (please refer to the Cloudonix Registration-Free Dialing specification for more details) and then use the dialRegistrationFree(number, token) method to start a call.

It is also possible to set up the SIP stack only right before making a call (or receiving a call). This is useful in case the application manages multiple subscriber accounts and knows which account to use for a call only at the last second. In such a case it is important to wait for the onSipStarted() event before issuing the dial call, for example:

Example Dial in Registration-Free
private void dial(String msisdn, String token, RegistrationData regdata) {
// listen for Cloudonix SDK events
cxClient.addEventsListener(new IVoIPObserver() {
@Override
public void onSipStarted() {
cxClient.dialRegistrationFree(msisdn, token);
cxClient.removeEventsListener(this);
}
});
cxClient.setConfiguration(regdata);
}

Incoming Calls

Call Reception in Registration Mode

When a call is received, the onCallState() event will be invoked with the CallState set to CALL_STATE_INCOMING. When the application handles the event, it can call either answer(callId) or reject(callId) as required. See Call Maintenance below for additional explanation of the onCallState() event.

Example Answering Incoming Classic Call

@Override
public void onCallState(String key, CallState callState, String contactUrl) {
Switch (callState) {
case CALL_STATE_INCOMING:
cxClient.answer(key);
break;
// …
}
}

Call Reception in Registration-Free Mode

When a push notification for an incoming call is received, containing a Registration-Free call token, the application should make sure that onSipStarted() has already been received, and then use the dialRegistrationFree(msisdn, token) call to accept the call.

Please note that the phone number provided in the first parameter can be of any value (the token is the only value that determines the success of receiving the call), but its value must never be set to null.

Call Maintenance

During the life of a call, from beginning to end, the Cloudonix Mobile SDK will call the client’s onCallState() event handle multiple times passing the call identifier (“key”), the updated call state and the remote side's address (the destination for an outgoing call, the origin for an incoming call). The event listener should examine the call state and perform actions to reflect the current state of the call to the user, as needed.

Normally a client is expected to handle at least the following call states:

  • CALL_STATE_INCOMING - The client should display a UI to indicate that a call is incoming and later use the Cloudonix Mobile SDK’s answer() method to pick up the incoming SIP call.
  • CALL_STATE_CONFIRMED - The client should display a UI to indicate the call is in progress and offer additional UI to the user to perform call operations (such as hanging up).
  • CALL_STATE_DISCONNECTED (and all its variations) - The client should recover and reset all resources used to handle the call and remove any “in call” UI.

See the “Call States” reference table, at the end of this document, for a complete list of possible call states and what they mean. Please note that there are various "disconnected" call states that are used to report an error that have caused the call to be disconnected, though in all cases the CallState_Disconnected event will eventually be delivered as well.

Sending DTMF

It is common for users to want to send DTMF signals to the remote end, to signal that the user has pressed on a standard numeric keypad during the call. The client can use the Cloudonix Mobile SDK’s DTMF() method. The method call receives the call ID of the call on which to send DTMF signals, and a character representing the DTMF signal to send.

Example Sending DTMF

public void sendDTMF(char c) {
cxClient.DTMF(this.currentCallId, c);
}

Application Shutdown

It is important to note that when the application is moved to the background, the SDK will still maintain context to allow the application to receive calls. If the application needs to shut down completely and not receive any calls, it should call shutdown(), after which the SDK is completely shut down and in order to start it again it needs to be reinitialized.