AJVoIP –Android Java VoIP SDK
with notification strings
Notification strings. 2
About 2
Package content 2
Requirements. 2
Usage. 4
Instructions. 4
Project configuration. 5
Example code. 5
Sample project 7
Features. 7
Licensing. 8
API 9
General considerations. 9
Functions. 9
Notifications. 24
Parameters. 32
Basic Parameters. 32
Advanced Parameters. 33
FAQ.. 67
Resources. 92
Important Note. 93
This is the old (but
still relevant) documentation using notification strings instead of SIPNotification
event objects.
You should use the new documentation instead if you are using SIPNotification
event objects.
For
maximum flexibility, the JVoIP SIP library implements also receiving the notifications as strings (instead of the new SIPNotification objects) with
the API_GetNotifications() or API_GetNotificationsSync() functions.
The most important
changes are in the Notification chapter and elsewhere where notification string parsing is
mentioned (for example here).
New versions of the
JVoIP library will keep full backward compatibility with notification strings
for the foreseeable future.
Example code:
https://www.mizu-voip.com/Portals/0/Files/AJVoIPTest_With_Notification_Strings.zip
In the above example the
notifications are handled as plain strings, not using the new SIPNotificationListener
with SIPNotification objects.
The Android Java VoIP
SDK (AJVoIP) is a SIP client library for the Android platform. Since it is
based on the open standard Session Initiation Protocol, it can inter-operate with any other
SIP-based device (servers and clients).
AJVoIP is an easy to use compact Android
SIP client library consisting of a single library file which have to be added
to your project (one single aar or jar file) containing a simple high-level API
(one single class).
With the Android SIP SDK
you have a compact but full featured SIP/media stack, easy to integrate with
any Android application.
It can be used to
develop a custom Android SIP client application or to add VoIP call
capabilities into any existing Android application.
The followings can be found
in the AJVoIP package:
·
The library
itself:
o
AJVoIP.aar
(Android Archive file to be used with Android Studio)
o
AJVoIP.jar (jar
file to be used with any other development environment such as Eclipse or
Embarcadero Delphi / C++ Builder)
·
Documentation:
o
SDK description: software home-page
o
Documentation
with notification strings: this document
o
JavaDoc: here
·
Sample project:
o
Test project (a
working example) to be downloaded from here
·
License:
o
AJVoIP comes with
life-time license allowing commercial usage for your company (limited features
and number of users with the Basic license, al features and unlimited users and
calls with the Advanced and Gold license)
·
Support:
o
Support is also
included with your AJVoIP license for no extra cost. Contact us with any question/issue/bug report and we are here to help.
o
Upgrades: AJVoIP
is actively maintained with at last one major new version per year including
improvements, bug fixes and new features in each new release. Upgrades are
always backward and forward compatible with no code changes required in your
project.
·
Programming
language: Java, Kotlin,
Scala or any other which can consume a aar/jar and can emit android apk such as
Xamarin, Corona, Phonegap/Cordova, C++, Python, Groovy, Flutter, Xamarin,
React, Ionic and others.
·
IDE: For development you can use any
environment which can produce android executables. The most popular options are
Android Studio and Eclipse. You can use any operating system to work on your
project: Windows, MAC, Linux.
·
SIP: a SIP account at any VoIP service
provider or your own IP-PBX/Softswitch/SIP sever. Can be also used without
registration for peer to peer SIP calls.
·
Network: All networks are supported with
connection speed above 12 kbits including Wi-Fi and mobile GPRS, EDGE, 3G, 4G,
LTE, 5G. VPN connections are also supported.
·
Size: below 3 MB
·
RAM: around 35 MB while in call. (This
means that you can run the SIP engine also on low-end devices with 256 MB RAM
or less)
·
CPU
architecture: any. Most
of the library is pure Java. To improve
performance, some audio processing and codec related functionalities are
implemented also as native ABI modules for all the popular platforms (arm, x86
and mips, including 64bit versions), but these modules are optional (will be
loaded only on compatible platforms although this means that it will work on
most devices)
·
CPU speed: any (The library will auto detect
the CPU performance and it might disable some features on old/slow CPU’s, such
as G.729, wideband and AEC which means that you can run it even on low-end 100
MHz ARM processors)
·
Android
versions: Android 4
(released in 2011) – Android 14+ (released in 2023). Compatible with all
devices since Android 4.
·
API level: All Android API/SDK versions are
supported (AJVoIP is optimized to old API levels but also takes full advantage
of the features found in latest versions if you are running it on a compatible
OS)
o
Minimum
(minSdkVersion): 14 (released in 2011 with Android 4.0 Ice Cream
Sandwich), which means compatibility also with ancient phones covering 100% of
the market.
Note: On request, we can ship also build with
minSdkVersion 9 (this might be necessary only if you wish to target some
specific/outdated hardware)
o
Target
(targetSdkVersion): 14 or higher (you should set this as high as possible for
your project environment. Current recommended is: 33)
Note: due to Google Play regulations you must always
target latest android versions as old API levels cannot be submitted.
o
Compile: The compileSdkVersion
should be set to 33 or higher (you should set it to highest possible by your
project environment)
o
Maximum: 34+. API
level 33 introduced with Android 13 in 2022. The SDK is continuously tested and
optimized to latest API levels as released by Google while also keeping full
backward compatibility with old API levels. You can expect to work it also in all
future versions with no modifications required and we also add optimizations to
latest API levels when new versions are released if there is any new Android
feature that can be exploited by the VoIP SDK.
·
Required
permissions:
You can set these in
your AndroidManifest.xml as uses-permission elements:
Example: <uses-permission android:name="android.permission.RECORD_AUDIO"/>
Here are
the required and optional permissions:
o
Dangerous/Mandatory
(your app must have permission for this):
§ RECORD_AUDIO (used for the audio
input stream)
o
Dangerous/Optional
(permission have to be asked only if related features are needed):
§ CAMERA (used only if you need video
calls)
§ POST_NOTIFICATIONS (not required for
AJVoIP, but might be needed for your app if you wish to post notifications)
§ READ_CONTACTS and WRITE_CONTACTS (not
required for AJVoIP at all, but might be needed for your app if you wish to
manage contacts)
§ READ_PHONE_STATE (only if the
rejectonphonebusy parameter is set to 0 or 2 or if you need more accurate call state
detection)
o
Normal
(permissions are granted automatically for these, just add them into your
manifest.xml):
§ INTERNET (mandatory)
§ ACCESS_NETWORK_STATE (optional but
highly recommended)
§ CHANGE_NETWORK_STATE (optional)
§ MODIFY_AUDIO_SETTINGS (optinal)
§ ACCESS_WIFI_STATE (optional)
§ CHANGE_WIFI_STATE (optional)
§ BLUETOOTH (optional for API level
< 31)
§ BLUETOOTH_CONNECT (optional for API
level >= 31)
§ DISABLE_KEYGUARD (optional)
§ VIBRATE (optional)
§ FOREGROUND_SERVICE (optional since
API level 27 if you wish to launch the sipstack from a foreground service)
§ REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
(optional for API level 26 or above running the sipstack as a service)
§ WAKE_LOCK (optional but highly
recommended)
§ SCHEDULE_EXACT_ALARM (optional for
API level < 32; might help to keep the app service running on some devices)
§ RECEIVE_BOOT_COMPLETED (needed only
if you wish to run it as a service and auto-start)
Note: there is no need to ask for
permissions at runtime if your application target API level 22 or below outside
the Play Store.
More details about permissions can be
found here.
·
Required
android features:
You can set these in
your AndroidManifest.xml as uses-feature elements:
The only important
feature is the android.hardware.microphone (but this is also not enforced by
default by the library because you might use it for other purposes when no
media recording is required for calls).
For a usual SIP client
application you should add the following line to your manifest:
<uses-feature
android:name="android.hardware.microphone"
android:required="true" />
The RECORD_AUDIO
permission must be also asked at runtime as described here. AJVoIP will ask for this on first
audio device opening, but this might fail outside your activity and it is
better if you ask it also from your app at a more appropriate time (for example
at startup or before the first call).
Other features that
might be used by the library (thus might be required by your application) are
the followings:
o
android.hardware.audio.low_latency
o
android.hardware.audio.output
o
android.hardware.audio.pro
o
android.hardware.telephony
o
android.hardware.bluetooth
o
android.hardware.bluetooth_le
o
android.hardware.wifi
o
android.hardware.sensor.proximity
o
android.hardware.camera
o
android.hardware.camera.front
o
android.hardware.camera.any
o
android.hardware.camera.autofocus
o
android.software.sip
o
android.software.sip.voip
o
android.software.webview
None of these are
crucial so you might add them to your manifest with required flag set to false
or don’t add at all if not mandatory for your use-case.
Example: <uses-feature
android:name="android.hardware.audio.low_latency" android:required="false"
/>
You can use the AJVoIP
library in any Android project. Just add the library to your project and call
its public API functions.
Step-by-step
instruction for using AJVoIP:
1.
Download AJVoIP
from here (this is the demo version) or from
the link provided by Mizutech (paid versions) and unzip.
You might load the sample
project first and
check its MainActivity.java file for a simple but working usage
example.
2.
Add the SIP
library to your project
You can use either the AJVoIP.aar
file or the AJVoIP.jar file. If you are using Android Studio then we recommend
the aar file. Otherwise the jar file.
·
For Android
Studio you can add it to your project this way:
1) Click File > New > New Module.
2) Click Import .JAR/.AAR Package then
click Next.
3) Enter the location of the AJVoIP.aar
file then click Finish.
4) Make sure the library is listed at
the top of your settings.gradle file:
include ':app',
':AJVoIP'
5) Open the app module's build.gradle
file and add a new line to the dependencies block:
dependencies {
...
implementation
project(":AJVoIP")
}
6) Click Sync Project with Gradle Files.
7) More details can be found here
·
If you are using
Eclipse then follow these steps:
1) Create a folder called libs in your project's
root folder
2) Copy the AJVoIP.jar file to the libs
folder
3) Now right click on the AJVoIP.jar
file and then select Build Path > Add to Build Path, which will create a
folder called 'Referenced Libraries' within your project
4) You can read more details here
·
If you are using
other IDE or environment:
Just import the
AJVoIP.jar into your project and use its public class.
3.
Instantiate a SipStack
object
Add the following code to the
location from where do you wish to start the SIP client:
import com.mizuvoip.jvoip.*; //import the SipStack class from AJVoIP
SipStack mysipclient = null; //declare the SIP stack object variable
somewhere in your application
mysipclient = new SipStack(); //create the SIP Stack instance.
mysipclient.Init(context); //initialize the SIP stack
//The context parameter is your application Context which can be
obtained from any activity or as described here
4.
Call the SetParameter
(or the SetParameters) function to pass any settings
mysipclient.SetParameter("loglevel","5");
//set
loglevel
mysipclient.SetParameter("serveraddress","voip.mizu-voip.com");
//set your
voip server domain or IP:port
mysipclient.SetParameter("username","sdktest2");
//set SIP
username
mysipclient.SetParameter("password","sdktest2");
//set SIP
password
//you might set other
parameters here such as proxyaddress, autoaccept and many others. See the parameters chapter for the full list
of possible parameters.
5.
Call the Start()
to start the sipstack
mysipclient.Start(); //this will start the SIP stack internal main
thread. It might also auto register, depending on the “register” parameter
//mysipclient.Register(); //if you have set the “register” parameter to 0,
then you might need to register explicitly
6.
Call any of the
API functions. This is where the actual work is
done. Example:
mysipclient.Call(-1,
“testivr3”); //init
call to “testivr3”. Possibly behind a “Call” button.
mysipclient.SendChat(-1,
“john”, “hi”); //send
“hi” text message to the john SIP user or SIP extension. Possibly behind a
“Chat” button.
Use any other API (for example to send DTMF, set
presence, call transfer, conference or other functions)
7.
Parse and process
the notifications from the sip stack after your needs. This can be done
continuously polling the GetNotifications in a separate thread and parsing of
the returned messages as described in the notifications chapter:
public void run()
{
while(!terminated)
{
String notification =
mysipclient.GetNotificationsSync();
if(notification.length()
> 0)
{
//parse the strings and handle the events
after your needs
}
}
}
Adjust your state machine and GUI
according the notifications received (the STATUS notification is the most relevant)
8.
Fine-tune your
application by adjusting any additional parameters that might be needed for your
use-case.
Scroll
trough the FAQ to find the answer for the most
relevant issues and potential features such as native
call integration or call
transfer usage.
Contact us if you run into any issue or with
any question
There are
no any specific requirements regarding your Android project, IDE or
environment. You just need to add the AJVoIP.aar into your Android Studio
project (or the AJVoIP.jar if you are using some other IDE) and you are ready
to go by importing the API class (import com.mizuvoip.jvoip.*;)
The
followings are to be considered for your gradle and manifest file.
The basic
requirements are the followings (SDK / api level settings for your app):
·
Set
the minSdkVersion
to 14 or higher (the minimal
SDK version your app is prepared to handle. Let us know if for some reason you
need to go below 14)
·
Set
the compileSdkVersion
to 33 or higher, preferably 33 or higher (depending on
the SDK version you wish to use to compile your project; you should set this to
as high as possible)
·
Set
the targetSdkVersion
to at least
to the minimum API level allowed in Google Play when your publish your app, 31 or higher in 2022 (It is
recommended to set this to a value to cover most of the phones on the market and Google Play doesn’t allow targeting too old
API levels)
The AJVoIP
library itself have been built with the following SDK/API settings:
·
min
SDK: 14 (this gives you a lot of flexibility, allowing your app to target any
SDK versions you wish starting with the already ancient v.14)
·
target
SDK: 33
·
compile
SDK: 33
·
the
library might load API level 14+ (including v.33) features at run-time with
class-loader or support libraries when it is running on a new devices, taking
full advantage of the latest Android platform features.
If your minSdkVersion
is 20 or below (prior to Android 5.0), then you should enable multidex as
described here.
The library
depends also on android support library (this is to allow your project to
compile and target any SDK using any API level since 14).
You might need
to add it into your gradle config as well:
dependencies {
…
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}
The only “dangerous”
permission required by default is audio recording. For this you should add the
following lines to your AndroidManifest.xml:
<uses-permission
android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-feature
android:name="android.hardware.microphone"
android:required="true" />
Above API
level 23 the permission request should be handled at runtime as described here and here.
Permissions can be
requested from your own code, however the AJVoIP will also check (and ask for
permission if needed) for RECORD_AUDIO (for calls) and CAMERA (on video calls).
You must
also add the following non-dangerous permissions to your AndroidManifest.xml
(allowed automatically, no need for explicit permission request):
<uses-permission
android:name="android.permission.INTERNET"/>
All other
permissions and features are optional and handled gratefully by the library if
not granted. For a full list see the “Required Permissions” section here. You need to take care
of these only if your app requires a specific feature depending on one of these
permissions.
More
details about permissions can be found here.
For a basic
gradle config file, see the build.gradle file in the sample application (inside the “app”
subfolder).
You might
also check the gradle file of our MizuDroid softphone (this is a
full featured SIP softphone based on the AJVoIP library with a long list of features).
For a basic
manifest file, see the AndroidManifest.xml in the sample application.
You might
also check the manifest file of our MizuDroid
softphone used in production.
Since
AJVoIP is already minified/optimized, you should exclude it from ProGuard, by
adding this line in your project proguard-rules.pro file:
-keep com.mizuvoip.jvoip.** { *; }
Otherwise,
you should be able to use any proguard rules for your project
as this will should affect the AJVoIP usage (the SIP library itself is already
highly optimized, but with its interface class kept untouched).
You might
need to slightly modify your project config to match your requirements, however
in overall AJVoIP doesn’t impose any hard limitations on the required
configurations and you should be able to use the library in any environment
with any settings if you respect the minimal requirements (min/target/compile
SDK versions as described above).
//error handling
removed for simplicity
--------------------------------------
File: YourCodeSipCall.java
--------------------------------------
package
yourpackagename;
import
com.mizuvoip.jvoip.*; //import AJVoIP
//create
SipStack class object instance:
SipStack
mysipclient = new SipStack();
//start your
message listener to accept the notifications from the SIP engine:
SIPNotifications
sipnotifications = new SIPNotifications(mysipclient);
sipnotifications.Start();
//initialize
the SDK:
mysipclient.Init((Context)this);
//set
parameters (replace uppercase words):
mysipclient.SetParameter("serveraddress",
"VOIP_SERVER_IP_OR_DOMAIN");
mysipclient.SetParameter("username",
"SIP_USERNAME");
mysipclient.SetParameter("password",
"SIP_PASSWORD");
mysipclient.SetParameter("loglevel",
"5");
//you might
set other parameters here
//start the
sipstack:
mysipclient.Start();
//register to your SIP server if
needed (usually not needed since the above Start can also auto-register,
depending on the “register” parameter):
//mysipclient.Register();
//make a
call to a user/extension/phone number/SIP URI (note: 1-2 seconds might be
needed between Start/Register and Call for the sipstack to initialize)
mysipclient.Call(-1,
"DESTINATION");
//the
following lines should be used from another function
//during the
call you might call call divert functions by your app logic or on user
interaction, for example Hold()
//call
hangup to end the call (possibly triggered by a "Hangup" button
pressed by the user):
mysipclient.Hangup(-1);
//stop
AJVoIP when you don't need it anymore
mysipclient.Unregister();
sipnotifications.Stop();
--------------------------------------
File:
SIPNotifications.java
--------------------------------------
package
yourpackagename;
import
com.mizuvoip.jvoip.*; //import AJVoIP
public
class SIPNotifications extends Thread
{
boolean terminated = false; //thread state
SipStack mysipclient = null;
//ctor
public
SIPNotifications(SipStack mysipclient_in)
{
mysipclient = mysipclient_in;
}
//start thread
public
boolean Start()
{
try{
this.start();
return true;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
//use this function from external
code when the sipstack is not needed anymore (when you app is closing).
public
void Stop()
{
terminated = true;
}
public
void run()
{
try{
//variable to
hold the incoming messages
String notifications;
//continuous
blocking read until thread is terminated:
while (!terminated) {
notifications = mysipclient.GetNotificationsSync(); //get the notifications
from the SIP stack
if(notifications.length() > 0)
{
ProcessNotifications(notifications);
}
}
}
catch (Exception e)
{
if(!terminated) e.printStackTrace();
}
}
//parse
sdk messages and modify your state (user interface, program logic) accordingly.
This might not be necessary for simple basic usage.
public void ProcessNotifications(String msg)
{
System.out.println("received from ajvoip: " msg+"\r\n");
//process notifications
here (change your user interface or business logic depending on the sipstack
state / call state).
//see
the Notifications section in the documentation for the details. Example code
can be found here.
}
}
See the API and the parameters sections below for the details about
the usage.
You can
download a working example using notification strings from here.
Usage:
1.
Download and unzip the AJVoIPTest_With_Notification_Strings.zip
file
2.
Open
the project in Android Studio
3.
Copy
the AJVoIP.aar into the \AJVoIPTest\AJVoIP folder! (from the demo or from the package sent
to you by Mizutech)
4.
You
might also need to adjust the SDK version and location in the following files:
local.properties
\app\ build.gradle
5.
From Android
Studio select Rebuild Project from the Build menu. Once the rebuild is ready, you can Run it (on your device or in
emulator)
The
relevant code can be found in the \\app\src\main\java\com\ajvoiptest\MainActivity.java file.
This is an
Android Studio example project. If you are using Eclipse or other environment,
then just inspect the above file or convert the project to your environment.
AJVoIP is a full
featured SIP library for Android with all the usual telephony features
implemented and many other extra features.
·
Standard SIP
client for calls (in/out), chat, conference and others
·
SIP and RTP stack compatible with any
VoIP server or client (Cisco, Asterisk, gateways, ATA, softphones, IP Phones,
X-Lite and many others)
·
Compatible with
all Android devices (phones, tablets, TV’s and others). SDK compatibility with
100% of the market share (min SDK: 9) and always optimized for latest Android
versions while keeping full backward compatibility even with ancient devices
·
Protocols: SIP/SIPS,
RTP/SRTP. Transport: UDP, TCP, TLS, TCP tunnel, SOCKS proxy traversal, HTTP
proxy traversal, HTTP, VPN tunneling
·
NAT/Firewall
support: stable SIP and RTP ports ,keep-alive, UPnP, rport support, fast
ICE/fast STUN protocols and auto configuration
·
Encryption: TLS/SRTP,
tunneling and peer to peer encrypted media (if direct routing is not disable by
your SIP server SDP negotiation)
·
RFC’s: 2543,
3261, 2976, 3892, 2778, 2779, 3428, 3265, 3515, 3311, 3911, 3581, 3842, 1889,
2327, 3550, 3960, 4028, 3824, 3966, 2663, 3022 and others
·
Supported
methods: REGISTER, INVITE, reINVITE, ACK, PRACK, BYE, CANCEL, UPDATE, MESSAGE,
INFO, OPTIONS, SUBSCRIBE, NOTIFY, REFER
·
Audio codec:
PCMU, PCMA, G.729, GSM, iLBC, SPEEX, OPUS
·
RTC Video codec:
H264, VP8 (optional as-is)
·
HD Audio:
Wideband, ultra-wideband and full-band codecs (speex, opus)
·
Audio
enhancements: PLC (packet loss concealment), AEC (acoustic echo
canceller), Noise suppression, Silence suppression, AGC (automatic gain
control), VAD (voice activity detection), audio focus and auto QoS (quality of
service)
·
Conference calls (built-in RTP mixer)
·
Voice
recording (SIPREC, local,
FTP or HTTP upload in wav, gsm or ogg format), SIPREC, custom audio streaming
(to external app or service)
·
DTMF (SIP INFO
method in signaling, RFC 2833, In-Band)
·
IM/Chat (RFC 3428), offline chat support
(caching messages when peer is not online), group chat
·
IMS/3GPP (basic
compatibility and features such as USSD and 3GPP SMS)
·
Presence capability and BLF (busy lamp
field)
·
Redial, call hold,
mute, forward and transfer (attended and unattended)
·
Call park and
pickup, barge-in
·
Additional call
features: call fork, re-INVITE, 3PCC, ED-137, early media, local ring-back,
PRACK and 100rel, replaces
·
Balance display, call
timer, inbound/outbound calls, Caller-ID display, voicemail (MWI)
·
Support for
credit (balance) and call rating display
·
Custom ringtone
·
Contact
management
·
Auto handle phone
power state, idle state, charging and airplane mode
·
Call optimizations
such as proximity sensor, WiFi lock/reconnect and optimal wake-looks (CPU/keyboard/screen)
·
Native call
integration support (including ConnectionService support; optional for custom
builds since it requires more permissions)
·
Unlimited lines,
multiple accounts
·
Support for run
as service with minimal battery usage (including bypassing background service
limitations)
·
Support for push
notifications
·
A long list of
other features (see the parameter list and the API for the details)
·
Flexibility (all
parameters/behavior can be changed/controlled by settings and/or the API)
·
Auto adapt to hardware: auto turn on/off
features based on CPU type and RAM size, so it will run also on low-end
hardware
·
Reliable
incoming calls with
all-time availability using improved service mode and/or push to handle
situations where your device or app is closed, standby or the device is
in doze or sleeping state
·
Auto adapt to
networking circumstances: different codec parameters and prioritization based
on network type (WiFi/3G/LTE/others) and quality (bandwidth/packet loss/jitter)
·
Stable high-level
API: Always backward and forward compatible including the parameters and the
API (you don’t need to change your code when upgrading to new versions)
The Mizu
Android Java VoIP SDK (AJVoIP) is sold with life-time unlimited client license
(Advanced and Gold) or restricted number of licenses (Basic and Standard). You
can use it with any VoIP server(s) which belongs to you or your company. Your
VoIP server(s) address (IP or domain name) will be hardcoded into the software
to protect the licensing. You can find the licensing possibilities on the Android SIP SDK page. After
successful tests please ask for your final version at info@mizu-voip.com. Mizutech will deliver the AJVoIP build
(your licensed copy) within one workday on your payment.
Release versions don’t have any of the demo limitations and can be fully
customized with your branding with “mizu”, “mizutech” words, links and all
reference to Mizutech removed. Your final build must be used only for you
company needs (including your direct sip endusers and VoIP clients).
The library doesn’t have any external dependencies (everything it
requires is within the .aar / .jar file).
Title, ownership rights, and intellectual property rights in the
Software shall remain with MizuTech and/or its suppliers.
The agreement and the license granted hereunder will terminate automatically if
you fail to comply with the limitations described herein. Upon termination, you
must destroy all copies of the Software. The software is provided "as
is" without any warranty of any kind.
You may:
Use AJVoIP on any number of devices or as
permitted by your license
Use AJVoIP as an SDK embedded in your Android project
Use AJVoIP with VoIP servers for which you have license for (after the
agreement with Mizutech). All the VoIP servers must be owned by you or your
company. Otherwise please contact our support to check the possibilities (the
Gold license allows 10+ or freely configured SIP server address)
You may not:
Resell AJVoIP
Use AJVoIP with VoIP servers not communicated with Mizutech, except Gold
license
Reverse engineer, decompile, disassemble or modify the software in any way
(except modifying the parameters and using it via the public API)
Demo version:
We are providing a demo
version which you can try and test before any payment. The demo version has all
features enabled but with some restrictions to prevent commercial usage. The
limitations are the followings:
·
maximum 10
simultaneous AJVoIP instances in the same time
·
will expire after
several months of usage (usually 2-8 months, depending on the last release
date)
·
maximum ~100 sec
call duration restriction
·
maximum 10 calls
/ session limitation (after 10 calls you will have to restart)
·
will work only
maximum 20 minutes and after that you have to restart the AJVoIP library or
your application
·
verifications
against the mizu license service
Note: for the first few
calls there might be fewer limitations than described above.
All the above
limitations are removed from your licensed copy.
On your request we can also send a trial version (will expire after some
time but doesn’t have the above demo limitations).
You can use AJVoIP as
an SDK by embedding into your Android application and calling its public API
functions.
Add AJVoIP.aar or
AJVoIP.jar to your project and use the following import statement in your code:
import com.mizuvoip.jvoip.*;
The whole API is defined in the SipStack
class for ease of use.
For maximum flexibility, the Android SIP
SDK exposes numerous functions, however this doesn’t mean that the usage is
difficult. You can ignore most of them and use only those few relevant for your
needs also outlined in the usage example.
For example if you just need to make
simple calls, then the following five functions will cover all your needs:
Init, SetParameters, Start, Call, Hangup.
All API calls are thread
safe and will not throw exceptions (on exception or error they will
send “ERROR” notifications and/or return false/-1 depending on the context).
API calls never returns
null (in case of strings you will always receive an empty string return value
when needed instead of null).
Most of the functions return
a boolean value. True when the operation was completed or initiated
successfully, otherwise false.
Most of the functions
are executed asynchronously (non-blocking) such as the Call and Register.
This means that it can return a true value immediately and fail later. For
example for the Call function the return value means only that the call was
initiated successfully. At this point we don’t know if the call will be
successful (connected) or not (rejected or failed). You can get the call status
by parsing the notification messages or you can periodically poll AJVoIP status
with the GetStatus function.
The line
parameter is part of most of the functions and it means the channel number to
be used if you wish to select a specific session.
For simple use cases usually you just have to set it to -1. For the details, see the “Line
parameter” and the “Multiple
lines” FAQ points.
The list of public
functions exported by the SipStack class are described below:
Constructor. Create new SIP stack
instance by creating a new SipStack object:
SipStack mysipclient = new SipStack();
boolean Init(Context
context_in)
Initialize the SIP engine. This is
the very first function you must call to initialize the internal data
structures.
The context_in parameter is your
application Context which can be obtained from any
activity or as described here.
boolean
SetParameter(String param, String value)
Configure the Android SIP library by
passing any settings.
The full list of available parameters
are listed here.
Example: wobj.SetParameter("loglevel",
5);
Notes:
Some basic parameters should be set before the Start
function have been called (such as “register”), however most parameters can be
also changed at run-time.
Some advanced parameters can be set also by line using
the SetLineParameter function (for advanced users only; use the other API
functions instead to control the individual lines).
boolean SetParameters(String parameters)
You can pass a set of parameters with
this function in value=key lines separated by CRLF (\r\n).
It has the same effect like the above
SetParameter function, but uses a list of parameters at once instead of setting
them individually.
See the full list of supported
parameters here.
Example: mysipclient.SetParameters("loglevel=5\r\ndtmfmode=1\r\n");
boolean
SetCredentials(String server, String username, String password, String
authname, String displayname)
Will set the SIP server address
(ip:port or domain:port) the SIP username and the password. These values can
also be preset by parameters. Parameters with empty strings will be omitted.
For example if you would like to change only the username and the password, you
can write SetCredentials(“”,”newusername”, “newpassord”)
If authname is empty, then the
username will be used for authentications. The displayname is usually empty (no
special displayname will be presented for peers). If other parameters are
empty, then they can be specified by user input (If the Android SIP SDK has a
visible user interface).
Note: you can also use the
SetParameter(s) to initialize the SDK with the credentials.
boolean
SetCredentialsMD5(String server, String username, String md5, String realm)
Instead of passing the password
directly you can use MD5 checksum.
In this case the md5 parameter must
be the md5 checksum for username:realm:password
The realm parameter is optional (can
be set as an empty string) but it is recommended for easy error detection. If
present and the server realm don’t match with this one, an error message will
be displayed by AJVoIP.
Will start the SIP engine (starting
the internal main thread).
This function call is optional to start
the sip stack on demand.
If not called, then the sip stack is
started anyway if the “startsipstack” parameter is set, otherwise will start at
first registration or outgoing call attempt.
Will connect to the SIP server. This
can be also done automatically by parameter (“register”). This function have to
be called only once at the startup. Further re-registrations are done
automatically based on the “registerinterval” parameter. When called
subsequently, the old registrar endpoint is deleted, a new one will be created
with a new call-id and AJVoIP will reregister.
Even if you wish to force
re-registration, you should not call this more frequently than 40 seconds
(because up to 40 seconds might be needed for a slow registration attempt)
boolean
Register(String server, String username, String password, String authname,
String displayname)
Same as the above but with
parameters. Otherwise you can set the credentials with the SetParameter(s)
function before to call Register().
boolean RegisterEx(String accounts)
You can
use this function to register multiple secondary accounts (up to 99) on the
same or other servers.
The
accounts parameter must have the following format: server,usr,pwd,…;server2,usr2,pwd2,…;
See the
Multiple account registration FAQ for more details.
Will
stop all endpoints (hangup current calls if any and unregister)
boolean CheckVoicemail(int
line)
Will
(re)subscribe for voicemail notifications. No need to call this function if the
“voicemail” parameter is set to 2.
The
line parameter should be set to -1.
boolean SetLine(int line)
Will
set the current channel. (Use only if you present line selection for the users.
Otherwise you don’t have to take care about the lines).
Note:
Instead of using each API call with the line parameter, you can just use this
function when you wish to change the active line and use all the other API
calls with -1 for the line parameter.
Will return
the current active line. This should be the line which you have set previously
except after incoming and outgoing calls (the SIP client will automatically
switch the active line to a new free line for these if the current active line
is already occupied by a call)
int GetLineStatus(int line) or string GetLineStatusText(int line)
Query
the status of the line.
Note: this is rarely
needed since you receive the status also by event notifications
String
GetLineDetails(int line)
Get
details about a line. The line parameter can be -1 (will return the “best” line
status).
Will
return the following string:
LINEDETAILS,line,state,callid,remoteusername,localusername,type,localaddress,serveraddress,mute,hold,remotefullname
Line line number (might be useful if you
pass -1 as line parameter
State same as in STATUS notification
CallID: SIP session id (SIP call-id)
Remoteusername is the other party username (if any)
Localusername is the local user name (or
username).
Type is 1 from client endpoints and 2
from server endpoints.
Localaddress: local IP:port
Serveraddress: remote IP:port
Mute: is muted status. 0=no,1=undefined,2=hold,3=other
party hold,4=both in hold (or if you wish to simplify: 0 means no, others means
yes)
Hold: is on hold status: 0=no,1= undefined,2=hold,3=other
party hold,4=both in hold (or if you wish to simplify: 0 means no, others
means yes)
Remotefullname is the other party display name if
any
boolean Call(int line, String peer)
Initiate
call to a number or sip username.
If the
peer parameter is empty, then will redial the last number.
·
Example:
o
mysipclient.Call(-1,
"004401234567"); //call to phone number on the default line
o
mysipclient.Call(2,
"bob"); //call to sip username on the second line
·
It is recommended to
pass only the peer number, extension or username to this function and not the
full SIP URI (the SIP stack will construct the full SIP URI with the
serveraddress already set)
·
This function is for
normal audio calls. For video use the VideoCall API.
boolean Hangup(int
line, String reasontext)
Disconnect current call(s). If you
set -2 for the line parameter, then all calls will be disconnected (in case if
there are multiple calls in progress). The “reasontext” parameter is optional.
Connect
incoming call.
Disconnect
incoming call. (Hangup will also work)
Ignore
incoming call.
boolean Forward(int line, String peer)
Forward
incoming call to peer (with 302 Moved Temporarily disconnect code)
boolean Transfer(int line, String peer)
Transfer
current call to peer which is usually a phone number or a SIP username. (Will
use the REFER method after SIP standards).
You
can set the mode of the transfer with the “transfertype” parameter.
If the
peer parameter is empty than will interconnect the currently running calls
(should be used only if you have 2 simultaneous calls)
boolean SetSpeakerMode(boolean
loud)
Switch
between speakerphone and loudspeaker.
Set to
loud parameter true if you wish to set to speaker/loudspeaker. Otherwise false
for normal earspeaker/earpiece.
boolean Mute(int line, boolean mute, int direction)
Mute
current call.
The
line parameter is the endpoint. -2 for all or -1 for current line.
Set
the mute parameter to true for mute or false to un-mute.
The
direction can have the following values:
Ø 0: mute in and out
Ø 1: mute out (speakers)
Ø 2: mute in (microphone)
Ø 3: mute in and out (same as 0)
Ø 4: mute default (set by the “defmute”
parameter, which is “mute microphone only” by default)
Return
if the selected line is muted or not.
Return
values:
Ø -1: unknown
Ø 0: not muted
Ø 1: both muted (in/out)
Ø 2: out muted (speaker)
Ø 3: in muted (microphone)
Ø 4: both muted (in/out; same as 1)
boolean Hold(int line, boolean hold)
Hold
current call. This will issue an UPDATE or a reINVITE.
Set
the second parameter to true for hold and false to reload.
Query
if the selected line is on hold or not
Return
values:
Ø -1: unknown
Ø 0: no
Ø 1: not used
Ø 2: on hold
Ø 3: other party held
Ø 4: both in hold
Note: pass -2 for the line to find if any endpoint
is in hold
boolean Conf(String peer)
Add
people to conference.
If
peer is empty than will mix the currently running calls (if there is more than
one call)
Otherwise
it will call the new peer (usually a phone number or a SIP user name) and once
connected will join with the current session.
boolean ConfEx(int
line, String peer, boolean add)
Add/remove
people or line to conference.
If
peer is empty than:
-if
add is true:
-if line is -2 then it will mix all
the currently running calls (if there is more than one call)
-if line is not -2, then it will add
the channel to the conference
-if
add is false:
-if
line is -2 then it will destroy the conference (but will keep the calls on
individual lines)
-if
line is not -2 then it will remove the selected line from the conference
Otherwise
it will call the new peer (usually a phone number or a SIP user name) and once
connected will join with the current session.
boolean Dtmf(int line, String dtmf)
Send
DTMF message by SIP INFO, In-Band or RFC2833 method (depending on the “dtmfmode” parameter). Please note that the
dtmf parameter is a string. This means that multiple dtmf characters can be
passed at once and the Android SIP library will streamline them properly. Use
the space char to insert delays between the digits. The dtmf messages are sent
with the protocol specified with the “dtmfmode” parameter.
Example: Dtmf(-2,”
12 345 #”);
Note: dtmf
messages can be also sent by adding it to the called number after a comma. For
example if you make a call to 123,456 then it will call 123 and then it will
send dtmf 456 once the call is connected.
boolean Info(int line, String msg)
Send any
SIP INFO message as defined in RFC 2976.
Use
this API to send any custom INFO messages to the server or to the connected
peer (in case if your server will forward it to other peer and not discard it).
The
msg string will be sent in the INFO body.
The
Content-Type can be specified with the infocontenttype
parameter. For example you might set the infocontenttype
to “application/mydata”. If the infocontenttype
is not set then it will be auto guessed as application/json, application/xml
or application/octet-stream”
Feedback
about the message delivery can be received with the INFO
notifications.
Example: Info(-2,”MyMessage”);
For more
details see the Custom INFO messages FAQ point.
boolean SendUSSD(int line, String method, String ussd)
Send an
USSD message after the IMS 3GPP TS 24.390 standard.
The
method parameter can be set to “INVITE”, “INFO” or “BYE”.
If
INVITE, then a new session will be created. Otherwise will use the session suggested
by the line parameter.
The ussd
parameter have to be set to the USSD string (for example “*135#”) or whole XML
(“<?xml version … “).
Will
return true if send initialized successfully or false on failure.
Further
feedback about the actual delivery or incoming ussd messages can be obtained
from the USSD
notifications.
More
details here.
boolean SendChat(int line, String peer, String
message)
Send a
chat message. (SIP MESSAGE method after RFC 3428)
Peer
can be a phone number or SIP username/extension number.
Parse
the CHAT notification to check if delivery succeeded or failed.
On
successful delivery you will also receive a log like: EVENT, chat sent
successfully
On
failed delivery you will also receive a log like: WARNING, chat message not
delivered
You
can also send typing notifications with the SendChatIsComposing API.
boolean SendSMS(int line, String peer, String message)
Send a
SMS message if softswitch has SMS delivery capabilities (Otherwise might try to
deliver as IM).
The
message is delivered as a 3GPP SMS, SMS HTTP API request or a standard SIP
MESSAGE with X-Sms: Yes header (in this case the server is responsible to
convert it to SMS).
Note:
incoming SMS messages are reported as CHAT notifications.
boolean VideoCall(String destination, int
fragmentResId, FragmentActivity fragmentinstance)
Initiate
RTC video call to destinationnumber which can be a number, username or SIP URI.
The
fragmentResId is the Integer resource ID of the FrameLayout in which the video
fragment will be loaded.
The
fragmentinstance is the instance of the Activity in which the video module will
be displayed. The video module consists of an android Fragment and the FragmentActivity will be its
parent.
Place
the <FrameLayout> in your Activity's content XML.
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="fill_parent"
android:layout_height="350dp"
/>
In the
above example the resource ID will be: R.id.fragment_container
RTC
capabilities must be available for the video to work. More details here.
boolean AcceptVideo(int fragmentResId,
FragmentActivity fragmentinstance)
Accept
RTC video call.
The
fragmentResId and fragmentinstance is as described at the VideoCall API above.
If
video interface is not loaded yet, then will initiate it now and call back. If
incoming call is not with video, then it might result in simple audio call.
Will remove the video fragment (will
also disconnect pending video call if any).
Instead of this function, you should just hide/destroy
your video container element from the user interface.
More details can be found here.
boolean
SetVideoDisplaySize(int type, int width, int height)
Use this function to control the
video display size (both for remote and local video).
Accepted parameters:
·
type: 1=for
remote video container, 2=for local video container
·
width: width in
pixels
·
height: height in
pixels; this parameter can be 0, and the height will be set depending on the
video's aspect ratio
boolean
VoiceRecord(int startstop, int now, String filename)
Will
start/stop a voice recording session.
·
Startstop: 0 to
stop, 1 to start locally, 2 to start remote ftp, 3 start to record both locally
and to remote ftp, 4 start to record as it is set by the “voicerecording” parameter
·
Now: used if the
startstop is set to 0. 0 means that the recorded file will be saved and/or
uploaded at the end of the conversation only. 2 means that the file will be
saved immediately
·
Filename: file
name used for storing the recorded voice (if empty string, than will use a
default file name)
This function should be
used only if you would like to control the recording duration.
If all conversations
have to be recorded, then just set the “voicerecording”
parameter after your needs.
The last recorded call
can be played by calling the PlaySound with the file set to “lastvoicerecord”.
boolean PlaySound(int start, String file, boolean
islocal, boolean toremotepeer, int line)
Play
any sound file.
At
least wave files are supported in the following format: PCM SIGNED 8000.0 Hz
(8 kHz) 16 bit mono (2 bytes/frame) in little-endian (128 kbits).
This
function can be used to play audio locally, but also for remote streaming.
For
remote playback, make sure to force a narrowband codec if your file is
narrowband and wideband codec (speex, opus) if your file is wideband (16 kHz,
16 bit mono in little-endian).
The
file must be found locally.
·
start: 1 for
start or 0 to stop the playback, -1 to pre-cache
·
file: file name
·
islocal: true if
the file have to be read from the device file system. False if remote file (for
example if the file is on the webserver)
·
toremotepeer:
stream the playback to the connected peer
·
line: used with
toremotepeer if there are multiple calls in progress to specify the call
(usually set to -1 for the current call if any)
For remote playback you can pass any file
path which can be passed for FileInputStream as our code uses FileInputStream
to load the file like this:
FileInputStream fileinputstream = new
FileInputStream(file);
Examples:
-playback a file locally (mysound.wav
must):
PlaySound(1,
"mysound.wav", false, false, -1)
-playback a file to the connected
remote peer (mysound.wav must exist):
PlaySound(1,
“mysound.wav", false, true, -1)
-stop the playback:
PlaySound(0,
"", false, false, -1)
In case if you just want to play a file locally,
then you can do it also directly from your code like this:
MediaPlayer mp =
MediaPlayer.create(appcontext, Uri.parse(file));
mp.start();
boolean StreamSoundBuff(int start, int line, byte[]
buff, int len)
Stream
from PCM audio buffer or from RTP packets.
This
function will stream the supplied audio buffer to the peer endpoint,
transcoding if necessary.
Parameters:
·
start: 1 for
start or 0 to stop the playback
·
line: specify the
channel in case if there are multiple calls in progress (usually set to -1 for
the current call if any)
·
buff: audio
buffer (raw PCM data or RTP packet)
·
len: length of
the buff (ideally it should be multiple of 360 if raw pcm or the size of the
RTP packets which are to be passed separately)
Notes:
·
The buff should not contain any
file header if you are using raw PCM (only raw linear PCM audio data) or it
should contain a full RTP packet (with the RTP header) if you are passing RTP
data.
·
You might set the
“useaudiodevicerecord” parameter to “false” if you need streaming but don’t
have an audio recorder device installed.
·
If previously supplied buffer(s)
are not completed yet, then the new one will be queued
·
Alternatively you can use the StreamSoundStream
function to pass an InputStream instead of buff and len.
·
In case if you wish to receive the
audio stream from the remote peer endpoint, see this FAQ point
instead.
Buffer/stream format:
At least raw linear PCM is supported
in the following format: PCM SIGNED 8000.0 Hz (8 kHz) 16 bit mono (2
bytes/frame) in little-endian (128 kbits). In case if your buffer is narrowband
(8 kHz 16 bit mono), then the stream will be automatically converted to
wideband if the VoIP audio codec is wideband such as opus or speex. In case if
your buffer is wideband (16 kHz 16 bit mono) then you should set the playbacksteamformat parameter to 1 to allow auto conversion to narrowband if the
VoIP audio codec is narrowband such as G.711 (PCMU, PCMA), G.729 or GSM.
The function can accept also RTP
packets and will transcode them if necessary. Set the streamsoundisrtp
parameter to -1 to auto-guess raw PCM
vs RTP (this is the default value), set to 0
if you supply raw PCM buffer or set to 1 if
you supply RTP packets.
boolean SetVolume(int
dev,int volume, int line)
Set
volume (0-100%) for the selected device.
The
dev parameter can have the following values:
0 for the recording (microphone)
audio device
1 for the playback (speaker) audio
device
2 for the ringback (speaker) audio
device
The
line is an optional parameter to be used only if you need different volume for
separate calls.
Note: The ringer volume might not be always honored and
might not change during ring playback.
int GetVolume(int
dev, int line)
Return
the volume (0-100%) for the selected device.
The
dev parameter can have the following values:
0 for the recording (microphone)
audio device
1 for the playback (speaker) audio
device
2 for the ringback (speaker) audio
device
The
line is an optional parameter to query the volume of a specific call line in
case if you set the volume per call. Otherwise don’t use or set to -2.
boolean
SetIdle(boolean idle)
You
might use this API to further extend the battery life (above the usual phone
power state changes).
The
sipstack internally has an idle state which can be useful to decrease CPU and
RAM usage by using less resources, slowing down all operations, running threads
in low priority and increases internal timer intervals. This means that the app
can enter in idle state even if running in foreground on a non-sleeping phone
state (but with no user interaction and no important task running such as an
ongoing call)
You
should call this function with the idle parameter set to true if the screen is
dimmed/off, there is no call and no user interaction with the application for a
while. Call with the idle parameter set to false when the user begins any
interaction with the application. The sipstack will also automatically disable
the idle state when there is a new incoming call, chat or other important event
that might require user interaction or CPU resources.
Returns voice activity statistics. See the VAD
notification for more details.
For this to work you should set the vad parameter to at
least 2 (4 for full report).
Note: if you call this function, VAD notifications will
not be sent automatically anymore. (So you will need to continue to poll for
the details).
More details here
Returns media statistics. See the RTPSTAT notification
for more details.
For this to work you should set the vad parameter to at
least 2 (4 for full report).
Note:
RTP statistics can be sent also automatically if you
set the rtpstat parameter.
if you call this function, RTPSTAT notifications will
not be sent automatically anymore
More details here.
Return
the program version number.
String GetStatus(int
line, int strict)
Returns
line status or global status if you pass -2 as line parameter. The possible
returned texts are the same like for notifications (listed below).
If the
strict variable is set to 1, then it will return “Unknown” if no such line is
activated. If the strict variable is set to 0, then it will return the default
active line if the line doesn’t exists.
You should use the
notifications described below to get the actual status of AJVoIP instead of
continuously polling it with this function call.
String GetNotifications()
Return the notifications from the SIP stack. You should poll
for the notifications periodically from a separate thread. It will return
accumulated events since the last function call (notifications separated by
\r\n -CRLF).
More details here.
Note:
·
In the new version and
documentation this function have been renamed to PollNotificationStrings (but
the GetNotifications function will also remain supported)
·
We are using simple polling for
this since Java doesn’t have function pointers to be used as a callback and
other methods are either deprecated (Observer interface) or too complex
(external libraries or sending the notifications on other channels such as a
separate TCP stream or message queue).
·
Once a notification string have
been read then it will be cleared from the internal list, so it is guaranteed
that you will never receive duplicates.
String GetNotificationsSync()
Same as
above, but will blocking wait for data (more efficient). You should call this
only from a separate thread.
In the new version and
documentation this function have been renamed to GetNotificationStrings (but
the GetNotificationsSync function will also remain supported)
boolean SetPushNotifications(int pushnotifications,
String clientid, String packagename, String gateway)
If you
wish to use VoIP push notifications then you might use this function to have it
assisted by the SIP SDK (otherwise you can implement it also separately in your
code).
Parameters:
o
pushnotifications:
0=disable,1=auto,2=direct,3=via gateway
o
clientid: your
app token ID (FCM registration token returned by registering to the
notification service)
o
packagename: the
package name of your application to be used for push notification. If empty
then it will be read from your app context. If using mizu push gateway then you
might leave it empty or set to "com.mizuvoip.mizudroid.app"
o
gateway: if your
SIP server doesn’t support push notifications then you might use a gateway (the
SIP stack will register also via this gateway)
To activate push
notifications, first you will need a Firebase project and register to FCM from your own code as described here.
Then once you call this
function with the acquired client token id, the SIP stack will begin to send
push bind request (extra SIP headers or tags in the REGISTER requests using the
protocol specified by pushtype).
This is required for
the server side to learn your token and be able to send push notifications on
incoming calls or chat.
The purpose of these
notifications should be only to wake up your application if in
background/sleeping mode, so it can start/register and process the incoming
INVITE as normally. For chat message it should be enough if you just display
the message and eventually store it (the user can launch your app by tapping on
the displayed notification).
Start example: SetPushNotifications(1, "TOKEN", "",
"");
Stop example: SetPushNotifications(0, "", "",
"");
If you set the pushnotifications
parameter to 1 (auto), then will try push with your server first (as described
in RFC 8599 so your server must answer to REGISTER with Feature-Caps:
*;+sip.pns="fcm") and if fails then it will try via push gateway.
For more details read here.
int GetPushNotifications()
Returns the push notification
subscription state from the SIP stack. This should be used only if you let the
SIP stack to handle the push notifications for you by calling the above SetPushNotifications
API first.
Possible return values:
§ 0: disabled (push notification
disabled)
§ 1: enabled unknown (might work)
§ 2=success (push notification working)
§ 3=failed (push notification
subscription failed)
Note: you can assume that push
notifications are working if you were capable to subscribe to FCM and get a
valid token AND the GetPushNotificatons function returns 2.
Contact
management has little to do with the SIP stack and should be handled entirely by your
application (except
presence status). You
can use the above AJVoIP API to add VoIP functionality to your address book or
contact list and based on the user presence you can display the different
buttons with your design. Near each contact you can display a call/chat button
which will launch a voip endpoint instance preconfigured with the actual
contact (“callto” parameter).
For the
contact listing you can just use the native system phone-book or a separate
contact list for your app if needed (or a mix of these).
For your convenience as
an extra functionality the SDK also provides a simple contact management API
which can be also used if for some reason you find it more suited for your
needs, but in general we recommend to handle the contacts entirely in your own
app since this task is more about user interface related development and less
to do with the SIP specific API.
Contact parameters are
stored as comma delimited strings with the following parameters:
imstatus,name,sip,phone,phone2,phone3,othernumbers,sipcontacturi,email,web,address,speeddial,extra,internalextra
boolean
SetContacts(String contacts)
Set all contacts
(contact parameters separated by new line)
String GetContacts()
Will return all
contacts (in separated lines the parameters described above)
boolean
DelContact(String name)
Delete contact.
boolean
AddContact(String params)
Add a contact. Example:
Add_Contact(‘,John
Smith,jsmith,’); //here we set only the name and the SIP fields
boolean
SetContact(String name, String params)
Change contact.
String
GetContact(String name)
Will return a single
contact in the format described above.
Helper functions to
set/get individual fields:
boolean SetContactName(String name,
String param)
Set contact name.
boolean SetContactSIP(String name,
String param)
Set contact sip uri.
boolean SetContactPhone(String name,
String param)
Set contact phone number.
boolean SetContactSpeedDial(String
name, String param)
Set contact speed dial number (short
number).
String GetContactName(String name)
Get contact name.
String GetContactSIP(String name)
Get contact sip uri.
String GetContactPhone(String name)
Get contact phone number.
String GetContactSpeedDial(String
name)
Get contact speed dial number (short
number).
Example code for
contact management can be found here.
Presence
is based on SIP SIMPLE SUBSCRIBE/NOTIFY mechanism and it is used to detect the
online status of the contacts.
There is
no need to manage the contacts within SIP endpoint (as described above) to have
presence functionality (so you can manage the contacts externally in your
application).
The
following steps are required:
1.
Related settings:
o enablepresence: 0/1
o email = email address sent with
contact info
o presenceexpire = 3600
o autoacceptpresencrequests = -1;
//-1: not set (1), 0=auto reject all,1=ask for new users,2=yes, autoaccept new
unknown users
2.
First you should
call PushContactlist to pass all the usernames and phonenumbers from your
external contact list if any. This is necessary, because for existing contacts AJVoIP
can accept the requests automatically, while for other it might ask for user
permission
3.
On first start
you might call NumExists. If using the Mizu VoIP server, then it will return
all existing contacts with SERVERCONTACTS,userlist notification where userlist
are populated with the valid users and their online status.
4.
Call CheckPresence(userlist). To save softswitch
resources, you should carefully select the contacts. (Send only the contacts
which are actually used and called numbers. We recommend up to 50 contacts. If the
user select a contact, then you can call this function later with that single
contact to request its status). This
function will start to send SUBSCRIBE requests.
5.
Use the SetPresenceStatus(statustring)
function call to change the user online status with one of the followings
strings: Online, Away, DND, Invisible , Offline (case sensitive) . This function will start to send NOTIFY
requests to subscribed parties.
6.
Once these are
done, the following notifications can be received from java sip stack:
NEWUSER,peerusername,displayname,email,URI
PRESENCE,peerusername,status,displayname,email
(displayname and email can be empty)
On newuser, you should ask the user if wish to accept it. If
accepted, call the NewUser function. The same function should be called when
the user adds a new contact to its contactlist.
For presence the following status strings are defined (be
prepared to receive any of these and handle it with case insensitive by
displaying red/green/gray/other icons):
o Open/Online/Reachable/Available/Call
Me/Registered [GREEN]
o DND (Do not disturb; halt popups and
sounds) [RED]
o Busy/Speaking (can be auto set)
[ORANGE/YELLOW]
o Pending/Forwarding [ORANGE/YELLOW]
o Away/Idle [ORANGE/YELLOW]
o Close/Unreachable/Offline/Unregistered
[GREY/WHITE]
o Unknown/Not Set [GREY/WHITE/NOCOLOR]
o Invisible (no status notifications
will be sent) [GREY/WHITE/NOCOLOR]
Other suggestion for colors:
o red: busy/dnd
o bright green: online
o pale green: away/forwarding/pending
o white: user exists but unknown status
or invisible
o no color: user doesn’t exists / no
presence feature
7.
You might use the
UnSubscribe() API to unsubscribe all endpoints (this includes presence,
voicemail and BLF subscribes).
BLF (Busy
Lamp Field) can be used to monitor the state of an extension and it is
implemented as SUBSCRIBE/NOTIFY with dialog event package as described in RFC
3265 and RFC 4235.
Set the enableblf parameter to enable/disable BLF. The
following values are defined:
0:
disable BLF
1:
auto (from here it will auto switch to 0 or 2 regarding the circumstances
–whether BLF was initiated and succeed/failed)
2:
enable BLF
3:
force always (if you set to 3 then it can’t be switched off later and will use
BLF even after failure)
Default
value is 1.
To
subscribe to other extensions call state, you can set the blfuserlist parameter or use the CheckBLF(userlist) to subscribe to other
extension(s) state changes (users separated by comma). To remove an extension,
just modify the blfuserlist parameter or call the DisableBLF(userlist) API.
Make sure
that the other extension also has BLF support (so it can respond with NOTIFY
for the BLF SUBSCRIBE).
Once the
state of the remote extension(s) are changed, you will receive BLF notifications
in this format:
BLF,peerusername,direction,state,callid
Fields:
·
BLF: state header string
·
peersusername:
extension username
·
direction
o undefined (not for calls or no announced by the
peer)
o initiator (outgoing call)
o receiver (incoming call)
·
state
o trying (call connect initiated)
o proceeding (call connecting)
o early (ringing or session progress)
o confirmed (call connected)
o terminated (call disconnected)
o unknown (unrecognized call state
received)
o failed (BLF subscribe or notify failed)
·
callid:
optional value if reported from the remote extension (the SIP call-id of the
call)
Some other not so
important API calls are listed below (helper functions):
boolean Test()
You might use this
function to check the API availability. Should return true.
boolean
ServerInit(String address) -deprecated
Call this function
before to start any communication with this address (usually an IP number).
This is required to release the Java security restrictions. Wait 1-2 second
before calling the next function like Register or Call. This function is
deprecated since v.3.8 (no need to call this, just call Register or others
directly)
boolean MightStop()
It is a good practice
to call this function when your app might be stopped or killed soon. For
example your app/activity is pausing/closing/exiting and from there the OS
might kill your process. This will just make sure that the internal SIP stack
settings are properly saved and the sipstack is prepared for an unexpected
termination.
boolean Stop()
Will stop all
endpoints. This function call is optional when you unload AJVoIP from external
app.
boolean Exit()
Will stop all endpoints
and terminates the java sip application. This function call is optional when
you unload the AJVoIP java module or wish to issue a forced termination. Its
behavior can be controlled by the “exitmethod” parameter.
boolean ReStart()
Restart the SIP stack.
(Avoid using this API.
Stop the old instance and create a new webphone object instead)
void CheckConnection()
You might call this
function to quickly recover from connection failures on events not know by AJVoIP
such as app switched to foreground or activity launch (otherwise AJVoIP should
auto-recover from network failures)
boolean
CapabilityRequest(String server, String username)
Will send an OPTION
request to the server. Usually you should not use this function.
The server parameter
can be empty if you already set it with other API calls or by parameter.
The username parameter
can be empty (in this case the “From” address will be set to “unknown”)
String LineToCallID(int
line)
Get the SIP Call-ID for
a line number.
int CallIDToLine(String
callid)
Get the line number for
a SIP Call-ID.
boolean SetLineParameter(int
line, String param, String value, int permanent)
Set parameter for the
current/next/all/specific line. Only some of the parameters are supported by
this function (listed below).
These are advanced
settings and this function might be used only if you need some
specific/different behavior for a specific line only.
Otherwise, the behavior
of the different lines are loaded from the global configuration (parameters),
from the circumstances
or can be influenced by the other API functions (try to use the other API’s
instead of this when possible).
Parameters:
Line:
channel number.
If -2, then it will be set as global
config like the SetParameter.
If -1, then for the active line.
If 0, then it will be applied for all next/new channel(s).
Otherwise it will be applied for the
specific line.
Param: settings
key name
Value:
value as string (or "NULL" to clear any old preset)
Permanent
If 1 then the setting will be kept
for all future lines with the same line number
If 0 then the setting will be applied
only for the current or very next channel with the same line
The following
parameters are supported by this function:
peer (called number), address
(will set both the serveraddress and proxyaddress), serveraddress, proxyaddress,
username, authusername, password, displayname, voicerecording, muted, holded, maxsipmessagesize,
codecretry, disccode, registerinterval, maxmsgresend, srtp_suite, strictsrtp, dtmfmode,
rtp_timestamp, rtp_seq, rtp_ssrc, defpayload, setfinalcodec, presenceexpiresec,
notifyexpiresec, sipproto, volumein, volumeout, volumering, videocalltype, videodirection,
keepvideosdponhold, defvideopayload, serverdomainandport, serveraddr, serverport,
serverip, proxyport, proxyip, realm, p_referred_identity, p_asserted_identity,
remote_party_id, privacy, customsipheader, customsdpfield, customsdpmediafield,
sip_uui,sessionid, discreason, usesdpip, transport, line, callid, state.
All preset settings for
all lines can be removed by passing 0 for the line and empty or NULL for both
the key and the value.
Examples:
mysipclient.SetLineParameter(1,"username", "mia",0);
//set the
username to mia for the next call on line 1
mysipclient.SetLineParameter(2,"username", "mia",1);
//set the
username to mia for all upcoming calls on line 2
mysipclient.SetLineParameter(2,"username", "NULL",1);
//clear the
permanently preset username from line 2
mysipclient.SetLineParameter(-1,"muted", "0",0);
//unmute the
current call (use the Mute API instead)
mysipclient.SetLineParameter(0,"muted", "4",0);
//set the
default muted state both side mute for the next call
mysipclient.SetLineParameter(0,"NULL", "NULL",1);
//clear all
the permanent settings from all lines
boolean
SetSIPHeader(int line, String hdr)
Set a custom sip header
(a line in the SIP signaling) that will be sent with all messages. Can be used
for various integration purposes to send auxiliary meta-data via the SIP
signaling (for example for sending the http session id).
Example: SetSIPHeader(-1, "X-MyData: VALUE”);
Multiple headers can be
separated by CRLF (\r\n).
You can also set this with the customsipheader parameter.
String GetSIPHeader(int
line, String hdr)
Return a sip header
value received by AJVoIP. If not found it will return a string beginning with
“ERROR:” such as “ERROR: no such line”.
boolean SetUUI(int
line, String value, int fortarget)
Set a custom UUI
(User-to-User Call Control Information as described in RFC 7433).
Value is the UUI data (with
or without parameters)
Fortarget specifies if
the UUI have to be sent to target party with call transfer or redirect escaped.
0: no (to peer with the User-to-User header), 1: yes (to target in Contact or Refer-To
URI), 2: both.
Example:
SetURI(-1, "anydata”,-2);
SetURI(-1,
"DATA;encoding=hex;purpose=foo;content=bar”,-2);
You can also set this
with the sip_uui parameter.
boolean SetSDPField (int
line, String field, int type)
Set a custom SDP field
(a line in the SDP body) that will be sent with all messages.
Set the type parameter
to 0 for global values (before the m= line) or 1 for media values (after the m=
line).
Example: SetSDPField(-1, "a=3ge2ae:requested",1);
Multiple headers can be
separated by CRLF (\r\n). You can also set this with the customsdpfield and customsdpmediafield parameters.
Line -2 means all lines, -1 means current
active line or use 1+ means for an existing line in call.
You can set a SIP header for the next
call by using line number -3 or clear the old header(s) by using line number 0.
Boolean RTPHeaderExtension
(int line, int profile, String extension)
Set RTP header extension for the RTP packets.
The profile will be set
as the first two bytes in the extension header (might be used as a custom
identifier or parameter).
The extension can be
one or multiple numbers separated by semicolon (;). These numbers will be sent
as 32 bit words with the RTP header extension payload.
Example: RTPHeaderExtension (-1, 1, "987"); //will set the profile number to 1 and the rtp extension
word to 987 for the current call
Line -2 means all lines, -1 means current
active line or use 1+ means for an existing line in call.
You can set a SIP header for the next
call by using line number -3 or clear the old header(s) by using line number 0.
Set the profile to 0 and the extension
string to empty to clear it.
boolean ED137PTT
(int line, int ptt, int pttid)
ED-137 Push to talk.
Parameters:
o
line: channel
number
o
ptt: 0: off (not
speaking), 1: on (Normal PTT ON), 2: Coupling PTT ON, 3: Priority PTT ON, 4:
Emergency PTT ON
o
pttid: optional
PTT-ID (otherwise loaded from global config)
Will return true if
initiated successfully or false on failure.
The ed137 parameter should be set to 1 before
using this function. See the ED_137 guide for more details
boolean SendSIPMessage(int
line, String msg, String body, String account, String target)
Send a custom SIP
signaling message (for example OPTIONS, NOTIFY, etc).
Parameters:
o
line: endpoint
where the message will be sent. -3: new endpoint, -2: all endpoints, -1:
current active, 0: register endpoint, 1+: call channel number
o
msg: SIP message
to send. It can be just the method name (OPTIONS,MESSAGE,NOTIFY,INVITE,etc),
the full message header or the full message including also a body (such as SDP)
o
body: optional
SIP message body (such as SDP, xml payload or chat text, etc). Set to
"null" if body must not be sent.
o
account: optional
SIP account details if you wish to use other parameters then the configured
one.
same format like the extraregisteraccounts parameter
o
target: optional
target username, number or SIP URI if not specified in the msg
Examples:
o
Send a custom
REGISTER request: mysipclient.SendSIPMessage(0,
"fullregistermessagehere", "", "");
o Send UPDATE on line 1: mysipclient.SendSIPMessage(1, "UPDATE",
"", "");
o Send IM on line 2: mysipclient.SendSIPMessage(2, "MESSAGE", "hi",
"", "evelin");
o Send OPTIONS to another server: mysipclient. SendSIPMessage(-3, "OPTIONS",
"", "username:password@otherserveraddress.com");
o
Send PUBLISH with
a custom body: mysipclient.SendSIPMessage(-3,
"PUBLISH", "anymessagehere", "");
The Content-Type for
INFO, MESSAGE and NOTIFY requests can be specified with the contenttype parameter. Otherwise the content type
will be auto guessed.
String GetSIPMessage(int
line, int dir, int type)
Return the last
received or sent SIP signaling message as raw text.
Dir:
0: in
(incoming/received message)
1: out
(outgoing/sent message)
Type:
0: any
1: SIP
request (such as INVITE, REGISTER, BYE)
2: SIP
answer (such as 200 OK, 401 Unauthorized and other response codes)
3:
INVITE (the last INVITE received or sent)
4: the
last 200 OK (call connect, ok for register or other)
String
GetLastRecInvite()
Return the last
received INVITE message.
String
GetLastRecSIPMessage(String line)
Get the last received
SIP message as clear text. Line is the line number or the SIP call id.
String GetLastRecFileName
(String line)
Returns the last
recorded file name.
String SendChatIsComposing
(String line, String number)
Send typing
notification.
String GetAddress()
Return the local SIP
listener address (IP:port)
boolean IsOnline()
Return true if network
is present
boolean IsRegistered()
Return true if AJVoIP
is registered (“connected”) to the SIP server.
int IsRegisteredEx()
Returns extended
registration state: 0=unknown,1=not needed,2=yes,3=working yes,4=working
unknown,5=working no,6=unregistered,7=no (failed)
int IsInCall()
Return whether the sip
stack is in call: 0=no,1=ringing,2=speaking
boolean
IsIncomingVideo()
Return true if the
current incoming call has video offer or false if it has only audio offer
Example code:
if(mysipclient.IsIncomingVideo())
//check incoming call type
{
//auto
accept video call
mysipclient.AcceptVideo(fragmentResId,
fragmentinstance);
}
else
{
//auto
accept audio call
mysipclient.Accept(-1);
}
int
GetCurrentConnectedCallCount()
Get number of current
connected calls
String
GetRegFailReason(boolean extended)
Will return a text
about the reason of the last failed registration. Set the extended parameter to
true to get more details
String GetDiscReasonText()
Return the disconnect
reason of the last disconnected call.
int GetAccountRegState(String
domain, String proxy, String username, String sipusername, boolean pushnotify,
boolean strict)
Query account register
state. Useful if you are using multiple accounts.
Returns -1: no such
account register ep, 0: working, 1: success, 2: failed, 3: unregistered.
Parameters domain,
proxy, username, sipusername will be used to match the account.
If the pushnotify is
true, then it will look after push register endpoints (useful if push via
gateway).
If the strict parameter
is false, then will check the best matching account after the passed
parameters.
If the strict parameter
is true, then will enforce exact parameter match when checking after the
endpoints (server domain/username/etc).
String GetAccountRegStateString(String
domain, String proxy, String username, String sipusername, boolean pushnotify,
boolean strict)
Query account register
state. Useful if you are using multiple accounts.
Return status text (for
example "Registered" if the account is registered to the server).
Parameters domain,
proxy, username, sipusername will be used to match the account.
If the pushnotify is
true, then it will look after push register endpoints (useful if push via
gateway).
If the strict parameter
is false, then will check the best matching account after the passed
parameters.
If the strict parameter
is true, then will enforce exact parameter match when checking after the
endpoints (server domain/username/etc).
String
GetCallerID(int line)
Will return the remote
party name
String
GetIncomingDisplay(int line)
Get incoming caller id
(might return two lines: caller id \n caller name)
String
GetLastCallDetails()
Get details about the
last finished call.
String GetMySIPURI(boolean
all)
Will return the SIP URI
on which the current endpoint can be reached such as username@server.com or username@localip:port.
If all is true, then it
will return all possible URI’s separated by comma.
void AddLog(String
msg)
Add a message to AJVoIP
log.
boolean
HoldChange(int line)
Same as Hold, but
without the second parameter. This call will always invert the hold status for
an endpoint (If the call was active, then it will switch to held status and if
the call was in hold, then it will reactivate it).
String VAD()
Returns voice activity
statistics. See the VAD notification for more details.
Note: if you call this
function, VAD will not be sent automatically anymore. (So you will need to
continue to poll for the details).
String HTTPGet(String
url)
Send a HTTP GET
request. Check if return string begins with “ERROR”.
Note:
You should never call
http requests from your main GUI thread, otherwise it will fail with a
NetworkOnMainThreadException exception (This exception will occur only
internally, not thrown to you).
For development, you might
remove the restriction:
StrictMode.ThreadPolicy
policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
boolean HTTPPost(String
url, String data)
Send a HTTP POST
request.
You should not call
this function from your main GUI thread.
String HTTPReq(String
url, String data)
Send a HTTP POST or GET
request. (If data is empty, then GET will be sent). Can be tunneled. Can block
for up to 20 seconds.
You should not call
this function from your main GUI thread.
boolean HTTPReqAsync(String
url, String data)
Send a HTTP POST or GET
request. (If data is empty, then GET will be sent). Can be tunneled. The
result will be returned in notifications with “ANSWER” header.
It is safe to call this
function also from the main GUI thread.
boolean SaveFile(String
filename, String content)
Will save the text file
to local disk AJVoIP working directory in encrypted format (use SaveFileRaw to
save as-is)
String LoadFile(String
filename)
Load file from local
disk.
boolean SaveFileRemote(String
filename, String content)
Save file to remote
storage (preconfigured ftp or http server )
boolean LoadFileRemote(String
filename)
Load file from remote
storage. The download process is performed asynchronously. You need to call
this function only once and then a few seconds later call the LoadFile function
with the same file name. It will contain “ERROR: reason” text if the download
failed.
String LoadFileRemoteSync(String
filename)
Will download the
specified file from remote storage synchronously (will block until done or
fails).
String
GetBlacklist()
Get blacklist
boolean SetBlacklist(String
str)
Set whole blacklist
(users/numbers separated by comma)
boolean
AddToBlacklist(String str)
Add to blacklist
boolean ClearCredentials()
Clear existing user
account details.
boolean DelSettings
(int level)
Delete settings and
data. Levels: 0: nothing, 1: settings, 2: everything
int IsEncrypted ()
Returns whether the
connection is encrypted. -1: unknown, 0=no,1=partially/weak yes,2=yes,3=always
strong
String GetLogs()
Can be used to get the
logs (which are otherwise written also to standard output and to Logcat).
The logpolling
parameter must be set to 1 for this to work.
Will store up to 20000
log entries (so you might call this periodically if you don’t wish to loose
past logs)
String GetBindir()
Returns the application
path (folder with the app binaries or app home folder)
String GetWorkdir()
Returns the application
working directory (data folder).
Based on:
appcontext.getFilesDir().getPath();
Environment.getDataDirectory().getPath();
String GetAltWorkdir()
Returns the application
alternative working directory (such as folder on external SD card).
String GetLogPath()
Will return the log
file path.
By default the log file
path will be set automatically, usually inside the work directory. It can be
modified with the logpath parameter.
Logs are written to
file only if the canlogtofile parameter is set to 1 or 2.
The log file might be
in use while AJVoIP is running and you will be able to access it only in shared
read mode.
int ShouldReset()
Check if the sipstack
should be restarted. Usually this is required only on local network change
(such as IP change or changing from mobile data to wifi).
Possible return values:
0=no,1=not registered for a while,2=network changed
boolean ShouldResetBeforeCall()
This function might be
called before calls and you should quickly restart the sipstack if returns true
(then continue to make the call).
boolean RecFiles_Del()
Delete local recorded
files.
boolean GetDeviceID()
Returns an unique device
ID.
String GetVersion()
Return the program
version number.
Most of the API
functions were covered above in this guide, however you might find also some
additional helper functions exposed. You should be able to cover all your needs
using the above functions and most of the additional API’s are redundant or
needed only in very special circumstances.
See the Javadoc for a complete listing of all public
functions.
Notifications can be
received by the GetNotifications or GetNotificationsSync API calls.
Usually you will have
to parse the received strings from your code. The parameters are separated by
comma ‘,’. First you have to check the first parameter (until the first comma)
to determine the event type. Then you have to check for the other parameters
according to the specification below.
Please note that you
can get more than one event at once, separated by newline (or ,NEOL \r\n) so
you should check for new lines first and then parse all events.
Notifications might be
prefixed with the “WPNOTIFICATION,” string (you should handle and remove this
before parsing the rest of the line).
A code example can be
found here.
The easiest way to get
started is to just log out all messages at first and from there the usage
should be more obvious.
See the new documentation if you wish to handle the
notifications as object events instead of plain strings.
Line parameter:
Most of the messages
contains a line parameter which is set to -1 for the global state or 0,1,2,3…
for the individual lines. For this reason you might see duplicated
notifications: one sent for the global state, another sent for the actual line
state.
For you wish to
implement something basic, then it is enough of you check the notifications
only for the global state and ignore the line states.
If you wish to handle multi-lines
explicitly then you
should check also the state of the individual lines (you might ignore the
notifications about global state in this case).
The following
messages are defined:
STATUS,line,statustext,peername,localname,endpointtype
You will receive STATUS
notifications when the SIP session state is changed (SIP session state machine changes)
or periodically even if there was no any change.
The STATUS notification
looks like this:
STATUS,line,statustext,peername,localname,endpointtype,peerdisplayname,[callid],online,registered,incall,mute,hold,encrypted,video,group, rtpsent,rtprec,rtploss,rtplosspercet,serverstats
The line parameter can
be -1 for general status or a positive value for the different lines.
General status means
the status for the “best” endpoint.
This means that you
will usually see the same status twice (or more). Once for general sip client
status and once for line status.
For example you can
receive the following two messages consecutively:
STATUS,1,Connected,peername,localname,endpointtype,peerdisplayname,[callid],…
STATUS,-1,Connected
You might decide to
parse only general status messages (where the line is -1), messages for
specific line (where line is zero or positive) or both.
Status notifications
are sent on state change but also at a regular interval (so you can see the
same notification again and again even if there was no state change).
The following statustext
values are defined for general status (line set to -1):
o
Starting...
o
Idle.
o
Ready
o
Register…
o
Registering… (or
“Register...”)
o
Register Failed
o
No network
o
Not Registered
o
Registered (or
“Registered.”)
o
Unregistered
o
Accept
o
Starting Call
o
Call
o
Call Initiated
o
Calling…
o
Ringing…
o
Incoming…
o
In Call (xxx sec)
o
Hangup
o
Call Finished
o
Chat (or
Messaging)
Note: general status means the “best”
status among all lines. For example if one line is speaking, then the general
status will be “In Call”.
The following statustext
values are defined for individual lines (line set to a positive value
representing the channel number starting with 1):
o
Unknown (you
should not receive this)
o
Init (voip
library started)
o
Ready (sip
stack started)
o
Outband
(notify/options/etc. you should skip this)
o
Register (from register endpoints) (or
“Register…” or “Registering...”)
o
Unregister
o
Subscribe
(presence)
o
Chat (IM)
o
CallSetup (one time event: call begin)
o
Setup (call
init)
o
InProgress
(call init)
o
Routed (call
init)
o
Ringing (SIP
180 received or similar)
o
CallConnect (one time event: call was just
connected)
o
InCall (call is
connected)
o
Muted
(connected call in muted status)
o
Hold
(connected call in hold status)
o
Speaking (call
is connected)
o
Midcall (might
be received for transfer, conference, etc. you should treat it like the
Speaking status)
o
CallDisconnect (one time event: call was just
disconnected)
o
Finishing (call
is about to be finished. Disconnect message sent: BYE, CANCEL or 400-600 code)
o
Finished (call
is finished. ACK or 200 OK was received or timeout)
o
Deletable
(endpoint is about to be destroyed. You should skip this)
o
Error (you
should not receive this)
You will usually have
to display the call status for the user, and when a call arrives you might have
to display an accept/reject button.
For simplified call
management, you can just check for the one-time events (CallSetup, CallConnect,
CallDisconnect)
Peername: the other party username (if any)
Localname: the local user name (or username).
Endpointtype: is 1 from client endpoints
(outbound) and 2 from server endpoints (inbound).
Peerdisplayname: the other party display name if any
CallID: SIP session id (SIP call-id) in
[square brackets]
Online: network status. 0 if no network or
internet connection, 1 if connectivity detected (always the global status)
Registered: registration state. 0=unknown,1=not
needed,2=yes,3=working yes,4=working unknown,5=working no,6=unregistered, 7+
=no (failed) (always the global status)
InCall: phone/line is in call. 0=no,1=setup
or ringing,2=speaking
Mute: is muted status. 0=no,1=undefined,2=hold,3=other
party hold,4=both in hold (or if you wish to simplify: 0 means no, others means
yes)
Hold: is on hold status: 0=no,1= undefined,2=hold,3=other
party hold,4=both in hold (or if you wish to simplify: 0 means no, others
means yes)
Encrypted: encryption status: -1: unknown,
0=no,1=partially/weak yes,2=yes,3=always strong (or if you wish to simplify: 0
and -1 means no, others means yes)
Video: set to 1 for video calls (with
video media offer). Otherwise 0.
Group: group string for group chat and
conference calls (members separated by | )
RTPSent: number of sent RTP packets (only if
endpoint is in call)
RTPRec: number of received RTP packets
(only if endpoint is in call)
RTPLoss: number of lost RTP packets (only if
endpoint is in call)
RTPLossPercent: percent of the lost RTP packets
(only if endpoint is in call)
ServerStat: RTP statistics received from the
server, if any (only if endpoint is in call)
For example the
following status means that there is an incoming call ringing from 2222 on the
first line:
STATUS,1,Ringing,2222,1111,2,Katie,[callid]
The following status
means an outgoing call in progress to 2222 on the second line:
STATUS,2,Speaking,2222,1111,1,[callid]
To display the “global”
phone status, you will have to do the followings:
1.
Parse the
received string (parameters separated by comma)
2.
If the first
parameter is “STATUS” then continue
3.
Check the second
parameter. It “-1” continue otherwise nothing to do
4.
Display the third
parameter (Set the caption of a custom control)
5.
Depending on the
status, you might need to do some other action. For example display your
“Hangup” button if the status is between “Setup” and “Finishing” or popup a new
window on “Ringing” status if the endpointtype is “2” (for incoming calls only;
not for outgoing)
If the “stats” is on
(set to a value higher than 0) then you will receive periodic status messages
during calls (might be useful if you are interested in RTP statistics during a
call).
REGISTER,line,state,text,main,fcm,user,reason
This notification is
received for register state changes from registrar endpoints.
line: channel number (should be
always 0 for register)
state:
0: in progress, 1: success, 2: failed, 3: unregistered
text: register state as text
main: true for primary account, false
for secondary registrations (if you are using multiple accounts)
fcm: specify if it is an extra FCM
push registration (0: not fcm, 1: fcm for main account, 2: fcm for secondary
account, 3: unreg)
user: local username (useful if you
are using multiple accounts)
reason: failure reason text if any
See the How
to register FAQ
point for more details.
Note: This notification can be disabled
by setting the sendregisternotifications parameter
to 0 (for compatibility reasons with old
versions).
PRESENCE,peername,state,details,displayname,email
This notification is
received for presence changes (peers online status).
Line: used phone line
Peername: username of the peer
State and details: presence status
string; one of the followings: CallMe,Available,Open,Pending,Other,CallForward,Speaking,Busy,Idle,DoNotDisturb,DND,Unknown,Away,Offline,Closed,Close,Unreacheable,
Unregistered,Invisible,Exists,NotExists,Unknown,Not
Set
Displayname: peer full name (it can
be empty)
Email: peer email address (it can be
empty)
Notes for the state
and details fields:
One of these fields
might be empty in some circumstances and might not be a string in the above
list (especially the details).
The details field will provide a more exact
description (for example “Unreachable”) while the state
field will provide a more exact one (for example “Close”). For this
reason if you have a presence control to be changed, check the details string first and if you can’t recognize
its content, then check the state string.
For displaying the state as text, you should display the details field (and display the state field only if the details
string is empty).
Incoming DTMF
notification.
Msg is a string parameter
representing the incoming DTMF digit. Usually one of the followings: 0123456789*#ABCDF
Supported dtmf methods:
SIP INFO and RFC2833
Example: DTMF,1,7 (dtmf digit”7”
received on first line)
INFO,type,line,peername,text
Notifications about
incoming/outgoing INFO or DTMF messages.
Note: for incoming DTMF you should watch
for the above described DTMF notification instead of this! DTMF notification
will be triggered even if the message was received with SIP INFO.
Parameters:
Type: The possible
values for the type parameter is the following:
ERROR:
Outgoing DTMF or INFO message failed
WARNING:
Outgoing DTMF failover from SIP INFO to RFC 2833 or In-Band on answer timeout
or error response
OK:
Outgoing DTMF or INFO was sent successfully
REC: Incoming INFO message receive.
Note that if the incoming message is a dtmf digit, then a DTMF notification
will be triggered instead of INFO
Line: Phone line
Peername: Other party
username
Text: INFO
message body when type is REC or any additional info if type us ERROR, WARNING
or OK.
Examples:
INFO,ERROR,1,1111,timeout (on Dtmf or Info message send failed to 1111 on
line 1)
INFO,WARNING,1,1111,failback to rfc2833 (on Dtmf failback from
INFO to rfc2833 or in-band)
INFO,OK,1,1111 (on Dtmf or Info message sent successfully to 1111 on line
1)
INFO,REC,1,1111,hello (on SIP INFO message received from 1111 which is
not DTMF)
Note:
When sending DTMF in RTP
(in-band or rfc2833) then it is not possible to get feedback whether the
message was actually delivered. In this case you will receive an INFO,OK when
the message send was initiated successfully. Otherwise if SIP INFO is used,
then you will receive INFO,OK only on 2xx answer from the server or the other
peer.
BLF,peerusername,direction,state,callid
This notification is
received for incoming BLF messages.
Described in the BLF
section above.
This notification is
received about incoming USSD messages or report about success/failure about the
outgoing USSD messages sent by SendUSSD.
Line: the session line
status: 0: send failed, 1: send succeeded,
2: received
text: text is the received USDD
string (if status is 2) otherwise it might contain an error (if status is 0)
This notification is
received for incoming chat messages.
Line: used phone line
Peername: username of the peer
Text: the chat message body
Note:
·
The chat actually could be an
incoming SMS message (for example a 3GPP SMS payload)
·
If the text begins with “_BASE64_”
then you must base64 decode the rest of the string before presenting it to the
user.
·
If the text begins with “GROUP: “
then it is a group chat. Example: “GROUP Katie,John: hi”. In this case you
might remove the header (until the
second colon) and display the message in a separate thread.
CHATREPORT,line,peername,status,statustext,group,md5
Chat transmission
status report so you can process if outgoing message deliver was successfully
or failed.
Line: used phone line
Peername: username of the peer
Status: 1 means sending in progress,
2 means successfully sent, 3 means failed
Statustext: error text if any
Group: optional parameter for group
chat (member names separated by | )
MD5: the MD5 checksum of the message
text
Note:
If the
offline messaging is not disabled (offlinechat parameter is not set to 0) then AJVoIP
can retry later (on next start and/or when any SIP request is received from the
target user) reporting status 4 instead of 3 on failed delivery. The MD5
checksum in this case will be calculated from concatendated pending message
text and not for the last message.
CHATCOMPOSING,line,peername,status
Chat “is composing”
notifications.
Line: used phone line
Peername: username of the peer
Status: 1 means other party is
typing, 2 means other party is idle or stopped typing
CDR,line, peername,caller,
called,peeraddress,connecttime,duration,discparty,reasontext
After each call, you
will receive a CDR (call detail record) with the following parameters:
Line: used phone line
Peername: other party username, phone
number or SIP URI
Caller: the caller party name (our
username in case when we are initiated the call, otherwise the remote username,
displayname, phone number or URI)
Called: called party name (our
username in case when we are receiving the call, otherwise the remote username,
phone number or URI)
Peeraddress: other endpoint address
(usually the VoIP server IP or domain name)
Connecttime: milliseconds elapsed
between call initiation and call connect
Duration: milliseconds elapsed
between call connect and hangup (0 for not connected calls. Divide by 1000 to
obtain seconds.)
Discparty: the party which was
initiated the disconnect: 0=not set, 1=AJVoIP, 2=peer, 3=undefined
Disconnect reason: a text about the reason of the call
disconnect (SIP disconnect code, CANCEL, BYE or some other error text)
VREC,line,stage,type,path,reason
Voice upload status
(for voice recording / call recording).
line: channel number (note: with stage 3 and 4 it will always report -1 or
-2 means default/not specified)
stage: 0:disabled,
1:call record begin,2:upload begin, 3: upload success, 4: upload fail (note: stage 0 might not be reported)
type: upload method: 0:
unknown, 1: local file, 2: ftp, 3: http, 4: server
path: upload path/file
(note:
if stage is 1 then type and path is not
reported yet)
reason: failure reason (if stage is 4)
Voice activity.
This is sent in around
every 2000 milliseconds (2 seconds) by default (configurable with the vadstat_ival
parameter in milliseconds) if you set the “vadstat” parameter to 3 or it can be
requested by VAD. Also make sure that the “vad” parameter is set to at least
“2”.
This notification can
be used to detect speaking/silence or to display a visual voice activity indicator.
Format:
VAD,local_vad:
ON local_avg: 0 local_max: 0 local_speaking: no remote_vad: ON remote_avg: 0
remote_max: 0 remote_speaking: no
Parameters:
local_vad: whether VAD
is measured for microphone: ON or OFF
local_avg: average
signal level from microphone
local_max: maximum
signal level from microphone
local_speaking: local
user speak detected: yes or no
remote_vad: whether VAD
is measured from peer to speaker out: ON or OFF
remote_avg: average
signal level from peer to speaker out
remote_max: maximum
signal level from peer to speaker out
remote_speaking: peer
user speak detected: yes or no
RTPSTAT,quality,sent,rec,issues,loss
Media quality reports.
Can be enabled by the rtpstat parameter.
The parameters are
calculated since the last RTPSTAT notification (for the past x seconds).
Parameters:
·
Quality: quality
points between 0 and 5. The calculations considers many factors such as RTP
issues, RTCP reports, codec problems, packet loss, packet delay, jitter and
processing delay.
The following values are defined:
o
0: no audio or
non-recognizable voice
o
1: very bad
quality
o
2: bad quality
o
3: medium quality
o
4: good quality
o
5: excellent
quality
·
Sent: RTP packets
sent
·
Rec: RTP packets
received and played
·
Issues: number of
issues (any issues are counted, such as sequence number mismatch or packet
drop)
·
Loss: lost
packets
More details here.
Sent for conference
calls. You might update the displayed peer name with the peers strings received
here.
The peers parameter is
the list of members separated by |. For example: Kate | John | Linda
This message is sent
immediately after startup (so from here you can also know that the SIP engine
was started successfully).
The what parameter can
have the following values:
“api” -api is ready to
use
“sip” –sipstack was
started
This message is sent
when the SIP stack is terminated/destroyed.
You should restart AJVoIP
(or reinit the library) when you receive this notification.
This is usually sent
when network was changed (connection type, IP address), thus it might be best
to reinitialize the whole SIP stack to recalculate the optimized environment
variables. The message is not sent while in call.
This message is sent
when the active line is changed.
Important events which
should be displayed for the user.
The following TYPE are
defined: EVENT, WARNING, ERROR
This means that you
might receive messages like this:
WPNOTIFICATION,EVENT,EVENT,any
text NEOL \r\n
These messages will be
received only if you set the “events” parameter to 2. (by default is set to 2)
Should be displayed for
the users in some way (hint/toast).
Example: Toast.makeText(appcontext, txt, Toast.LENGTH_LONG).show();
Detailed logs (may
include SIP signaling).
The following TYPE are
defined: EVENT, WARNING, ERROR
These messages will be
received only if you set the “events” parameter to 3. (by default is set to 2)
RTP statistics.
Example: RTP: sent
15695 lasts: 0 (p2p: 0 sdp: 0 rrp: 15695 tnl: 15701), rec: 17281 lastr: 0,
loss: 201 1%, cpu: 0.0%, cpurel: 0.0% (0.0), srvsent: 10326 srvrec: 10302
srvloss: 10 0%
Format: messageheader,
messagetext. The followings are defined:
“START”
[api/sip]. You should start to call the API only after you receive the
START,api notification.
“CREDIT” messages are received
with the user balance status if the server is sending such messages.
“RATING” messages are received
on call setup with the current call cost (tariff) or maximum call duration if
the server is sending such messages.
“MWI” messages are received on
new voicemail notifications if you have enabled voicemail and there are pending
new messages
“PRESENCE” peer online status
“SERVERCONTACTS” contact found
at local VoIP server
“NEWUSER” new user request
“ANSWER” answer for previous
request (usually http requests)
Here is how the
notifications looks like in a typical session (start, register, make a call, hangup,
terminate):
WPNOTIFICATION,START,api,NEOL
WPNOTIFICATION,START,sip,NEOL
WPNOTIFICATION,STATUS,-1,Initialized,NEOL
WPNOTIFICATION,STATUS,-1,Register...,NEOL
WPNOTIFICATION,EVENT,EVENT,Connecting...,NEOL
WPNOTIFICATION,STATUS,-1,Registering...,NEOL
WPNOTIFICATION,STATUS,0,Registering,istvantest2,istvantest2,1,voip.mizu-voip.com,[2e1123294504249584311k49333rmwp],,1,4,0,0,0,0,0,NEOL
WPNOTIFICATION,CREDIT,Credit:
4.2 USD,NEOL
WPNOTIFICATION,STATUS,-1,Registered.,NEOL
WPNOTIFICATION,EVENT,EVENT,Authenticated
successfully. [ep: 0 2e1123294504249584311k49333rmwp Registering 12538],NEOL
WPNOTIFICATION,STATUS,0,Registered,istvantest2,istvantest2,1,voip.mizu-voip.com,[2e1123294504249584311k49333rmwp],,1,2,0,0,0,0,0,NEOL
WPNOTIFICATION,STATUS,-1,Starting
call to testivr3,NEOL
WPNOTIFICATION,EVENT,EVENT,call
[wpmain],NEOL
WPNOTIFICATION,STATUS,-1,Call,NEOL
WPNOTIFICATION,STATUS,-1,Call
Initiated,NEOL
WPNOTIFICATION,STATUS,1,CallSetup,testivr3,istvantest2,1,testivr3,0,0,0,100,,[6e4351661777543861707k49334rmwp],1,2,1,0,0,0,0,NEOL
WPNOTIFICATION,STATUS,1,Routed,testivr3,istvantest2,1,testivr3,[6e4351661777543861707k49334rmwp],,1,2,1,0,0,0,0,NEOL
WPNOTIFICATION,STATUS,1,InProgress,testivr3,istvantest2,1,testivr3,[6e4351661777543861707k49334rmwp],,1,2,1,0,0,0,0,NEOL
WPNOTIFICATION,STATUS,-1,Calling...,NEOL
WPNOTIFICATION,STATUS,1,Ringing,testivr3,istvantest2,1,testivr3,[6e4351661777543861707k49334rmwp],,1,2,1,0,0,0,0,NEOL
WPNOTIFICATION,STATUS,-1,Ringing...,NEOL
WPNOTIFICATION,STATUS,1,CallConnect,testivr3,istvantest2,1,testivr3,0,0,0,100,,[6e4351661777543861707k49334rmwp],1,2,2,0,0,0,0,NEOL
WPNOTIFICATION,STATUS,1,Speaking,testivr3,istvantest2,1,testivr3,[6e4351661777543861707k49334rmwp],,1,2,2,0,0,0,0,NEOL
WPNOTIFICATION,STATUS,-1,Speaking
(0 sec),NEOL
WPNOTIFICATION,STATUS,-1,Hangup,NEOL
WPNOTIFICATION,STATUS,-1,Speaking
(2 sec),NEOL
WPNOTIFICATION,EVENT,EVENT,hangup
[wpmain],NEOL
WPNOTIFICATION,STATUS,1,CallDisconnect,testivr3,istvantest2,1,testivr3,98,98,0,100,,[6e4351661777543861707k49334rmwp],1,2,0,0,0,0,0,NEOL
WPNOTIFICATION,STATUS,-1,Call
Finished,NEOL
WPNOTIFICATION,CDR,1,testivr3,istvantest2,testivr3,voip.mizu-voip.com,1499,1969,1,User
Hung Up (exD),[6e4351661777543861707k49334rmwp],NEOL
WPNOTIFICATION,STATUS,1,Finishing,testivr3,istvantest2,1,testivr3,[6e4351661777543861707k49334rmwp],,1,2,0,0,0,0,0,NEOL
WPNOTIFICATION,EVENT,EVENT,Call
duration: 2 sec [ep: 1 6e4351661777543861707k49334rmwp Finishing 12538],NEOL
WPNOTIFICATION,STATUS,1,Finished,testivr3,istvantest2,1,testivr3,[6e4351661777543861707k49334rmwp],,1,2,0,0,0,0,0,NEOL
WPNOTIFICATION,STATUS,-1,Registered.,NEOL
WPNOTIFICATION,STOP,api,NEOL
Parse notifications code example
Below is a short
code snippet demonstrating basic notification parsing.
Notifications
handling is all about a bit of string parsing so maybe better if you just
implement it from scratch so you will be more familiar with your own logic then
the string handling practices in this example code.
In this example we
assume that we receive the notifications in a function called
ProcessNotifications.
public void ProcessNotifications(String receivednot)
{
if (receivednot == null || receivednot.length() < 1) return;
// we can receive multiple notifications at once, so we split them by CRLF or with ",NEOL \r\n" and we end up with a String array of notifications
String[] notarray = receivednot.split(",NEOL \n");
for (int i = 0; i < notarray.length; i++)
{
String notifywordcontent = notarray[i];
if (notifywordcontent == null || notifywordcontent.length() < 1) continue;
notifywordcontent = notifywordcontent.trim();
notifywordcontent = notifywordcontent.replace("WPNOTIFICATION,", "");
// now we have a single notification in the "notifywordcontent" String variable
Log.v("AJVOIP", "Received Notification: " + notifywordcontent);
int pos = 0;
String notifyword1 = ""; // will hold the notification type
String notifyword2 = ""; // will hold the second most important String in the STATUS notifications, which is the third parameter, right after the "line' parameter
// First we are checking the first parameter (until the first comma) to determine the event type.
// Then we will check for the other parameters.
pos = notifywordcontent.indexOf(",");
if(pos > 0)
{
notifyword1 = notifywordcontent.substring(0, pos).trim();
notifywordcontent = notifywordcontent.substring(pos+1, notifywordcontent.length()).trim();
}
else
{
notifyword1 = "EVENT";
}
// Notification type, "notifyword1" can have many values, but the most important ones are the STATUS types.
// After each call, you will receive a CDR (call detail record). We can parse this to get valuable information about the latest call.
// CDR,line, peername,caller, called,peeraddress,connecttime,duration,discparty,reasontext
// Example: CDR,1, 112233, 445566, 112233, voip.mizu-voip.com, 5884, 1429, 2, bye received
if (notifyword1.equals("CDR"))
{
String[] cdrParams = notifywordcontent.split(",");
String line = cdrParams[0];
String peername = cdrParams[1];
String caller = cdrParams[2];
String called = cdrParams[3];
String peeraddress = cdrParams[4];
String connecttime = cdrParams[5];
String duration = cdrParams[6];
String discparty = cdrParams[7];
String reasontext = cdrParams[8];
}
// lets parse a few STATUS notifications
else if(notifyword1.equals("STATUS"))
{
//ignore line number. we are not handling it for now
pos = notifywordcontent.indexOf(",");
if(pos > 0) notifywordcontent = notifywordcontent.substring(pos+1, notifywordcontent.length()).trim();
pos = notifywordcontent.indexOf(",");
if(pos > 0)
{
notifyword2 = notifywordcontent.substring(0, pos).trim();
notifywordcontent = notifywordcontent.substring(pos+1, notifywordcontent.length()).trim();
}
else
{
notifyword2 = notifywordcontent;
}
if (notifyword2.equals("Registered."))
{
// means the SDK is successfully registered to the specified VoIP server
}
else if (notifyword2.equals("CallSetup"))
{
// a call is in the setup stage
}
else if (notifyword2.equals("Ringing"))
{
// check the other parameters to see if it an incoming call and display an alert for the user
}
else if (notifyword2.equals("CallConnect"))
{
// call was just connected
}
else if (notifyword2.equals("CallDisconnect"))
{
// call was just disconnected
}
else if (notifyword1.equals("CHAT"))
{
// we received an incoming chat message (parse the other parameters to get the sender name and the text to be displayed) }
}
else if(notifyword1.equals("ERROR"))
{
// we received an error notification; at least log it somewhere
Log.e("AJVOIP", "ERROR," + notifywordcontent);
}
else if(notifyword1.equals("WARNING"))
{
// we received a warning notification; at least log it somewhere
Log.w("AJVOIP", "WARNING," + notifywordcontent);
}
else if(notifyword1.equals("EVENT"))
{
// display important event for the user
Log.v(notifywordcontent);
}
}
}
The Android SDK is very flexible and you
have a long list of parameters that you can use, however this doesn’t mean that
the usage is difficult. You can ignore most of these them and use only those
few relevant for your needs also outlined in the usage example. Usually you
only have to pass the basic parameters and change the advanced parameters only
if really required for you specific use-case.
Parameters can be specified with the SetParameter or SetParameters API calls.
Example: mysipclient.SetParameter("username","sdktest2");
All parameters can be passed as strings and will be converted to the proper
type internally by the Android SIP library .
Note:
§ Once a parameter is set, it might be cached by AJVoIP
and used even if you remove it later. To prevent this, always set all the
parameters to their value if you changed it before. Strings can be set to “DEF”
or “NULL”. So instead of just deleting, set its value to “DEF” or “NULL”. “DEF”
means that it will use the parameter default value if any. “NULL” means empty
for strings, otherwise the parameter default value. Example: transport=DEF
§ Not all parameters can be changed at runtime. It is
recommended to set all the relevant parameters (with the SetParameter or
SetParameters functions) before to call the Start function. You can just
restart the sip stack if you need reconfiguration at runtime (stop the current
AJVoIP instance and create a new one).
These are the most
important parameters.
(string)
The domain name or IP
address of your SIP server. By default it uses the standard SIP port (5060). If
you need to connect to other port, you can append the port after the address
separated by colon.
Examples:
“mydomain.com” -this
will use the default SIP port: 5060
“sip.mydomain.com:5062”
“10.20.30.40:5065”
Default value is empty.
If not set, then you (or the users) will
be able to call only using full SIP URI and it is more difficult to accept
incoming calls. If set, then any username/phone number can be called what is
accepted by the server.
As the SIP server you can use any
softswitch, IP-PBX, SIP proxy server or SIP gateway (with or without
registration). Some SIP services requires the use of an outbound proxy.
(string)
This is the SIP
username (A number/Caller-ID for the outgoing calls). The AJVoIP SIP endpoint will
authenticate with this username on your SIP server.
When compact is true,
then this parameter must be filled properly. Otherwise it can be empty or
omitted so the users will have to type it.
Default value is empty.
Note: If you need a different name for
SIP user name and Auth name (authorization name) then you can use the sipusername parameter.
(string)
SIP authentication
password.
If your server doesn’t
require digest authentication or if you need only peer to peer calls then this
parameter can be omitted.
Default value is empty.
These parameters are more rarely used and should be set only if you have a
specific need or a good VoIP/Android knowledge. You should modify only those
parameters which you fully understand, otherwise better if you leave all with
the default values (the default values are already optimized for production).
(string)
Specify default SIP
username. Otherwise the “username” parameter will be used for both the username
and the authentication name.
If this is not
specified, then the “username” will be used for the From field and also for the
authentication.
If both username and
sipusername is set then
-the username will be
used in the From and Contact fields (CLI/caller-id)
-the sipusername will
be used for authentication only
Default is empty.
(string)
Specify default display
name used in “from” and “contact” headers (Enduser full name).
Default is empty (the “username”
field will be displayed for the peers)
(int)
Transport protocol for
the SIP signaling
-1: auto (auto guess)
0: UDP (User Datagram
Protocol. The most commonly used transport for SIP)
1: TCP (signaling via
TCP. RTP will remain on UDP)
2: TLS (encrypted
signaling)
3: HTTP tunneling (both
signaling and media. Supported only by mizu server or mizu tunnel)
4: HTTP proxy connect
(requires tunnel server)
5: Auto (automatic
failover from UDP to HTTP if needed)
Default is -1.
TLS/SIPS notes:
To enable full encryption set both the
transport and the mediaencryption parameters to 2.
If you set TLS (2), then make sure that
you are using the correct serveraddress parameter.
SIP servers usually listens for TLS on port 5061, thus the serveraddress should
look like yourdomain:5061.
If the SIP port is configured to 5061 and
the transport parameter is not set (-1), then it might default to 2 (TLS).
TLS 1.3 enabled by default from API level
29.
If you need strict TLS certificate
validations (not only encryption) then you might set the tlspolicy parameter to 3 (0: def-auto, 1: allows
self signed or invalid cert, 2: medium with warning if fails but continue, 3:
with server cert validation and disconnect if not secure not allowing
failbacks, 4: perform also domain validation).
Client side certificate can be also set
(ask mizutech support if you need this feature).
There is also a SetSSLContext function if
you wish to set your custom SSLContext.
(int)
Media encryption method
(encryption for the RTP streams)
-1: auto (will try SRTP
if transport is TLS)
0: not encrypted
(default)
1: auto (will encrypt
if initiated by other party)
2: SRTP
3: ZRTP (experimental)
Default is -1.
Note: To enable full encryption set both
the transport and the mediaencryption parameter to 2.
(int)
Media encryption method
0: most compatible
1: default auto
2: strict (might
disconnect if peer is not respect the standard or on protocol error)
3: allow only strict
SRTP call, otherwise disconnect
Default: 1
(int)
Internet protocol (IP
layer).
Specify if you wish to
prefer IPv4 or IPv6.
Possible values:
-1: Auto
0: IPv4 only (disable
IPv6)
1: IPv4 (parse also
IPv6)
2: Both (prefer IPv4)
3: Both (no preference)
4: Both (prefer IPv6)
5: IPv6 only (disable
IPv4)
Default is -1/Auto
(auto guessed from configurations such as serveraddress and from the SIP signaling
/ SDP).
Other IP related parameters (all are set
based on this inet parameter, but can be set also separately if you have some
special requirement):
hasipv4 (true/false), hasipv6 (true/false), listenonipv6 (true/false),
ipvdualstack (true/false), cropipv6scopeid (true/false), preferipv (-1: auto
(def to 1), 0: no preference, 1: prefer ipv4, 2: prefer ipv6)
(string)
Outbound proxy address
(Examples: mydomain.com, mydomain.com:5065, 10.20.30.40:5065)
Leave it empty if you
don’t have a stateless proxy. (Use only the serveraddress parameter)
Default value is empty.
(string)
Instead of using the
password parameter you can pass an MD5 checksum for better protection:
MD5(username:realm:password)
(The parameters are separated with the
‘:’ character)
The realm is usually your server domain
name or IP address (otherwise it is set on your server)
If you are not sure, you can find out the
realm in the “Authenticate” headers sent by your server with the” 401 Unauthorized”
messages. Example:
WWW-Authenticate: Digest realm="YOURREALM",
nonce="xxx", stale=FALSE, algorithm=MD5
Default is empty.
(string)
Set if your server
realm (SIP domain) is not the same with the “serveraddress” parameter.
If the “md5” parameter
was set, then this must match with the realm used to calculate the md5
checksum.
Default is empty, which
means that the “serveraddress” will be used.
(int)
With this parameter you
can set whether the SIP UA should register (connect) to the sip server.
0: no
1: auto guess (yes if
username/password is set, otherwise no)
2: yes
AJVoIP will also
reregister automatically based on the “registerinterval” parameter.
Default value is 1.
(int)
Registration interval
in seconds (used by the re-registration expires timer).
Default value is -1
(auto guess)
Valid range is -1
(auto) or between 10 and 30000.
Notes:
o
Many servers will not accept values
above 3600 (although the SIP stack can be auto adjust it based on server
negotiation)
o
The actual resend of the REGISTER
messages might be done at a shorter interval to cover any potential packet loss
and network/server delays.
o
When set to auto guess (-1), it
will calculate an optimal interval depending on the circumstances such as
network type, server load, transport method, data saver settings and others. It
will result to around 90-180 under normal conditions on UDP or 600 on TCP.
o
If your softswitch supports
keep-alive messages (to prevent NAT binding timeouts), then you might set to a
longer interval (~3600 sec) to prevent high CPU usage on your server especially
if you have many hundreds of SIP UA running at the same time. If your server
doesn’t support keep-alive, then you might set this to a lower value (between
30 and 90 sec. 60 sec is a good choice for most NAT devices and routers). Note
that usually this is not necessary because server side support is not needed to
keep the NAT bindings.
o
If the register expire interval is
not accepted by the server, then the SIP stack is capable to automatically
negotiate a new value as directed by the server Min-Expire header or
auto-guess.
o
The register expires might be auto
set to a higher value if push notifications are enabled to reduce the need of
push re-register/rebind requests.
(boolean)
Set to false to prevent
unregister messages to be sent by AJVoIP (for example to prevent unregister on
web page reload).
Default is true
(boolean)
Use this setting for
multi-account registration.
You can specify
multiple SIP accounts in the following format:
IP,usr,pwd,t,proxy,realm,authuser;IP2,usr2,pwd2;IP3,usr3,pwd3,
, ,realm3;IP4,usr4,pwd4…
where:
·
IP: is the SIP
server address (domain or IP:port)
·
usr: is the SIP
username
·
pwd: is the SIP
password
·
t: is the
register timeout in seconds (optional)
·
proxy: SIP proxy
(optional)
·
realm: SIP realm
(optional)
·
authusr: auth (sipusername
if separate extension id and authorization username have to be used)
See the Multiple
account registration FAQ for more
details.
(int)
Accept the expires
interval sent by the server.
0: no
1: yes (prioritize the
contact expire)
2: yes (prioritize the
global expire)
Default value is 1.
(int)
NAT keep-alive packet
send interval in milliseconds.
Keep-alive is a
mechanism to keep the NAT open between register resends (so the server can
initiate a new incoming transaction on the same stream with no issues, such as
incoming call).
Possible values:
o
-1: auto (will
default to around 28000 -28 sec- on UDP and 600000 – 10 min- on TCP)
o
0: disabled
o
other: interval
in milliseconds (must be above 3000, otherwise treated as seconds)
Default value is -1.
(int)
NAT keep-alive packet
type.
0=no keep-alive
1=space + CRLF
(_\r\n) (very efficient because low bandwidth and low server usage)
2=NOTIFY (standard
method)
3=CRLF (\r\n) (very
efficient because low bandwidth and low server usage. Not recommended)
4=CRLFCRLF (\r\n\r\n)
(very efficient because low bandwidth and low server usage. After RFC draft)
Default is 4.
(boolean)
If set to true then the
Android SIP library will immediately starts the call with the given parameters
(for example with your page load). The serveraddress, username, password,
callto must be also set for this to work.
Default value is false.
(string)
Can be any phone
number/username that can be accepted by your server or a SIP URI. Used with
“autocall” to specify the destination number.
Default value is empty.
(int)
Check rport in SIP
signaling (requested and received from the SIP server by the VIA header)
0=don’t ask (rtport
request will not be added to the VIA header)
1=use only for
symmetric NAT (only when it is sure that the public address will be correct)
2=always (always
request and use the returned value except if already on public ip)
3=request even on
public IP (meaningless in most cases)
9=request with the
signaling, but don’t use the returned value (good If you want to keep the local
IP and for peer to peer calls)
Change to 0 or 2 only
if you have NAT issues (depending on your server type and settings)
(You might adjust also
the use_fast_stun parameter if you change the use_rport)
Default is 1
(int)
Nat traversal via UpNP
supported routers.
0: disable
1: enable
Default is 1
(int)
Fast ICE negotiations
(for p2p rtp routing):
0=no (set to 0 only if
your server needs to always route the media)
1=auto
2=yes
3=always (not
recommended)
Default is 1
Note: if set to 1 or 2
then the stun should not be disabled
(int)
Fast stun request on
startup.
-1=force private
address (if the client has both private and public IP, than the private IP will
be sent in the signaling)
0=no
1=use only for stable
symmetric NAT
2=use only if both
tests match even if not symmetric (recommended)
3=use for symmetric NAT
even if only one match
4=always
5=use even on public IP
Change if you have NAT
issues (depending on your server type and settings)
(You might adjust also
the use_rport parameter if use_fast_stun is changed)
Default is 2
(int)
Specify whether the UDP
have to be connected before sending on the socket. (Some IP-PBX might require
udp connect and in this way the Android SIP library can always detect its local
address correctly. However this should not be used whit multiple servers or
separate domain and outbound proxy)
0=no
1=on init
2=on first send (not
recommended. can block)
3=on both or any (not
recommended)
Default value: 0
(int)
If to treat session
progress (183) responses as ringing (180). This is useful because some IP-PBX
never sends the ringing message, only a session progress and might start to
send in-band ringing (or some announcement)
The following values
are defined:
0: do nothing,
1: change status to
ring
2: start local ring and
be ready to accept media (which is usually a ringtone or announcement)
3: start media receive
and playback (and media recording if the “earlymedia” parameter is set)
4: change status to
ringing and start media receive and playback (and media recording if the
“earlymedia” parameter is set to true)
Default value is 2.
*Note: on ringing
status AJVoIP is able to generate local ringtone. However this locally
generated ringtone playback is stopped immediately when media is started to be
received from the server (allowing the user to hear the server ringback tone or
announcements)
(int)
Set to 1 to auto-redial
on 301/302 call forward.
Set to 0 to disable
auto call forward.
Default value is 1.
(int)
Change this option only
if you have RTP setup issues with your server(s).
UDP packets to send to
open the NAT device and initiate the RTP. Some servers will require at least 5
packets before starting to send the media after the 183 “session in progress”
response. In this case set this value to 10 (In this way the server will
receive at least 5 packets even on high packet loss networks)
0: no
1: write only an empty
udp packet
2: write a normal RTP
packet
3 or more: write this
number of RTP packets
Default is 2
*Note: instead of
sending more “fake” packets, you can set the “earlymedia” to 1 or more to begin
the rtp stream immediately.
*Note: you can use the
“natopenpackettype” to specify the format. 1 means short CRLFCRLF packet
(default). 2 means full RTP packet with zeroed content.
(int)
Start to send media
when session progress is received.
0: no
1: reserved
2: auto (will early
open audio if wideband is enabled to check if supported)
3: just early open the
audio
4: null packets only when
sdp received
5: yes when sdp
received
6: always forced yes
Default is 2.
*Note: For the early
media to work, AJVoIP has to open the NAT when SDP is received. This can be
done by sending a few fake rtp packets or by starting to send the media
immediately when session in progress is received. The first method consume less
bandwidth, but it is not supported by some softswitch.
(int)
Used only for HTTP
tunneling with Mizu VoIP servers.
0: no
1: same as sip proxy
(proxyaddress)
2: system default
3: manual (must be set
by the httpproxyurl parameter –deprecated after version 3.5)
4: auto
Default value is 4.
(string)
Useful when the
transport parameter is set to 4 (auto) to specify the http tunneling gateway
address.
Default value is null
(address loaded from the “serveraddress” parameter)
(int)
DTMF send method
0=disabled
1=SIP INFO method
(out-of-band in SIP signaling INFO messages)
2=auto (auto guess from
peer advertised capabilities)
3=INFO + NTE
4=NTE (Named Telephone
Events as specified in RFC 2833 and RFC 4733)
5=In-Band (DTMF audio
tones in the RTP stream)
6=INFO + InBand
Default is 2 (and you
should change it only if you have a good reason to do so, since the auto-detect
should work in all circumstances, except if your SIP server is sending bogus
DTMF capabilities).
Note: When more than one method is used
(dtmfmode 3 or 6), the receiver might receive duplicated dtmf digits.
(int)
Specify whether to
allow sending DTMF digits before call connect
0=no
1=auto (yes if rfc2833
or inband is allowed and already sent/received rtp packets)
2=yes (always send)
Default: 1
(int)
Subscribe to voicemail
notifications (MWI). Accepted values:
0=disabled
1=display voicemail only
if NOTIFY is received automatically without subscription
2=auto-detect if
voicemail SUBSCRIBE is needed
3=subscribe for
voicemail messages after successful registration
4=subscribe for
voicemail messages on startup
Default value is 2. Set
to 3 if your server has support for MWI to be sure that AJVoIP will check the
voicemail.
For voicemail you can
receive MWI notifications in the following format:
MWI,hasvoicemail,voicemailnumber,to,count,message
o
hasvoicemail: yes
or no (Messages-Waiting indicator)
o
voicemailnumber:
voicemail number (as configured or as received in Message-Account)
o
to: username from
the SIP To header (usually the local account username, useful if you have
multiple accounts)
o
count: number of
pending messages
o
message: message
text if sent by the server (Voice-Message)
Example: MWI,yes,5001,1111,3,3/0
(String)
Specify the voicemail
address. Most IP-PBX will automatically send the voicemail access number so you
don’t need to set this parameter.
(int)
-1=default transfer
type (same as 6)
0=call transfer is disabled
1=transfer immediately and
disconnect with the A user when the Transf button is pressed and the number
entered (unattended transfer)
2=transfer the call
only when the second party is disconnected (attended transfer)
3=transfer the call
when AJVoIP is disconnected from the second party (attended transfer)
4=transfer the call
when any party is disconnected except when the original caller was initiated
the disconnect (attended transfer)
5=transfer the call
when AJVoIP is disconnected from the second party. Put the caller on hold
during the call transfer (standard attended transfer)
6=transfer the call
immediately with hold and watch for notifications (unattended transfer)
7=transfer with no hold
and no disconnect (simplest
unattended transfer)
8=transfer with
conference (will put the parties to conference on transfer; will mute or hold
the old party by default)
Default is -1 (which is
the same as 6)
Note:
·
Unattended means simple immediate
transfer (just a REFER message sent)
·
Attended transfer means that there
will be a consultation call first
·
The most popular transfertypes are
1, 5 and 6
·
If you have any incompatibility
issue, then set to 7 (unattended is the simplest way to transfer a call and all
sip server and device should support it correctly)
·
More details can be found here.
(int)
Specify if replace
should be used with transfer so the old call (dialog) is not disconnected but just
replaced.
This way the A party is
never disconnected, just the called party is changed. The A party must be able
to handle the replace header for this.
-1=auto
0=no
1=yes
Default is -1
(int)
Allow incoming replace
requests.
0=no
1=yes and always
disconnect old ep
2=yes and don't
disconnect if in transfer
3=yes but never
disconnect old ep
Default is 2.
(int)
Specify if line should
disconnect after transfer if not determined by the other transfer related
configurations.
-1=auto
0=never
1= on C party connected
status
2= on timeout
3= on connected or
timeout
4= on ok for refer
Default is -1
(int)
Specify if line should
disconnect after incoming transfer
-1=auto
0=no
1= yes
Default is -1
(int)
Milliseconds to wait
before sending REFER/INVITE while in transfer.
Default value is 400.
(int)
Specify if to handle
transfer subscription state (such as reload the call on transfer failure)
-1=auto
0=no
1= disconnect
2= reload
Default is -1
(int)
Create subscribe dialog
for call transfer.
-1=auto
0=never
1= if no notify
received
2= always
Default is -1
(int)
Specify whether to
enable direct call to SIP URI (peer to peer or via server)
0=no (so you should use
only the username part of the SIP URI to make calls. set the domain part as the
sipserveraddress parameter)
1=check IP in URI
(will recognize full SIP URI if the domain part can be resolved to a valid IP)
2=always check (so you
can make calls to full SIP URI without a SIP server to be set)
3=crossdomain (so you
can register to domain A and make direct call to domain B)
Default is 1
(string)
Set the character
decoding for SIP signaling.
Default is empty (will
load the local system default).
More details:
http://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html
http://www.iana.org/assignments/character-sets/character-sets.xhtml
(int)
SRV DNS record lookup
setting:
-1: auto (will check
SRV record for the VoIP server, but remembers if fails and will not check again
next time)
0: don’t lookup (will
use only A record)
1: lookup A record
first. If fails then lookup srv record (because mostly the srv record is not
set anyway)
2: lookup SRV record
first for VoIP server address. If fails then lookup A record (RFC compliant)
3: always lookup SRV record
first. If fails then lookup A record
4: check also without
the _sip._udp. prefix
If the SRV lookup
returns multiple records, than SIP UA will failover to the next server on
connection failures.
Default value is -1.
(int)
Domain record lookup
mode
0=auto (same as 2)
1=yes always re-query
2=use cache if needed
(default)
3=use cache whenever
possible
4=from cache only
5=disable
Default value is 0.
(int)
Force WiFi network.
Possible values:
0=no
1=auto
2=lock in call
3=lock always
4=always
5=always lock
6=extra
Default value: 1
(int)
Keep device awake
during calls.
Possible values:
0=no
1=basic only
2=auto
3=full then partial
4=always full only
Default value: 2
(boolean)
Keep a partial lock on
the CPU while in call to prevent sleep.
Default value is true.
(boolean)
Always keep a partial
lock on the CPU to prevent sleep.
Default value is false.
(boolean)
Auto handle keyguard
lock.
Default value is true.
(int)
Enable/disable
proximity sensor during calls.
Possible values:
0=disable
1=software based
(deprecated)
2=hardware based
Default value: 2
(int)
Specify how to handle
if there is a native/mobile call in progress.
Possible values:
0=don’t check (will behave as it would be without native call in
progress)
1=basic behavior changes (such as no ring)
2=don’t alter the audio
Default value: 1
Should be set to 1 if
using connection service or keep 1 always.
(int)
Specify when to use
Bluetooth device.
Possible values:
0=guess
1=no
2=yes
Default value: 0
Set this parameter to 2 before the call
if you have Bluetooth connectivity issues.
(int)
Enable/disable
video.
Possible values:
-1: auto (default)
0: disable
1: enable
2: force always
RTC capabilities
must be available for video to work.
(int)
Speaker device to be
used.
Possible values:
0=default (usually speakerphone/headphone)
1=headphone (speakerphone/headphone)
2=speakerphone (loudspeaker)
Default value: 0
(int)
Overwrite audio mode
which is set by AJVoIP by calling the AudioManager.setMode API.
By default AJVoIP will
set the audio mode depending on the circumstances (call type, OS version, etc).
You might use this
parameter to force an audio mode after your needs. It can be also changed at
runtime and it will be applicable for the next setMode function calls.
Possible values:
-9: automatically
managed by AJVoIP (recommended)
-8: never change
0: MODE_NORMAL
1: MODE_RINGTONE
2: MODE_IN_CALL
3:
MODE_IN_COMMUNICATION
4: MODE_CALL_SCREENING
5: MODE_CALL_REDIRECT
6:
MODE_COMMUNICATION_REDIRECT
Default value: -9
(int)
Specify whether to use
audio “focus”. (Auto decrease the volume of other apps).
Possible values:
0: auto
1: no
2: yes
Default value: 0
(int)
Speakerphone output
device.
Possible values:
0: Auto guess
1: Speaker
2: Speaker Forced
3: VoIP
4: Bluetooth
5: No changes
Default value: 0
(int)
Audio recorder stream.
Possible values:
0: Default
1: Auto guess
2: Mic
3: Voice call
4: Voice downlink
5: Voice uplink
6: Voice communication
Default value: 1
(Normally it should be
set to 0,1 or 2. Other values are very unusual)
(int)
Audio player stream for
calls.
Possible values:
0: STREAM_VOICE_CALL
1: STREAM_SYSTEM
2: STREAM_RING
3: STREAM_MUSIC
4: STREAM_ALARM
5: STREAM_NOTIFICATION
Default value: 0
(int)
Audio speakerphone
player stream.
Possible values:
0: STREAM_VOICE_CALL
1: STREAM_SYSTEM
2: STREAM_RING
3: STREAM_MUSIC
4: STREAM_ALARM
5: STREAM_NOTIFICATION
6: default
Default value: 0
(int)
Audio player stream for
ring.
Possible values:
0: STREAM_VOICE_CALL
1: STREAM_SYSTEM
2: STREAM_RING
3: STREAM_MUSIC
4: STREAM_ALARM
5: STREAM_NOTIFICATION
Default value: 2
(int)
With this, you might
overwrite the setUsage parameter for the AudioAttributes.
Default is USAGE_VOICE_COMMUNICATION.
(int)
Specify when to switch
to speaker mode.
Possible values:
0: auto
1: never
2: always
Default value: 0
(int)
You can disable audio
playback and/or recording streams with this option (will still open the device,
but will not record/playback)
0=disable all
1=disable recording
2=disable playback
3=enable all
Default value is 3.
(boolean)
Set to false to disable
using the audio input device (microphone). In this case you should also set the
mediatimeout parameter to 0.
Default is true.
(boolean)
Set to false to disable
using the audio output device (speaker/earphone). In this case you should also
set the mediatimeout parameter to 0.
Default is true.
(int)
Vibrate on incoming
call
0=auto (depends on
phone settings)
1=no
2=yes
Default is 0.
(int)
Generate ringtone for
incoming and outgoing calls.
0=no (you can generate
ringtone also by using the Java API to playback a sound file when you receive
ringing notifications)
1=play ringtone for
incoming calls
2=play ringtone for
incoming and outgoing calls. (ringtone for outgoing calls can be generated also
by your VoIP sever. When remote ringtone is received, java softphone will stop
the local ringtone playback immediately and starts to play the received
ringtone or announcement)
Default is 2.
(string)
Specify a ringtone
sound file or URI (system ring tones) to be used.
If you use a file instead of a system
ringtone URI:
·
Set only the file name, not the
full path. Copy the file to your app folder or near the AJVoIP library
·
The file should be in the following
format: PCM SIGNED 8000.0 Hz (8 kHz) 16 bit mono (2 bytes/frame) in
little-endian (128 kbits).
·
You can use any sound editor to
convert your file to this format (usually from File menu -> Save as).
Default value is empty.
If not specified, then AJVoIP will use the default ringtone for call alert.
Example:
This example code illustrates how to present the UI for the user for
choosing a native ringtone from android device ad how to get the path of the
ringtone audio file:
Open ringtone UI:
public final int RINGTONE_REQCODE = 123456; // request code used in onActivityResult
String title = "Select
your ringtone";
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, title);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALL);
startActivityForResult(intent, RINGTONE_REQCODE);
Get the path to the selected ringtone in onActivityResult:
protected void onActivityResult(int requestCode, int resultCode,
Intent data)
{
if (requestCode
== RINGTONE_REQCODE)
{
if(resultCode
== RESULT_OK)
{
String ringTonePath = "";
Uri uri =
data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if (uri != null)
{
// the absolute path to the ringtone audio
file selected by the user
ringTonePath = uri.toString();
Log.v("AJVOIP", "User selected
ringtone path: " + ringTonePath);
// pass it to AJVoIP
mysipclient.SetParameter("ringtone",
ringTonePath);
}
}
if (resultCode
== RESULT_CANCELED)
{
Log.v("AJVOIP", "user canceled
ringtone selection");
}
}
}
(int)
Ring while in call if incoming
or outgoing call
0=No
1=Only a beep for
incoming call
2=Yes, normal ring
Default value is 1
(int)
Check if audio device
is muted or volume settings are too low (and un-mute and/or increase volume if
necessary).
0: no
1: at first run
2: always
Default value is 1
(int)
Default microphone
volume in percent from 0 to 100. 0 means muted. 100 means maximum volume, 0 is
muted.
Default is 50% (not
changed)
Note:
The result volume level might be affected
by the AGC if it is enabled.
Volume levels above 70% might result in
distorted sound.
Usually it should not be changed as users
should control the volume by OS level volume controls.
(int)
Default speaker volume
in percent from 0 to 100. 0 means muted. 100 means maximum volume, 0 is muted.
Default is 50% (not
changed)
Note:
The result volume level might be affected
by the AGC if it is enabled.
Volume levels above 70% might result in
distorted sound.
Usually it should not be changed as users
should control the volume by OS level volume controls.
(int)
Default ringback volume
in percent from 0 to 100. 0 means muted. 100 means maximum volume, 0 is muted.
Default is 50% (not
changed)
Note: Usually it should not be changed as
users should control the ringer by OS level volume controls.
(int)
Will play a short sound
when calls are connected
0=Disabled
1=For auto accepted
incoming calls
2=For incoming calls
3=For outgoing calls
4=For all calls
Default value is 0
(int)
DTMF sounds on key
press.
0=No
1=Yes for one digit
2=Yes also if multiple
digits
Default is 1
(int)
Automatic gain control.
0=Disabled
1=For recording only
2=Both for playback and
recording
3=Guess
Default value is 3
This will also change the effect of the volumein
and volumeout settings.
(boolean)
Enable/disable packet
loss concealment
Default is true (enabled)
(int)
Enable/disable voice
activity detection.
0: auto
1: no
2: yes for player (will
help the jitter)
3: yes for recorder
4: yes for both
Default is 2.
Notes:
-The vad parameter is
automatically set to 4 by default if the aec2 algorithm is used.
-If you wish to use VAD
related statistics in your application, you might have to also set the “vadstat”
parameter after your needs. Possible values: 0=no,1=auto (default),2=detect no
mic audio,3=send statistics. See the VAD notification and VAD for more
details.
-If you want to disable
audio related notifications (microphone warning on no signal detected) then set
the “enablenomicvoicewarning” parameter to 0
(int)
Enable/disable RTP
statistics by triggering RTPSTAT notifications.
Possible values:
-1: auto (will trigger
RTPSTAT events in every 6-7 seconds and more frequently at the beginning of the
calls)
0: disabled
Positive value: seconds
to generate RTPSTAT events.
Default is 0 (disabled)
More details here.
(int)
Enable/disable acoustic
echo cancellation
0=no
1=yes except if headset
usage guessed
2=yes if supported
3=forced yes even if
not supported (might result in unexpected errors)
Default is 1.
Note:
The aec decision might be overwritten or
modified by the aectype parameter.
After tests, the success rate of the
built-on AEC algorithms is above 90%. This is considered a good value as there
are no any perfect aec algorithms, but it might not work (or partially work) in
some devices or circumstances (depends on many factors such as audio hardware,
driver, OS/device, environment/room, codec, network delay).
For more details, read here.
(string)
AEC algorithm(s) to
use.
One or more of the
following strings separated by comma:
·
auto: will select
automatically based on circumstances (CPU power, device capabilities, network)
·
none: disable aec
·
software:
software aec (requires extra CPU processing)
·
hardware: android
hardware aec capabilities (not supported on all phones)
·
fast: a fast
software aec implementation (used preferably on slow/old devices or in addition
for the above algorithms)
·
volume: this will
just decrease the volume when speech detected from other end (using VAD)
Default is auto.
Note:
o
It is recommended to leave both the
aec and aectype values with its default values
o
To force all echo cancellations
algorithms you might set the aec to “2” and the aectype to
“software,hardware,fast,volume” (this might be too much, forcing the software
to do unnecessary processing and in some circumstances it might remove too much
audio)
For more details, read here.
(int)
Noise suppression.
0=Disabled
1=For recording only
2=Both for playback and
recording
3=Auto guess
Default value is 3
(int)
Enable/disable silence
suppression
Usually not recommended
unless your bandwidth is really bad and expensive.
-1=auto
0=no (disabled)
1=yes
Default is -1 (which
means no, except mobile devices with low bandwidth)
(int)
Enable the usage of OS/hardware
level audio processing for aec/denoise/silence suppress.
0=auto
1=no
2=yes
Default is 0
Note: even if this is set to 2, the media
stack might not use the android hardware capabilities if you disable
aec/denoise/silencesupress by their respective parameters
(boolean)
Enable/disable rtcp. (RFC
3550. Partial support)
(string)
List of allowed
audio codec’s separated by comma.
Will accept one or
more of the following strings (upper or lower case doesn’t matter):
pcmu, pcma,
g711 (for both PCMU and PCMA), g719, gsm, ilbc, speex, speexwb, speexuwb, opus,
opuswb, opusuwb, opusswb, def
By default the
Android SIP library will automatically choose the best codec depending on
available codec’s, circumstances (network/device) and peer capabilities.
Set this parameter
only if you have some special requirements such as forcing a specific codec,
regardless of the circumstances.
Default: empty
(which means auto detection and negotiation)
Recommended value:
leave it empty for “best” codec negotiation unless if you have some specific
requirement.
Example: OpusWB,G.729,PCMU (This will disable Speex, GSM,
iLBC, GSM and PCMA).
You can also set one
single codec (if your server/peers allows only one codec or for testing to rule
out all kind of codec negotiation related issues).
You can set to “def” to enable all the default codec’s again.
Under normal circumstances, the
following is the built-in codec priority:
I.
Wideband Speex and
Opus (These are set with top priority as they have the best quality. Likely
used for VoIP to VoIP calls if the peer also has support for wideband)
II.
G.729 (Usually the
preferred codec for VoIP trunks used for mobile/landline calls because it’s
excellent compression/quality ratio for narrowband)
III.
iLBC, GSM (If
G.729 is not supported then these are good alternatives. iLBC has better
characteristics and GSM is better supported by legacy hardware)
IV.
G.711: PCMU and
PCMA (Requires more bandwidth, but has the best narrowband quality)
The default codec order will highly
depends on the device CPU power (high-complexity codec’s are deprioritized on
low-end devices) and network type (high bandwidth codec’s are deprioritized on
slow networks such as GPRS, 2G or slow 3G). On a decent device with good
internet connection (WiFi, LTE, 5G, 4G or good 3G) the softphone should pick up
the Opus wideband if peer has support for this codec. If peer has support only
for narrowband then G.729 should be selected, otherwise another codec
negotiated with the peer endpoint.
More details here.
Note: for the codec
configuration, either use the codec/prefcodec settings OR the use_xxx settings (where
xxx is the codec name; listed below).
You can achieve similar result with both. The use_xxx settings are a little bit
more flexible regarding the codec prioritization.
(int)
Set your preferred audio
codec.
Will accept one the
following strings (upper or lower case doesn’t matter):
pcmu, pcma,
g711 (for both PCMU and PCMA), g719, gsm, ilbc, speex, speexwb, speexuwb, opus,
opuswb, opusuwb, opusswb
Default is empty
which means the built-in optimal prioritization.
By default the SIP
stack will present the codec list optimized regarding the circumstances (the
combination of the followings):
·
available
client codec set (not all engines supports all codecs)
·
server
codec list (depending on your server, peer device or carrier)
·
internal/external
call: for IP to IP calls will prioritize wideband codecs if possible, while for
outbound calls usually G.729 will be selected if available
·
network
quality (bandwidth, delay, packet-loss, jitter): for example iLBC is more
tolerant to network problems if supported
·
device
CPU: some old mobile devices might not be able to handle high-complexity
codec’s such as opus or G.729. G711 and GSM has low computational costs
You can also
fine-tune the codec settings with the use_xxx settings described below.
(string)
List of allowed video
codec’s separated by comma (H264, VP8, VP9).
You might use this
parameter to exclude some codec from the offer list.
For example if you
wish to use only H.364, then set this to: “H264”
Default: empty (which
means auto detection and negotiation)
(int)
Max bandwidth for
video in kbits.
It will be sent also
with SDP “b:AS” attribute.
Default is 0 which
means auto negotiated via RTCP and congestion control.
(int)
You can suggest the
size of the video (in pixels) with the following parameters:
·
video_width
·
video_height
·
video_min_width
·
video_min_height
·
video_max_width
·
video_max_height
(int)
GSM codec setting.
0=never,1=don’t offer,2=yes with low priority,3=yes with high priority
Default is 1.
(int)
iLBC codec setting.
0=never,1=don’t offer,2=yes with low priority,3=yes with high priority
Default is 1.
(int)
Narrowband speex codec
setting. 0=never,1=don’t offer,2=yes with low priority,3=yes with high priority
Default is 1
(int)
Wideband speex codec
setting. 0=never,1=don’t offer,2=yes with low priority,3=yes with high priority
Default is 2
(int)
Ultra wideband speex
codec setting. 0=never,1=don’t offer,2=yes with low priority,3=yes with high
priority
Default is 1
(int)
Narrowband (8000 Hz)
opus codec setting. 0=never,1=don’t offer,2=yes with low priority,3=yes with
high priority
Default is 1
(int)
Wideband (16000 Hz)
opus codec setting. 0=never,1=don’t offer,2=yes with low priority,3=yes with
high priority
Default is 2
(int)
Super wideband (24000
Hz) opus codec setting. 0=never,1=don’t offer,2=yes with low priority,3=yes
with high priority
Default is 1
Note: this codec might not work on all
devices, depending on the audio device and driver capabilities!
(int)
Ultra wideband (fullband
at 48000 Hz) opus codec setting. 0=never,1=don’t offer,2=yes with low
priority,3=yes with high priority
Default is 1
(int)
G.729 codec setting.
0=never,1=don’t offer,2=yes with low priority,3=yes with high priority
Default is 2
*In some countries a license/patent is required if you
use G.729 so enable only if you have licenses or licenses are not required in your
case (consult your lawyer if you are not sure)
(int)
G711alaw codec.
0=never,1=don’t offer,2=yes with low priority,3=yes with high priority
Default is 2
(int)
G711ulaw codec.
0=never, 1=don’t offer, 2=yes with low priority, 3=yes with high priority
Default is 1
(int)
This setting will
disable speex and opus wideband and ultrawideband for outgoing calls to regular
phone numbers since these are usually not supported for pstn calls and they
might requires longer initialization.
0: no
1: check at first call
2: check all calls
Default is 0.
(int)
Some server cannot
handle the final codec offer in the ACK message correctly.
In this case you will
have to set this setting to 0, otherwise you will have one way audio.
0=never (RFC compliant)
1=auto guess (not send
in case of certain servers and autocorrect in subsequent calls)
2=when multiple codecs
are received
3=always reply with the
final codec in the ACK message
Default value is 1.
(int)
Enable 3GPP
(IMS/5G/VoLTE) features.
Possible values:
-1: auto detect (default)
0: disable
1: basic
2: full/all
It is also possible to
enable only certain 3GPP features. In this case use the following
parameters instead of ims3gpp:
o
ims3gpp_phonenum: use tel URI and set user=phone
(-1: auto, 0: no, 1: user=phone, 2: also tel uri). Note: you might also use the
sipproto param.
o
ims3gpp_minphonelen: tel uri only if phone number is
longer then this. Default is 4. Set to 0 to use tel also for non-phone number
peers
o
ims3gpp_authuname: auth username must contain the
domain (-1: auto, 0: no. 1: yes)
o
ims3gpp_ussd: IMS USSD described at 3GPP TS 24.390. Send with SendUSSD,
receive as USSD notifications (-1: auto, 0: no, 1: yes)
o
ims3gpp_sms: +g.3gpp.smsip with MESSAGE using binary encoded PDU’s described in 3GPP TS 24.011 (-1: auto, 0: no, 1: yes)
o
ims3gpp_smsc: SMSC Center Address number.
Otherwise AJVoIP will use the destination number (if that is a phone number)
(int)
Specify if to enable
3PCC Third Party Call Control as described at RFC 3725.
Note: 3PCC has nothing to do with 3GPP.
They are completely different technologies.
This feature is often
used in callcenters or for click-to-call to setup calls between two or more
other parties.
Possible values:
0: disable (block 3PCC requests)
1: don't handle
2: accept (handle
incoming requests)
3: initiate 3PCC calls
by sending with no SDP
4: initiate 3PCC calls
by sending SDP with connect IP set 0.0.0.0
5: initiate 3PCC calls
by sending SDP with no media line
Default is 2.
If 3pcc is enabled,
then AJVoIP will send the codec answer in ACK if not received by INVITE or it
will re-INVITE if received SDP with no media line or with 0.0.0.0 contact IP,
thus allowing all the possible third party call controls.
Some more related
information can be found here, here, here and here.
You might also set the autoaccept parameter to true
if AJVoIP acts as an auto-responder.
(int)
Enable/disable the
ED-137 behavior to be used for air traffic management services.
Set to 0 to ignore the
ED-137 specification (act as normally)
Set to 1 to turn on the
ED-137. This will change a list of internal settings and behaviors to conform
with the ED-137 specification.
Default value is 0.
See the ED-137 guide for more details.
(int)
Set to 2 to always put
low computational and low bandwidth codec in the offer list, specifically GSM
and PCMU. Low CPU or bandwidth devices might choose these codecs (such as a
mobile phone on 3G).
Set to 0 to disable.
Default is 1 (auto)
(int)
Number of payloads in
one UDP packet.
By default it is set to
0 which means 2 frames for G729 and 1 frame for all other codec.
(int)
Sets traffic class or
type-of-service octet in the IP header for packets sent from UDP socket which
can be used to fine-tune the QoS in your network. As the underlying network
implementation may ignore this value applications should consider it a hint.
The value must be
between 0 and 255.
Valid values:
Ø
0: disabled
Ø
1: automatic (set
to 10 under normal conditions and disabled when in tunneling)
Ø
2: low-cost
routing
Ø
4: reliable
routing
Ø
8: throughput
optimized routing
Ø
10: low-delay
routing
Ø
or’ing the above
values (from above 2)
Default value is 1.
Notes:
for Internet Protocol
v4 the value consists of an number with precedence and TOS fields as detailed
in RFC 1349. The TOS field is bitset created by bitwise-or'ing values such the
following :
IPTOS_LOWCOST: 2
IPTOS_RELIABILITY:
4
IPTOS_THROUGHPUT: 8
IPTOS_LOWDELAY: 16
The last low order bit
is always ignored as this corresponds to the MBZ (must be zero) bit.
For Internet Protocol
v6 tc is the value that would be placed into the sin6_flowinfo field of the IP
header.
This parameter might
work only in preset environments; the runtime might not have enough rights to
modify the IP headers.
(int)
Specify if other lines
will be muted on new call
0=no (default)
1=on incoming call
2=on outgoing call
3=on incoming and
outgoing calls
4=on other line button
click
Default is 0
(int)
Specify if other lines
will be put on hold on new call
0=no (default)
1=on incoming call
2=on outgoing call
3=on incoming and
outgoing calls
4=on other line button
click
Default is 0
(int)
Specify if line should disconnect
after transfer
-1=auto
0=no
1= yes
2= hold and reload if
needed
Default is -1
(int)
Specify call hold type.
Call hold is usually
initiated by the Hold function and with parameter you can
specify which type of call hold do you wish to request.
Possible values:
-2: no
-1: auto (defaults to
2)
0: no (don’t hold. a=sendrecv)
1: reserved (not used)
2: hold: instructs the
peer to not send audio (mute speaker. Local JVoIP: a=sendonly, peer: a=recvonly)
3: hold: not sending
audio to the other (mute microphone. Local JVoIP: a=recvonly, peer: a=sendonly)
4: hold: both (mute
both in/out audio. a=inactive)
Default is -1.
Note:
By default the hold will check the previous
state. For example if previously it was local hold (2) and you switch to remote
hold (3) then actually will switch o both hold.
There is also a holdexplicite parameter
which if set to 1, then the hold will be
done strictly after the holdtypeonhold parameter, without considering previous
state. This way you can also change between local and remote hold without the
need to unhold first.
(int)
Default mute direction
0: both
1: mute out (speakers)
2: mute in (microphone)
3: both
4: both
5: disable mute
(int)
If to send ACK for
authentication requests (401,407).
0=no
1=yes (default)
Should be changed only
if you have compatibility issues with the server used.
(int)
You may change it if
you have compatibility issues with stateless proxies
0=never
1=no
2= conform RFC
3= yes. Sending for
both server and contact URI (default)
4=always
(boolean)
Enable 100rel (PRACK)
Set to false if you
have incompatibility issues.
Default is false.
(boolean)
Will send the client
MAC address with all signaling message in the X-MAC header parameter.
Default value is false.
Note: The SDK might not have enough
rights to read the MAC address.
(string)
This will overwrite
the default User-Agent setting.
Do not set this when
used with mizu VoIP servers because the server detects extra capabilities by
reading this header.
Default is empty.
(int)
Specify if to send
the Session-ID header as specified in RFC 7989.
Possible values:
-1: if received
(default)
0: no (disable)
1: yes (enable)
Default is -1.
(string)
Set a custom sip header
(a line in the SIP signaling) that will be sent with all messages. Can be used
for various integration purposes (for example for sending the http session id).
You can also change this parameter runtime with the SetSIPHeader function.
Default value is empty.
(string)
Specify UUI data
(User-to-User Call Control Information as described in RFC 7433).
Can be used to send
data to other endpoints. Not all endpoints and SIP servers supports this
feature.
If prefixed with *0: then the UUI will be
sent only to peer with the User-to-User header.
If prefixed with *1: then the UUI will be
sent only to target party with call transfer or redirect escaped in Contact or
Refer-To URI.
If not prefixed or prefixed with *2: the
UUI will be sent both way.
Example:
It can be set also at
runtime with the SetUUI function.
Default value is empty.
Simple example: mydata
Example
with parameters: *2:mydata;encoding=hex;purpose=foo;content=bar
(string)
Add any prefix for the
called numbers.
Default is empty.
(int)
Normalize (called)
numbers by removing .-,;()[]: and space if the string otherwise doesn't
contains a-z or A-Z characters (looks like a phone number).
Possible values:
-1: auto (usually
defaults to 1 yes, except if self username also contains special characters)
0: no
1: yes
Default is -1.
(int)
Take in consideration
Android OS Data Saver settings.
0: no
1: yes
Default is 1.
If 1, then it will
change a few internal settings to use less data such as longer kee-palive and
reregister interval, prioritizing codec’s which requires less bandwidth, auto
enable silence suppression and more.
(int)
Take in consideration
Android DND settings (Do Not Disturb).
0: no
1: yes
Default is 1.
(int)
Take in consideration
Android OS Airplane mode settings.
0: no
1: yes
Default is 1.
If 1, then it will not
force network (and wifi) reconnect if no network.
(boolean)
If set to true, than
users must register before to make any calls.
Default value is false.
(int)
Set to true to reject the
incoming calls if there is already a native phone call in progress (GSM/mobile
call).
Possible values:
0: Reject calls
1: Allow calls
2: Forward calls
Default value is 1.
For better accuracy, this feature
requires “dangerous” READ_PHONE_STATE permission.
(boolean)
Set to true to reject the
incoming calls if there is already a VoIP call in progress.
This feature might not
be enabled by default as it requires dangerous READ_PHONE_STATE permission.
Default value is false.
(String)
Specify a number where
calls should be forwarded when the user is already in a call. (Otherwise the
new call alert will be displayed for the user or a message will be sent on the API)
Default is empty.
(String)
Specify a number where
ALL calls should be forwarded.
Default is empty.
(String)
Specify a number where
ALL calls should be transferred.
This might be used if your softswitch
doesn’t support call forward (302 answers).
Default is empty.
(int)
Set to ignore all
incoming calls.
0=don’t ignore
1=silently ignore
2=reject
Default value is 0.
(boolean)
Set to true to
automatically accept all incoming calls (auto answer).
Default value is false.
Note: Autoanswer can be also forced from
the server by the “P-Auto-Answer: normal” SIP header.
(string)
Block incoming
communication from these users. (users/numbers separated by comma).
Default value is empty.
(int)
Set to ignore calls if
target doesn’t match
0=accept all incoming
calls
1=check if target user
match
2=check rinstance
3=check rinstance
strict
4=check all strict
Default value is 0.
(int)
Set to 1 to suppress
notifications (STATUS, CDR) from automatically handled calls (ignored,
forwarded, rejected and similar).
0=send status
notifications also about auto handled calls
1=do not send status
notifications from auto handled calls
Default is 0.
(int)
Maximum ring time
allowed in millisecond.
Default is 90000 (90 second)
(int)
Maximum speech time
allowed in millisecond.
Default is 10800000 (3
hours)
(int)
Automatically start the
sipstack after a specified time.
0=no (the sipstack will
be started on the first register or call event)
1=on startup if not
tunneling or serveraddress/username/password are set (the sipstack will be
started at app init)
2=on startup always
(the sipstack will be started at app init)
Other=seconds (the
sipstack will be started after the specified seconds)
Default value is 1
You can set to 0 if
there is less change that AJVoIP will be used once the users will open the
webpage hosting AJVoIP.
You can set to 1 or
higher if there is a high probability that the user will use AJVoIP to make
calls (this will shorten the setup time for the first call)
(int)
You can slow down or
speed up the SIP protocol timers with this setting. You may set it to 15 if you
have a slow server or slow network.
Default value is 10.
(int)
Same as “timer” but it
affects idle, connect and ring timeout and maximum call durations.
Default value is 10.
(int)
RTP timeout in seconds
to protect again dead sessions.
Calls will be
disconnected if no media packet is sent and received for this interval.
You might increase the
value if you expect long call hold or one way audio periods.
Set to 0 to disable
call cut off on no media.
Default value is 300 (5 minute)
(int)
RTP timeout in seconds
for API notify.
After this timeout a
warning message is sent via notifications without any further action.
The following log will
be generated: “WARNING,media timeout (notify)”
Default value is 0 (disabled)
(int)
RTP stream keep-alive
packet send interval in milliseconds.
This is useful if your PBX
has an RTP timeout setting to prevent disconnects when the java softphone is
hold or muted.
Default value is 0.
(You might set it to 25000 for example)
(boolean)
Send rtp even if muted
(zeroed packets)
Set to true only if
your SIP server is malfunctioning when no RTP is received.
Default value is false.
(int)
For call disconnect
compatibility improvements. Some VoIP devices might have bugs with CANCEL
forking, so it is better to always send a BYE after the CANCEL message on call
disconnect. In this case set the discmode parameter to 3.
1: quick
2: conform the RFC
3: send BYE after
CANCEL when needed
4: double: always
repeat the CANCEL and the BYE messages
Default value is 2.
(int)
Maximum time in
milliseconds to wait for unregistration when the Unregister is called or the
java sip stack is closed.
If set to 0 that an
unregister message is sent (REGISTER with Expires set to 0) but AJVoIP is not
waiting for the response, which means that it will not repeat the un-register
in case if the UDP packet was lost.
Default value is 2000.
(int)
Auto detect other SIP
endpoints on the same LAN (broadcast message) such as colleagues at the network
place or family members behind the home wifi.
When other user is
found, a NEWUSER event notification is triggered.
Possible values:
0: no (will disable
also the listener so other endpoints will not be able to detect it)
1: listen only (will be
discoverable)
2: yes find others
Default is 2.
(int)
Specify text
messaging mode (IM/chat/SMS/API)
-1: auto guess or
ask (default)
0: disable all
1: disable incoming
messages and auto guess outgoing mode
2: disable message
sending and auto guess incoming mode
3: reserved (you
might implement HTTP API based chat for this externally)
4: reserved (you
might implement native SMS for this externally)
5: VoIP SMS
6: VoIP IM/chat (SIP
MESSAGE)
Set the ims3gpp_sms
parameter to 1 or 2 to use 3GPP binary encoded messages for SIP MESSAGE or to 0
to always disable.
Note: the old haschat and chatsms
parameters are deprecated now but still supported
Will try to resend not
delivered messages later (on next register and/or when any message received
from peer). The offline message queuing will take care of filtering out
duplicates and will try to resend the message multiple times on failure until
max number of resend or timeout reached.
(int)
-1=auto (usually yes,
no for 3gpp sms)
0=no (disable offline
chat)
1=yes (default)
2=force always
Default is -1.
(boolean)
Specify if the
transport will be encrypted (both media and the signaling)
Compatible only with
Mizu VoIP servers.
Automatically turned on
when using http tunneling.
For standard encryption
you can use TLS/SRTP with the transport/mediaencryption parameters.
Default is false.
(int)
Some IP-PBX doesn’t
allow “web” or “proxy” authentication.
0=normal
1=only proxy auth
2=only simple auth
(int)
Specify if you will
supply encrypted passwords via parameters or via the Java API
0=no (default)
1=xor
2=des+base64
3=xor+base64 (this is
the preferred method; easiest but still secure enough)
4= base64
This method is
deprecated from version 3.4. All parameters can be passed encrypted now by just
prefixing them with the “encrypted__X__” string where X means the id of the
encryption method used.
From version 4.8 there
is no need to specify this parameter anymore. Just prefix any parameter with
encrypted_X as described here.
(int)
0=no (default)
1=local (in the user
home directory)
2=remote ftp or http
upload
3=both
(int)
The format of the
recorded filenames.
0=date-time + peer name
(default)
1=date-time + sip call-id
2=sip call-id
3=date-time + username
4=date-time + username
+ peer name
The date-time will be
formatted in the following way: yyyyMMddhhmmss
Note: You can also use the
“voicerecfilenameprefix” parameter to add a prefix for the file name.
(string)
FTP location for the
recorded voice files if the “voicerecording” parameter is set to 2 or 3.
Format: ftp://USER:PASS@HOST:PORT/PATH/TO/THEFILE
Example: ftp://user01:pass1234@ftp.foo.com/FILENAME
The FILENAME part of
the string will be replaced with the file name according to the “voicerecfilename”
parameter.
(int)
Recorded file
compression.
0: PCM wave stereo
files with separate channels for in/our (default)
1: raw gsm. 2 files
will be generated for each call. One for the recorder file and another for the
playback. These files can be played with players supporting gsm codecs for
example quicktime (which works also as a browser
plugin) or a winamp plugin is downloadable from here.
2: ogg/vorbis
(optional, on request; module might not be included by default)
(int)
The maximum recorded
file length.
-1: dynamic, no limit
1: max around 1 minute
2: max around 2 minute
…
Default is -1.
(int)
How to synchronize the
recording/playback side:
-1: Auto
0: No (don’t
synchronize)
1: Yes (fill with noise
the other channel)
2: Yes (wait for both
side)
Default: 2
(int)
Specify whether the
file upload should be retried on failure if the voicerecording parameter is set
to 2 or 3.
0: no
1: once
2: until success
Default: 1
(string)
FTP location for
general storage (for example for settings, contactlists)
Format: ftp://USER:PASS@HOST:PORT/PATH/TO/THEFILE
Example: ftp://user01:pass1234@ftp.foo.com/FILENAME
The FILENAME part of
the string will be replaced with the actual file name.
(string)
HTTP location for
general storage (for example for settings, contactlists)
Format: http://www.yourdomain.com/storage/
(this is just an example URL format. This
URL will not work. You need to change this to your own web address)
(int)
WebSocket server URL
for WebRTC video if any. Example: wss://rtc.myserver.com/sip
(int)
Configurations and
statistics are stored in a local file to be reused in next sessions.
This is not critical
and the Java VoIP client will work just fine if this file is lost or deleted by
the user.
Sometime is useful to
not allow configuration/settings storage on the user device.
The autocfgsave option
can be set to the following values:
·
-2: disable all
file write forced
·
-1: disable file
write
·
0: disable config
storage
·
1: save only
·
2: load only
·
3: save and load
Default is 3.
(boolean)
Set to true to clear
all previously stored or cached settings.
Default is false.
(int)
Specify local SIP
signaling port to use.
Default is 0 (a stable
port which is selected randomly at the first usage)
Note: this is not the port of your server
where the messages should be sent. This is the local port for sip user agent.
(int)
Specify local RTP port
base.
Default is 0 (which
means signalingport + 2)
Note: If not specified, then the Android
SIP SDK will choose signalingport + 2 which is then remembered at the first
successful call and reused next time (stable rtp port). If there are multiple
simultaneous calls then it will choose the next even number.
(int)
Increment RTP port for
each call by this value.
Might be needed only
with some misbehaving routers.
Default is 0.
Note: You will still have a different RTP
port for each simultaneous calls even if this is set to 0.
(String)
Specify local network
interface IP address for the sockets to bind to.
This parameter might be
used only on devices with multiple local IP addresses to force the specified
IP.
This parameter should
be used only with local private IP (an IP address which is present on the
device).
Default is empty (by
default it doesn’t bind to any IP and it is up to the OS routing table from
which IP the packets are sent)
Note: This parameter should be used only
in very specific circumstances when the device has multiple IP address and you
wish to use only one of them.
(String)
Specify local IP
address to be used for the SIP signaling.
This parameter might be
used only on devices with multiple ethernet interface to force the specified IP
or if JVoIP is behind NAT to specify its public IP.
This parameter should
be used only with static IP (if the device IP doesn’t change dynamically from
DHCP) or if you can better detect the best IP to be used in your app instead of
letting AJVoIP to auto detect it.
Default is empty
(auto-detect best interface to be used or detect the external IP)
Note:
AJVoIP by default will auto detect the
“best” IP to be used and this parameter should be used only in very specific
circumstances.
It is also possible to set the address
sent in SDP explicitly with the localsdpip and
localsdpport parameters.
(String)
Specify local subnet
preference.
For example if the
device where JVoIP is running might have two separate IP (such as 192.168.1.5
and 10.0.0.5) then you might set the favlocalip to 192 to always prefer the
192.x.x.x subnet.
This parameter might be
used only on devices running on a known environment (local LAN) in case if you
wish to suggest the subnet to be used.
Default is empty
(auto-detect best subnet to be used)
Note: AJVoIP by default will auto detect
the “best” IP to be used and this parameter should be used only in very
specific circumstances.
(boolean)
This will increase the
priority for the whole thread-group which might help on slow CPU’s or when
other applications are generating high CPU load.
Note: the priority of the threads
handling media are increased regardless of this setting.
Default is false.
(int)
Tracing level. Values
from 0 to 9.
You should set the
default loglevel to 1 for production and 5 for test or development.
Loglevel 0 is not
recommended as the Android SIP SDK will not even display important even
notifications for the user in this case.
Loglevel 5 means a full
log including SIP signaling.
Loglevel higher than 5
should be avoided (this can slow down the application).
The logs are sent to
the following outputs:
o
status display
(only level 1 –these are the most important events that should be displayed
also for the enduser)
o
file if the canlogtofile
parameter is set to 1 or 2
o
logcat if the
logtoconsole parameter is set to true
o
system log if the
systemout parameter is set to true (System.Out)
o
accessible for
the GetLogs() API
o
sent with
notifications if the events parameter is 3
More details here.
(int)
Whether to send tracing
to the java console (System.out.print or often referred as STDOUT).
Possible values:
o
0: no (disable
log to console)
o
1: auto
(depending on loglevel)
o
2: always (always
log to stdout)
Default is 1.
(boolean)
Whether to send logs to
standard output.
Default is false.
(boolean)
Whether to send logs to
standard Logcat.
Default is true.
(int)
Specify if AJVoIP
should write the logs to file.
Possible values:
o
0: never
o
1: if the
loglevel is higher then 2 and not headless
o
2: always
Default value is 1.
With loglevel set to 2 or more, the logs
are written also to a local file by default.
To disable the log files, set the
canlogtofile parameter to “0” (or set the “loglevel” to 1 and keep the
canlogtofile default at 1).
The logs are usually stored at
\mwphonedata\webphonelog.dat or you can specify the path with the logpath parameter. The exact path can be queried
with the GetLogPath API.
The log file is recreated with every
startup and the old log file is renamed to previous_webphonelog.dat (so you
will have max 2 log files: the current and the previous).
(boolean)
If set to true then
will send a capability request (OPTIONS) message to the SIP server on startup.
The serveraddress parameter must be set correctly for this to work. This method
is useful to release the security restrictions when using the Android SIP
library with the API and also to open the NAT devices.
Default value is false.
(boolean)
If set to true then
will send a short message (\r\n) to the SIP server on startup. The
serveraddress parameter must be set correctly for this to work. This method is
useful to release the security restrictions and also to open the NAT devices.
Deprecated since
v.3.8.2
Default value is false.
(int)
NAT keep-alive interval
in milliseconds which is usually sent from register endpoints.
Default value is 28000.
(28 seconds)
(int)
Number of buffers used
for audio recording.
Default is 7.
(int)
Audio recording mode. 0
means default; 1 means event based; 2 means device poll.
Default is 0.
(int)
Although the jitter
size is calculated dynamically, you can modify its behavior with this setting.
0=no jitter,1=extra
small,2=small,3=normal,4=big,5=extra big,6=max
Default is 3
(int)
Specify whether to
enable audio playback speedup on high queue size.
(Instead of dropping
packets, it might attempt to speed up the playback rate for a short time until
queue size drops below threshold)
Possible values: -1:
Auto Guess (default), 0: No, 1: Yes
(int)
Specify whether to
enable drop of RTP packets on media start.
Sometime the other end
might start sending RTP before the media is opened at AJVoIP side resulting in
accumulation of packets.
Dropping the first few
packets will make the playback of the rest more smooth, but might result in
some loss of audible media (usually up to 100 milliseconds)
Possible values: -1:
Auto Guess (default), 0: No, 1: Yes
(int)
You can limit the
jitter buffer size with this setting.
With the jittersize left as default (3)
the maximum buffered packet count is limited to 8, so you might set this
parameter to a lower value.
One packet means a received udp packet
which might contain one or more audio frame.
For example when using G.729 the typical
media stream are with 2 frames/packet. Each frame is 10 msec length.
A jitter limitation of 5 would mean
maximum 100 msec to be cached. (while the default setting would allow 8 packet
which means 160 msec)
Default value is 99 (no
limitation)
(boolean)
Set to true for encrypted communication (both media and signaling)
This has nothing to do
with standard SIP encryption and it works only with mizu server tunneling
module.
(int)
How to handle
incoming calls.
Possible values:
-1: auto
0: disable all
incoming calls
1: enable incoming
calls (while app is running; no background listener)
2: enable also
background calls (push or service implemented)
Default is -1.
(int)
This parameter is
deprecated and to be used only for the softphones.
Use the pushnotifications
parameter or the PushNotification API to enable/disable push
notifications.
Specify whether to
enable push notifications by default.
Possible values:
-1: auto
0: disabled
1: enabled auto
2: enabled direct to
SIP server
3: enabled via
gateway Default: -1
If set to 1, then
will try push with your server (as described in RFC 8599 so your server must
answer to REGISTER with Feature-Caps: *;+sip.pns="fcm") and if fails
then it will try via push gateway.
For more details see
the push notifications FAQ.
(int)
Enable push
notifications via as Google Firebase FCM.
Possible values:
-1=auto
0=disabled
1=enabled auto
2=enabled direct (with
your SIP server if it has push support)
3=enabled via gateway
Default is -1 which
means auto enable when required and possible. If FCM is available(if I have
json file configured) and background service is not 1 AND there was incoming
calls in the last 120 days or installed less then 120 days ago; otherwise it
means no.
We provides push
service (free tier) for all our customers enabled by default (via gateway if
your server doesn't support push notifications).
To configure push notifications, you
might use the PushNotification
API instead of these parameters.
For more details see the push
notifications FAQ.
(string)
Specify FCM gateway to
be used if a push gateway have to be used (instead of directly with SIP
server).
Default is: fcm.webvoipphone.com:35060
To configure push notifications, you
might use the PushNotification
API instead of these parameters.
For more details see the push
notifications FAQ.
(string)
Project ID. This is
your application package name, used for export and upload to google market to
be used also for push notifications.
Default is: empty or
loaded from your app context or com.mizuvoip.mizudroid.app with mizu gateways.
To configure push notifications, you
might use the PushNotification
API instead of these parameters.
For more details see the push
notifications FAQ.
(string)
Your app token (token
ID or Project ID returned by registering to the notification service) which can
be received from your OS push/apns/fcm API.
Default is empty
string.
To configure push notifications, you
might use the PushNotification
API instead of these parameters.
For more details see the push
notifications FAQ.
(int)
Specify what
protocol to use for push notifications
Possible values:
-1: auto (1 with mizu
servers, 2 with others or not sure)
1: mizu proprietary
X-MPUSH
2: standard RFC 8599
3: force RFC8599 even
with our servers or secondary
4: both
Default is -1
In case if you are
using a Mizu server, the AJVoIP can use the mizu proprietary protocol for push
binding: X-MPSUH: a:packagename:clientid.
Otherwise (with any
third-party SIP servers) you should use the Push Notification for SIP standard
as described in RFC 8599 which will send pn-* contact tags (Media
Feature Tags) like pn-provider=fcm;pn-param=PACKAGENAME;pn-prid=TOKEN
and will expect Feature-Caps: *;+sip.pns="fcm" in the answer).
For the details about SIP push
notifications see the “SIP signaling” chapter in the VoIP Push Notifications guide.
For more details see the push
notifications FAQ.
(int)
Set to 1 or 2 if your
app is running as a service (or you are running the sipstack from a service) to
enable some related optimizations.
This might be necessary
if your apps needs to be always available for incoming calls but for some
reason you don’t implement push notifications.
Possible values:
-1: auto
0: no
1: background service
2: foreground service
Default: -1
Note: background
services are heavily limited since API level 26 but AJVoIP implements all
possible workarounds to bypass this limitation. Foreground services are more
reliable since API level 26. Use a foreground if the always visible
notification is acceptable for your user-case.
More details can be
found here.
(int)
Enable scheduled wakeup
if running as a background service to help with background service limitations and doze/standby limitations.
Possible values:
0: Never
1: Yes if running as
service
2: Always force
Default: 1
More details can be
found here.
(String)
Used for scheduled
wakeup.
Set this to the name of
your android service class that will run in the background to be able to
receive incoming calls.
Default value: empty
Example:
SetParameter(“serviceclassname”,
“com.mycompany.appname.mainclass.myservice”);
(int)
Might ask the user to
white-list your app if running as a background service to help with background
service limitations and doze/standby limitations.
Possible values:
0: No
1: Yes if running as
service
2: Always force
Default: 1
More details can be
found here.
(int)
1: single line
2: unlimited
Default is: 2
(int)
Set cleanup speed and
wait times.
0: slow but will more
care about un-registration and cleanup
1: fast
2: very fast with no
unregister
Default is: 1
(int)
Defines the level of
notifications:
0=no
notifications,1=status and cdr,2=important events,3= all logs including SIP
signaling messages (depending also on loglevel).
Default is 2.
(int)
Set to a value in seconds if you wish to receive extended periodic statistics
for each line (STATUS notifications).
Default is 0 (no
periodic statistics)
1.
Have
a look at the description and pricing from the SIP library home
page
2.
Download
and try the demo from here. You might start
with the quick intro and then read
trough this documentation.
3.
Contact
Mizutech at info@mizu-voip.com with the following
details
-your VoIP server(s)
address (ip or domain name). This will be hardcoded in your release; otherwise
anybody could just download it from your and use as it owns)
-your company
details for the invoice (if you are representing a company)
4.
Mizutech
support will send your own AJVoIP build within one workday on your payment.
The payment can be made from the home page pricing grid with paypal
or credit card or by wire transfer.
All licenses include also a support plan in the cost.
The support is done mostly by email. For “gold license” we offer 24/7 phone emergency
support.
Maintenance upgrades are also free as included with your license plan.
Email to info@mizu-voip.com with any issue you
might have.
Guaranteed supports hours depend on the purchased license plan and are included
in the price.
Once your initial 1-4 years support period expires, it can be increased by 2
years for around $600 (This is optional. There is no need for any support plan
to operate your AJVoIP as the library is shipped with life-time license).
Note:
·
We can’t guarantee
that all the listed features will work correctly in your environment (your SIP
servers / integrated with your software). Please test the demo/trial version
before purchase to make sure that all the functionality critical to your
use-case works correctly.
·
Our support answer
time is usually up to one work-day for issues related to core functionality
(such as connect/register and voice calls). We are trying to resolve all such
issues as soon as possible. Issues affecting non-core features (such as call
hold or presence) might be handled only in the upcoming new releases.
·
Direct support is
provided for the common features (voice calls, chat, dtmf and others) and not
for extra features (such as presence or video). Direct support is not provided
for the issues described in the known limitations section. If you have some special
must-to-have requirement, we recommend to test with the demo version before purchasing your license. However we
appreciate all bug reports and we are constantly working on our software
shipping new features, improvements and bug fixes with each new release.
·
Mizutech doesn’t
provide direct server side support. Although AJVoIP is known to work well with
all common SIP servers (including Asterisk, FreeSWITCH and many others), your
servers have to be managed by you and we are not responsible for proper
configuration of your servers. However, in case if there is any incompatibility
issue then we might be able to help you with the resolution if you send us the
related logs.
You will receive the followings:
·
The
AJVoIP library itself. This is one single file usually named as “AJVoIP.jar” or
“AJVoIP.aar”
·
Latest
documentations
·
Usage
examples
·
Invoice
(on request or if you haven’t received it before or during payment)
·
Support
on your request according to the license plan
More details.
Yes, please contact
us at info@mizu-voip.com.
Note: Please
contact us only with AJVoIP related or VoIP specific projects. We are highly
specialized for VoIP development thus we will not accept general app
development projects which can be done by any developer or team (We don’t
handle tasks such as building user interface or design elements).
Yes. The VoIP SKD uses the SIP protocol standard to communicate with
VoIP servers and sofswitches. Since most of the VoIP servers are based on the
SIP protocol today, AJVoIP should work without any issue. AJVoIP have been
tested with numerous other SIP stack (software/hardware) and we invest extra
effort to achieve maximum compatibility even with misbehaving SIP
implementations.
If you have any incompatibility problem, please contact info@mizu-voip.com with a problem description and a detailed
log (loglevel set to 5). For more tests please send us your VoIP server address
with 3 test accounts.
Short answer: “better
than Skype”
Long answer:
The library is
capable for perfect voice quality if that is possible in your environment
(server/peer codec support, network link quality, etc). Otherwise it aims to
produce the best possible call quality achievable depending on the
circumstances.
AJVoIP includes
wide-band OPUS and Speex codec
which are capable to offer a perfect call quality (MOS score of 6).
Of course, these
have to be supported also by the peer to be used. PSTN networks usually has
support only for narrowband codec (such as G.729, GSM, iLBC or G.711), so the
call quality will be lower here (but still better than traditional phones if
the user connection fulfills the minimal bandwidth and quality required for
VoIP).
The media stack
implements best practices for network and audio device handling to minimize the
total delay.
A wide range of
audio enhancement algorithms are also implemented such as AEC, denoise, PLC and
AGC.
AJVoIP is also
capable to auto-fine-tune itself to the circumstances by default (based on device
capabilities, CPU speed, network bandwidth/quality, peer/server capabilities),
but you can also force any settings with the parameters (such as codec,
framesize, aec, etc).
The Android SIP SDK
will connect to your voip server directly. No any intermediary app server is
involved.
AJVoIP will not “call to home” and will not send any sensitive information to
Mizutech servers.
AJVoIP might contact Mizutech servers for the following reasons:
·
demo
versions might contact Mizutech licensing servers time to time. This is
completely removed in final builds (after your order)
·
AJVoIP
will use a random stun server by default hosted by Mizutech. This “fast stun”
protocol is usually not required for normal functionality so you might just disable
it (set the “use_fast_stun” parameter to 0) or set the “stunserver” parameter
to your stun server. (However these can improve the connectivity if your VoIP
server is not NAT friendly so better to leave it as is. Mizu services (non)
availability can’t alter the usability of your product)
·
Push
Notifications: if you don’t implement your own push notification service then
AJVoIP might use the Mizu push notification gateway which we offer for all our
customers (free tier). This can be disabled or replaced with your own
implementation.
The Android VoIP SDK is a close-source application. The source code is
available only for internal usage at an additional higher cost.
SIP registration
means connecting to your SIP server and authenticating. From this procedure
your SIP server will learn your application address and can route incoming
calls to your application (or other sessions, such as chat, presence,
voicemail, etc).
The SIP stack
auto-start behavior can be altered with the startsipstack setting or you can use
the Start function to launch the instance
explicitly.
When started, the
SIP stack by default (unless you set the register parameter to 0)
will automatically register to your SIP server if you configured the SIP account details (serveraddress, username, password and any
other parameters that might be required such as the proxyaddress and
sipusername).
Otherwise you might
disable auto-start (startsipstack) and/or the auto
register (register), pass the above parameters dynamically from your
code and use the Start and/or the Register function to initiate the start/connect/register
procedure.
Registration success
of failure can be obtained from the REGISTER notifications (especially useful
if you are using multiple accounts as this
notifications are sent separately per account.
The registration
success or failure can be obtained from the STATUS notifications.
o Proceeding
notification strings:
§ Register…
§ Registering… (or “Register...”)
§ Register Failed
o Success notification
strings:
§ Registered
§ Registered.
o
Failure
notification strings:
§ Connection lost
§ No network
§ Server address
unreachable
§ No response from
server
§ Server lost
§ Authentication
failed
§ Rejected by server
§ Register rejected
§ Register expired
§ Register failed
The registered state
can be requested with the IsRegistered or IsRegisteredEx API.
The failure reason can
be also obtained (instead of the above STATUS strings) by using the GetRegFailReason API.
Check this
FAQ point if you are
having problems with connect/register.
Multiple account registration
The VoIP SDK is capable
to register multiple accounts at the same time. This can be useful to be able
to make and receive calls from multiple accounts or multiple servers.
You can configure
multiple accounts using the extraregisteraccounts parameter or the RegisterEx function passing a string with the accounts
fields. Fields are to be separated by comma and multiple accounts separated by
semicolon.
The
following fields can be passed:
serveraddress,
username, password, registerinterval,
proxyaddress, realm, authusername
Most of
these fields are optional. The mandatory parameters are the username, password
(and the serveraddress if that it is different from your main SIP server).
The SIP accounts can be
configured by parameters in the following way:
serveraddress,
username, password, registerinterval:
primary account
serveraddress2,
username2, password2, registerinterval2:
second account
serveraddress3,
username3, password3, registerinterval3:
third account
…
serveraddressN,
usernameN, password, registerintervalN: N
account
Or via the RegisterEx(String accounts) API call where the
accounts are passed as string in the following format:
server,usr,pwd,…;server2,usr2,pwd2, …;
(accounts
separated by ; and parameters separated by , )
Example:
mysipclient.RegisterEx("myserver2.com,user2,pwd2;myserver2.com,user3,pwd3,120,,,sipusername3");
Or via the “extraregisteraccounts” parameter which have to be
set like this:
server,usr,pwd,…;server2,usr2,pwd2…;
Example: mysipclient.SetParameter("extraregisteraccounts","myserver2.com,user2,pwd2;myserver2.com,user3,pwd3,120,,,sipusername3");
Notes:
-Up to 99 secondary
accounts can be used this way
-The ival/registerinterval
parameter is optional (default is 3600 which means one hour)
-All other parameters
are applied globally for all account (there is no per account profile). The
“proxyaddress”, if set, will be applied for primary account only
-You can use the
REGISTER notifications to find out the register state of the separate accounts
-STATUS about
registrations are not reported from secondary accounts (but you will receive
call state STATUS notification while in call as normally)
-If you need easier control
for the separate accounts then you can also just launch AJVoIP multiple times
(multiple instances) with different parameters
(Multiple instances per account requires a bit more system resources –some
more RAM for each instance- but it might be more convenient for you)
·
Make sure that
the “serveraddress” parameter is set correctly (otherwise you will be able to
make calls only to direct SIP URI).
·
Optionally:
Register to the server. This can be done automatically if the “username” and
“password” parameters are preset. Alternatively you can register from API
(Register) or just let the user to fill in the username/password fields and
click on the “Connect” button. If AJVoIP is registered, then it can already
accept incoming calls (it will do it automatically, or you can handle incoming
calls from your application, or you can entirely disable incoming calls)
·
Now you can make
outgoing calls in the following ways:
o
Automatically
with AJVoIP start. For this you will have to preset the username, password, autocall
and callto parameter. Then AJVoIP will immediately launch the outgoing call
when starts (usually with your page load)
o
Just let the
users to enter a called number and hit the “Call” button
o
or just call the Call
function (from user button click or from your business logic)
Optionally on call you
might set the following flags (for example if you have a separate call page
activity, then you might set these from onCreate):
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if(Build.VERSION.SDK_INT
>= 24) getWindow().setSustainedPerformanceMode(true);
Check this
FAQ point if you are
having problems initiating calls.
To be able to receive
incoming calls, make sure that you are registered to your SIP server first. Then you
can easily test for example by using any third party softphone and make calls to your android SIP
username (or extension id or full URI, as required by your server).
In your project all you
have to do is to watch for incoming ringing STATUS notifications and from there you can show any user
interface (activity) as you wish.
If you follow the example
code, you receive
the notifications in the public void ProcessNotifications(String msg) function.
You can find the
possible strings that can be received at the “Notifications” chapter in the documentation.
To catch incoming
calls, you have to look (string parse) for STATUS messages with “Ringing” text (second
parameter is the state text) and the endpointtype (forth
parameter) set to 2 (means incoming).
For example the
following status means that there is an incoming call ringing from 2222 on the
first line:
STATUS,1,Ringing,2222,1111,2,Katie,[callid]
AJVoIP is capable for
automatic line management so if you don’t wish to handle lines explicitly in some specific way, then you can
ignore all notifications, except those where the line (first parameter) is -1 (the global state).
If you wish to auto
accept all incoming calls, you can set the autoaccept parameter to true. Otherwise use the
Accept API to connect the call (or the Reject API to disconnect). Check the parameters to find out more call divert
settings, such as auto-answer or forward if needed.
Check this
FAQ point if you are
having problems receiving incoming calls.
Check the followings in
case if you are unable to build your project because dependency issues.
For example you might
receive an error something like this:
Unable to resolve
dependency for ':app@debug/compileClasspath': Failed to transform file
'AJVoIP.aar' to match attributes {artifactType=android-exploded-aar} using
transform ExtractAarTransform
This has less to do
with our aar and it is a gradle bug.
Possible solutions:
1.
Clean project
Rebuild
project
2.
https://github.com/golang/go/issues/23307
3.
https://stackoverflow.com/questions/45138391/failed-to-transform-file-45907c80e09917e1b776adf038505958-to-match-attributes
4.
Make sure your machine is connected to the internet.
Go
to File -> Settings & expand Build, Execution, Deployment -> Gradle
-> UNCHECK Offline work -> OK
Go to File
-> click on Invalidate Caches / Restart -> Invalidate & Restart
5.
Upgrade android studio and tools to latest version
6.
Just create a new project and add our aar to it and the code from
MainActivity.java.
First of all you should check the logs (logcat) to see any ERROR and the SIP
signaling.
For outgoing call you should see an INVITE sent to server (or peer) and a 2xx
response (usually 200 OK) on call connect or other response (4xx, 5xx, 6xxx) on
call failure. Some server requires previous successful registration (REGISTER)
to allow calls.
Some servers has problems with codec negotiation (requiring re-invite
which is not support by some devices). In these situations you might enable
only one codec which is supported by your server by setting the codec parameter
(for example codec: PCMU).
AJVoIP by default doesn’t allow cross-domain calls. For example if you
are registered as a@A.com (to A domain) then you will not be
able to make direct calls to b@B.com (to B domain).
Contact mizutech support if you need this use-case to remove the limitation.
Can’t connect to SIP server
If the
SDK cannot connect or cannot register to your SIP server, you should verify the
followings:
·
You have set your
SIP server address:port correctly
·
Make sure that
you are using a SIP username/password valid on your SIP server
·
Make sure that
the autostart parameter is true and the register parameter is 1 or 2. Otherwise use the Start() and/or Register()
functions explicitly.
·
Make a test from
a regular SIP client such as mizu softphone or x-lite from the same device (if these also doesn’t work, then there is some
fundamental problem on your server not related to our library or your device
firewall or network connection is too restrictive)
·
Check if some
firewall, NAT or router blocks your device or process or the SIP signaling
·
Check the logs
·
If there are no
any answer for the REGISTER requests, turn on your server logs and look for the
followings:
o The REGISTER reaches your server?
o Is there any response triggered (or
some error)?
o If answer is triggered, is it sent to
the correct address? (it should be sent to the exact same address from where
the server received the REGISTER request)
o The answer packet reach the client PC?
You can use Wireshark to see the packets at network level.
·
Send us a detailed client side log if still
doesn’t work with loglevel set to 5 (from the browser console or from softphone
skin help menu)
If the calls are disconnecting after a few second, then try to set the
“invrecordroute” parameter to “true” and the “setfinalcodec” to 0.
If the calls are disconnecting at around 100 second, then most probably you are
using the demo version which has a 100 second call limit.
See the CDR and the log about the details.
Ask for RECORD_AUDIO permission from your app before to make calls.
·
No
technical support for Bluetooth related functionality (we provide it “as is”
since incompatibility issues might occur due to the high device fragmentation)
·
The
video module is provided “as-is” with no specific support. Find more details here.
·
AEC
is a best effort algorithm and it might not work (or it might work only
partially) in some circumstances. There is no any quick fix for underperforming
AEC
·
The
full STUN specification is not implemented due to size and performance
considerations (a fast and light STUN version is used when needed which always
outperforms the standard STUN implementations with no drawbacks)
Please test with the
demo version first
before to purchase a license, to make sure that it fulfills your requirements
and it works correctly in your environment.
Media statistics
means RTP/RTCP level details, which can be used to analyze call quality or to
display a call quality indicator.
·
Basic
details: are received with the STATUS notifications such as total rtpsent,
rtprec,rtploss, rtplosspercet and server statistics if reported. These and
more is also received with the RTP LOG notification.
·
Quality
reports: can be sent as RTPSTAT notifications if enabled
by the rtpstat parameter.
Alternatively it can
be requested with the RTPStat function call.
·
Logs:
You can also see more details in the logs such as total rtp statistics reports
for calls longer then 7 seconds if the loglevel is at least 3 as EVENT, rtp stat: sent X rec X loss X X% or the RTP notification. If you set the “loglevel” parameter to at least “5” than
the important rtp and media related events are also stored in the logs. You
might search for “call details” at the log which also includes media related
reports after each call.
AJVoIP has built-in
VAD (voice activity detection) algorithm included.
The talking/silence
state of both the local user and the remote peer can be reported.
To enable VAD
reports, set the vad parameter to 4.
Once this is set,
you can receive the VAD state either by calling the VAD function or by the VAD notifications if the vadstat
parameter is set to 3 or 4.
For the
notifications interval you might also adjust the vadstat_ival parameter after
your needs (default is 3000 in milliseconds, which means a VAD report in every
3 seconds).
If the vadstat is
set to 4 then it will report the state also when changed from silence to
speaking or inverse.
In the SIP
protocol the client endpoints have to send their (correct) address in the SIP
signaling, however in many situations the client is not able to detect it’s
correct public IP (or even the correct private local IP). This is a common
problem in the SIP protocol which occurs with clients behind NAT devices
(behind routers). The clients have to set its IP address in the following SIP
headers: contact, via, SDP connect (used for RTP media). A well written VoIP
server should be able to easily handle this situation, but a lot of widely used
VoIP server fails in correct NAT detection. RTP routing or offload should be
also determined based in this factor (servers should be always route the media
between 2 nat-ed endpoint and when at least one endpoint is on public IP than
the server should offload the media routing). This is just a short description.
The actual implementation might be more complicated.
You may have to change Java VoIP toolkit configuration according to
your SIP server if you have any problems with devices behind NAT (router,
firewall).
If your server has NAT support then set the use_fast_stun and use_rport
parameters to 0 and you should not have any problem with the signaling and
media for AJVoIP behind NAT. If your server doesn’t have NAT support then you
should set these settings to 2. In this case AJVoIP will always try to discover
its external network address.
Example configurations:
If your server can work only with public IP sent in the signaling:
-use_rport 2 or 3
-use_fast_stun: 1 or 2 or 4 (recommended is 2)
If your server can work fine with private IP’s in signaling (but not when a
wrong public IP is sent in signaling):
-use_rport 9
-use_ fast_stun: 0
-optionally you can also set the “udpconnect” parameter to 1
Asterisk is well known about its bad default NAT handling. Instead of detecting
the client capabilities automatically it relies on pre-configurations. You
should set the "nat" option to "yes" for all peers.
More details:
http://www.voip-info.org/wiki/view/NAT+and+VOIP
http://www.voip-info.org/wiki/view/Asterisk+sip+nat
http://www.asteriskguru.com/tutorials/sip_nat_oneway_or_no_audio_asterisk.html
For
FreeSWITCH you might set the "NDLB-force-rport" and "aggressive-nat-detection"
values to "true" in the sip_profiles configuration.
More details here.
Use the following settings if you have 2 voip servers:
·
serveraddressfirst:
the IP or domain name of the first server to try
·
serveraddress:
the IP or domain name of the next server
·
autotransportdetect:
true
·
enablefallback:
true
In this way java voip framework will always send a register to the
first server first and on no answer will use the second server (the “first”
server is the “serveraddressfirst” at the beginning, but it can change to “serveraddress”
on subsequent failures to speed up the initialization time)
Alternatively you can also use SRV records to implement failover or
load balancing.
It is normal to get cropping audio with debug builds running from the
IDE on your phone and especially on emulator. Call quality during test sessions
can be improved by lowering the log level, disabling AEC and denoise and
forcing a low complexity codec such as PCMU. If you wish to focus on call
quality tests then you should build a release version and run it normally on
your phone, not from your development environment such as the Android Studio
IDE.
Call quality is influenced primarily by the followings:
·
Codec
used to carry the media (PCMU, PCMA requires the less CPU but more bandwidth;
G.729 and OPUS wideband requires more CPU but it is more optimized for
bandwidth). The best possible call quality can be achieved with OPUS wideband
if you are using a release build
·
Network
conditions (check also your upload packet loss/delay/jitter)
·
Hardware:
enough CPU power and quality microphone/speaker (try a headset, try on another
device)
·
AEC
and denoise algorithms increases the CPU load especially under debug
·
Missing
(disabled) AEC and denoise might result in suboptimal call quality
·
Log
details: high loglevel might decrease the sound quality. You should set the
loglevel to 5 or lower
·
Debugging:
release versions have better quality due to optimizations
If you have call quality issues then the followings should be verified:
·
whether
you have good call quality using a third party softphone from the same location
(try X-Lite for example). If not, than the problem should be with your server,
termination gateway or bandwidth issues.
·
make
sure that the CPU load is not near 100% when you are doing the tests
·
watch
for RTP statistics
·
make
sure that you have enough bandwidth/QoS for the codec that you are using
·
change
the codec (disable/enabled codec’s with the codec/prefcodec or the use_xxx parameters)
·
run
your app on a real device (your phone) and not on the simulator
·
force
a low complexity codec such as PCMU for your debug builds and test sessions
·
check
the AJVoIP logs (check audio and RTP related log entries with loglevel 5)
·
set
the loglevel to 1 (or up to 5)
·
wireshark
log (check missing or duplicated packets)
The SDK by default
comes with optimal default value but in some circumstances you might need to
further optimize for performance.
If you are running
the SDK on some ancient device or any device with low-end CPU or lower-powered
devices, you can optimize the performance with the following settings:
·
Make
sure that no other processes on your device are running with abnormally high
CPU usage (remove or optimize other processes that are unnecessarily consuming
the CPU)
·
Prioritize
low computational codecs with the following settings:
use_pcmu=3
use_pcma=2 use_g729=1 use_gsm=2 use_speex=1 use_speexwb=1 use_speexuwb=0
use_opus=1 use_opuswb=1 use_opusuwb=0 use_opusswb=0 use_ilbc=1
·
Set
the loglevel to 1 (High log levels will slow down the SDK. But don’t set it to
0)
·
Set
the following parameters to 0 to lower the number of threads (especially if
there are only 1 or 2 CPU cores available for AJVoIP):
audiorecthread, audioplaythread, audioplaythread2
·
Disable
extra audio processing by setting the followings to 0: aec, aec2, denoise, agc,
silencesupress
(In case if you
don’t wish to completely disable AEC, then just fine-tune the aec, aec2 and
aectype settings. Avoid full software aec.)
·
Increase
the audioqueuemaxsize value. Default is 40. Increasing it can help with short
CPU spikes and packet bursts but might increase the playback delay
·
Additional
optimizations:
o codecframecount: 2 (or
even 4; might be incompatible with some bogus servers)
o voicerecording: 0
o syncvoicerec: 0
o vad: 1
o plc: false
o rtcp: false
o aectype: none
o enablepresence: 0
o registerinterval:
300
o keepaliveival: 50
o timer: 20 (not
recommended)
o timer2: 20 (not
recommended)
o Set the cpuspeed
parameter to 700 or less (or some other value between 300 and 2000)
·
In
case if you are using the SDK for some special purpose with on way audio then
you should to set the useaudiodevicerecord or useaudiodeviceplayback parameters
to false. In this case you might also set the mediatimeout parameter to 0.
It might be possible
that one or two of the above already fixes any performance problems on your
devices. In that case it is not necessary to change all of these settings.
1. Review your server NAT related settings (set nat=yes in Asterisk
config if you are using Asterisk based solution)
2. Set the “setfinalcodec” AJVoIP parameter to 0 (especially if you are using
Asterisk or OpenSIPS)
3. Set use_fast_stun, use_fast_ice and use_rport to 0 (especially if you are
using SIP aware routers). If these don’t help, set them to 2.
4. If you are using MizuVoIP server, set the RTP routing to “always” for the
user(s)
5. Make sure that you have enabled all codec’s
6. Make a test call with only one codec enabled (this will solve codec negotiation
issues if any)
7. If you still have one way audio, please make a test with any other softphone
from the same PC. If that works, then contact our support with a detailed log
(set the” loglevel” parameter to 5 for this)
Depending on your softswitch configuration, you might not have ringback
tone or early media on call connect.
There are few parameters that can be used in this situation:
·
set
the “changesptoring” parameter to 3
·
set
the “natopenpackets” parameter to 10
·
set
the “earlymedia” parameter to 3
·
change
the use_fast_stun parameter (try with 0 or 2 or 4)
·
set
the “nostopring” parameter to 1
·
set
the “ringincall” parameter to 2
One of these should solve the problem.
The remote party hear itself back
(echo)
About
Echo suppression and
cancellation are special voice processing algorithms to prevent the audio
played on the speaker to be recorded and sent back to the other party resulting
in echo.
The perceived echo
depends on many factors:
·
The
AEC algorithms used by AJVoIP and on the other end
·
Network
delay
·
Device
hardware capabilities (on both the AJVoIP side and the other side)
·
Speaker
device
·
OS
audio processing and audio driver
·
Room
characteristics
Please note that
when you hear echo with AJVoIP, the culprit is usually the other end as there
is nothing to solve the echo problem if it is already present in the incoming
stream. The solution in this case is to use AEC capable devices also for the
peers.
AEC is important
only if a speaker/loudspeaker/speakerphone
is used. If the user will make a normal call with off-speaker or using a
headset than echo is generated only if the internal speaker or the headset is
broken.
Also it is possible
that some software is capable to suppress echo under specific circumstances and
other software might fail in the same circumstances but might have better
success in other circumstances.
Success rate
Please note that
echo cancellation is not an exact science and there is no perfect algorithms
for 100% echo cancellation.
AJVoIP includes five different AEC/AES algorithms:
·
software: two
separate software based AEC algorithm (requires extra CPU processing)
·
hardware: android
hardware aec capabilities (not supported on all phones)
·
fast: a fast
software aec implementation (used preferably on slow/old devices or in addition
for the above algorithms)
·
volume: this will
decrease the volume when speech detected from other end (using VAD)
After our tests with
numerous hardware the AJVoIP media stack is capable to eliminate more than 90%
of the echo with around 92% success rate.
Settings
Echo cancellation in
AJVoIP is usually turned on by default when necessary (depending on the
playback device used and might be disabled by default on devices with very slow
CPU such as ancient or low-budget phones).
You might adjust the
following settings to fine-tune the AJVoIP side AEC if there is echo generated
by AJVoIP in your environment:
·
Set
the aec parameter to 2.
·
Set
aectype parameter after your needs. For example you might set
it to software,hardware,fast,volume to apply
all suppression algorithms
·
For
better quality you can also set the denoise parameter to 1.
To completely disable AEC,
set the aec parameter to 0 and the aectype to
none. This might be used to save CPU time in
circumstances when no echo is possible such as have only one way audio (like IVR
calls) or there is no loudspeaker usage.
Support
We can’t provide
technical support for AEC related issues, because AEC is known to not work
(partially or at all) in some circumstances and there is no any quick fix for
these issues except the above mentioned settings.
AJVoIP based apps
can be converted also to ChromeOS and run on any compatible device such as Chromebooks.
For this a conversion is needed to ARC (App Runtime for Chrome).
You can convert the
Android apk using any tool, for example as described here.
More details can be
found here.
Video requires RTC
capabilities (handled automatically by AJVoIP or you can set your own webrtcserveraddress).
Details:
VoIP Video streaming is
a moving target. In the past we had H.263, nowadays H.264 and VP8 but soon the
industry will move to H.265, AV1 and VP9.
To avoid constant
rewrite and optimizations to the latest preferred standards we decided to take
full advantage of the WebRTC capabilities already found on all platforms.
AJVoIP uses the WebRTC module offered by the Android browser via a WebView,
thus always up to date but requiring RTC capabilities for SIP compatibility.
This is handled with the default settings or you can use the webrtcserveraddress parameter if you wish to specify
your own WebRTC server endpoint (websocket listener). A simple way to test
video functionality is to make a WebRTC call from Chrome to check if it works
as expected or at least test your Chrome browser WebRTC
capabilities.
Video re-INVITE is not currently
supported (usage with SIP devices which are capable to initiate or accept the
video from start as upgrading a voice call to video will not work). RTC uses
the latest standards for video negotiation and byte stream format thus might
not be compatible with all SIP devices as it enforces a strict video codec
negotiation that might not be supported by the peer device.
If video is your main
use-case we recommend testing it first in your environment before to purchase
to make sure that it works with your server/ devices. (You can make a quick
test with the MizuDroid softphone downloadable from the Google Play as that is
based on this AJVoIP library).
We provide the video
module as-is with no specific support as we rely on the platform RTC
capabilities here with the limitations mentioned above, but you can assume that
android will always ship with the latest video tech which should provide
optimal performance and compatibility with the latest devices.
Required permission: CAMERA
Codec support: depends
on the RTC stack. Usually H264, VP8 and VP9.
Video related
parameters: video, vcodec, video_bandwidth, video size
parameters, webrtcserveraddress
Video related API’s: VideoCall, AcceptVideo, RemoveVideo, SetVideoDisplaySize,
IsIncomingVideo
How to close a video call
Once a
video call is terminated, you will also need to remove or hide your video
display user interface element. You can follow this sequence:
1.
hangup
the call by calling hangup() function (and/or catch the disconnected state of
the call from the STATUS notications)
2.
optional:
wait 2 seconds if you need a CDR record about the video call
3.
remove/unload
webphone fragment from FrameLayout (resource ID of FrameLayout received in VideoCall)
Note: you might use RemoveVideo function to remove the video display, but the
better way is to just hide/destroy your container.
Example code:
//disconnect the call
sipstackinstance.Hangup();
//if you
need CDR, then execute the below code a bit later from a 2 second timer
//
remove/destroy webphone fragment
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.remove(finstance.getSupportFragmentManager().findFragmentById(fragmentResId)).commit();
Make sure that your softswitch has support for IM and it is enabled. The Java
SIP client is using the MESSAGE protocol for this from the SIP SIMPLE protocol
suite as described in RFC 3428.
Most Asterisk
installations might not have support for this by default. You might use Kamailio for this purpose or any other softswitch (most of them has support for RFC
3428).
AJVoIP doesn’t receive incoming calls
To be able to receive calls, AJVoIP must be registered to your server.
Once the SIP client is registered, the server should be able to send incoming
calls to it.
The other reason can be
if your server doesn’t handle NAT properly: Please try to start AJVoIP with use_fast_stun
parameter set to 0 and if still not works then try it with 2.
If you wish to be able
to always accept incoming calls (even when the user is not actively using the
app), then implement all-time availability as discussed below.
To be able to accept calls, IM and other notifications, the server needs to be
capable to deliver the SIP signaling messages to your application.
Normally your
application is “connected” to your SIP server with an active UDP or TCP register
session thus the SIP server is capable to send call connect, IM and other
messages via these streams.
New Android OS versions
heavily restricts apps running in the background and usual applications will
just stop running when not in foreground or actively used by the user.
To be able to receive
incoming call while your app is in background, closed, standby or the device is
in doze or sleeping state, you have two options:
·
Run as a service
·
Enable voip push notifications
One way to implement
all-time availability (beside using push notifications) is to continuously run
the sip stack, keeping your register session alive, always connected to your
SIP server using UDP (with keep-alive to bypass NAT’s) or a TCP connection.
This is necessary because to be able to always accept incoming calls or text message
(even when the app is not opened) your SIP server needs to be capable to
deliver the INVITE/MESSAGE/other SIP messages to your application.
This should be used
only if you don’t wish to enable push notification for some reason or push
notifications can’t be used for your use-case for some reason.
This can be achieved by
running the SIP stack from a service.
You need to have an
android service running in the background and on an incoming call you can start
your activity from that service using the below code:
Intent intent = new
Intent(this, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Running the app (or
just the SIP stack) as service is a convenient mode to achieve availability and
AJVoIP implements all best practices for battery optimizations thus requiring
minimal CPU and energy while running in idle (slow down timers, auto-lowering the
prioritiy of it’s threads and other
optimizations).
To be able to keep the
register session alive the app needs to fulfill the followings conditions:
·
actually running
(not killed/closed or put in a dose or sleep state)
·
capable to
acquire wake lock
·
capable to
acquire wifi lock (if there is no mobile data or the user prefers Wi-Fi)
Background services are
severely restricted in latest Android versions and apps
are also affected by Doze and Standby limitations.
There are workarounds and good practices supported by AJVoIP and additional
techniques that you might implement as described below.
The followings should
implemented the followings in your app:
·
Set the runservice AJVoIP parameter to 1 or 2
·
Set the serviceclassname AJVoIP parameter to your service
class name
·
Run the service
with START_STICKY and start the SIP stack from the service
The followings might
be implemented/handled by your app:
·
A simple what to
circumvent the background service limitations since API level 26 dosing or sleep
is to just run a foreground service (instead of a background service).
This is a more reliable way to make it always available but a non-removable
notification will be displayed while the app is running.
·
You might also start your app service at boot (requires the RECEIVE_BOOT_COMPLETED
permission. Since API level 26 only foreground services can be automatically
started. More details: 1,2,3)
·
From API level 26
(Android Oreo) the OS prevents the use of startService() method to start the
service from background. If you call startService() from background on Android O, you
will get an IllegalArgumentException. In this case you might just catch the
exception and start a foreground service instead using the startForegroundService() API.
·
From API level 29
(Q) you should only use a foreground service (background services are not
allowed to run continuously for networking/audio as it would be required for
VoIP)
·
Optionally you
might implement a tricky technique to always restart your service if
killed by the OS (just make sure to not restart if the user explicitly
unregistered and stopped your application)
·
Optionally check
for isBackgroundRestricted and ask the user to release the restrictions
The followings are
implemented/handled by AJVoIP:
·
Acquire wake lock
/ wifi lock: by default this is handled by the AJVoIP itself with no further
actions required from your side. It can be finetuned with the forcewifi,
cpupartiallock and cpualwayspartiallock settings if for some reason the default
behavior is not suitable for your use-case
·
The SIP stack is
also capable to auto wake-up by using the Android alarm manager capabilities. This will also help in
some circumstances, but this kind of alarms are limited usually to a 10 minute
intervals. You can enabled/disable this with the scheduledwakeup parameter.
·
Ignore batter
optimizations: latest Android versions might automatically enforce Doze or
Standby. Whitelisting your application can be asked with the
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS which can be done from your code or
just set the askforwhitelist parameter to 1.
Note: this is a dangerous permission
and google might remove your app from the Google Play if used for no valid
reason as described at the end of this page.
In case if you wish to do this from
your own app for some reason, set the askforwhitelist to 0 and use this
copy-paste code:
PowerManager pmanager =
(PowerManager) getSystemService(Context.POWER_SERVICE);
if
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if (!pmanager.isIgnoringBatteryOptimizations(getPackageName()))
{
//Ask the user to
disable battery optimization
Intent intent = new
Intent();
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
startActivity(intent);
}
}
To summarize, there are
the following ways to achieve always availability:
·
Enable push
notifications: Recommended method to enable always availability (discussed
below). If enabled, then there is no need to run any service.
·
Using a
foreground service: This is a simple and reliable method with the drawback of a
non-removable notification displayed on the device home screen
·
Using a
background service: A bit more tricky and workarounds required as describe
above, but fully supported by AJVoIP
·
Optional tricks
such as auto restart and asking the user to reconfigure their phone settings to
allow your app to run in the background
·
Not using any
service: You can just enable push notification support (discussed below), thus
your app doesn’t have to be run continuously (zero battery utilization)
VoIP Push
notification is an effective solution to wake up/launch your closed or sleeping
application on incoming SIP call or text message without the need to run your
application in the background and to keep a persistent connection (or frequent
UDP keep-alive or re-register) with the SIP server/proxy.
The SIP library has
full support for push notifications which can be negotiated directly with your
server (if your server has push support) or via gateway (if your server doesn’t support push RFC 8599)
There are two ways
to enable/disable/configure push notifications.
·
Using
the API: call the PushNotification function
(recommended)
·
Using
parameters: configure the pushnotifications / fcmgateway / packagename / fcmclientid parameters.
Push notifications
can use the mizu proprietary protocol (with mizu servers/gateways using the
X-MPUSH header) or the Push Notification for SIP standard described in RFC 8599. This protocol to use is selected
automatically by default or you can set it explicitly with the pushtype parameter or by the first parameter of the PushNotification
function.
Push notifications
works in the following ways:
1.
Create
a Firebase project for you app and
download the google-services.json file to your project
2.
Configure
Firebase for your app and obtain an FCM token ID as described here
3.
Configure
AJVoIP with the PushNotification function (or with
the related parameters)
4.
AJVoIP
will send your app package name and token ID with the REGISTER requests to your
SIP server (or to the push gateway if your server don’t have push notification
support)
5.
On
incoming calls/chat your server/gateway will send a push notification first to
wake-up your app and then your app will be able to process the incoming
INVITE/MESSAGE/etc as normally.
All these steps are
explained at the “AJVoIP”chapter in the VoIP Push
Notifications guide.
Push notifications
with your SIP server
Push Notification
for SIP is described in RFC 8599.
If your server has
push notification support then AJVoIP will send all the required details (Project
ID, Registration token) with the SIP signaling (pn-* media feature tags in
Contact) and your server must send a push notification to AJVoIP (via FCM) to
wake up the app before incoming calls and it can also send IM chat messages as
push notifications (along the usual SIP MESSAGE).
For more details see
the instructions
at the “AJVoIP”chapter from the VoIP Push
Notifications guide (except the Mizu server/gateway related instructions,
but similar things have to be done also on your server)
In case if your
server doesn’t have push support then you can still use push notifications via
gateway as described below.
Push notifications
via Mizu gateway or service
If you use your own
(or other) SIP server which doesn’t have push notification support (or you
don’t wish to use it’s push capabilities) then you can use the mizu VoIP push
notification gateway or free service to handle push notifications for your app
(AJVoIP also comes with a free tier push service to handle push notifications).
In this case follow
the instructions at the “AJVoIP -Mizu PUSH service” from the VoIP Push
Notifications guide.
Push notifications
with Mizu servers
Push notification
support is included in all Mizu server side products. In case if you use a
Mizutech server, then you can implement push notifications as described at the VoIP Push Notifications guide “AJVoIP” chapter.
More details about
VoIP push notifications can be found here and here.
There is no such thing as the "best codec". All commonly used codec's
present in AJVoIP are well tested and suitable for IP calls.
This
depends mainly on the circumstances.
Usually
we recommend G.729 since this provides both good quality and good compression
ratio.
If G.729
is not available in your license plan, than the other codecs are also fine
(GSM, speex, iLBC)
Otherwise
the G711 codec is the best quality narrowband codec. So if bandwidth is not an
issue in your network, than you might prefer PCMU or PCMA (both have the same
quality)
Between AJVoIP
users (or other IP to IP calls) you should prefer wideband codec's (this is why
you should always leave the opus and speex wideband with the highest priority
if you have calls between your VoIP users. These will be picked for IP to IP
calls and simply omitted for IP to PSTN calls)
To calculate the bandwidth needed, you can use this
tool. You might
also check this blog entry: Codec misunderstandings
What is the default codec priority?
The codec priority order is calculated automatically based on circumstances
(CPU, device capabilities, network). The AJVoIP library does a good job to
always select the optimal codec set so you should change the codec priorities
only if you have some very specific needs. The SIP library is also capable to automatically
re-INVITE with changed codec set if the server or the peer device rejects the
first INVITE due to codec incompatibility.
If you doesn't change the codec priorities with the parameters and you
have enough CPU power and good network, than the default codec order will be
the following (listed in priority order):
1.
Opus
wideband (enabled low priority 2)
2.
speex
wideband (enabled low priority 2)
3.
G.729
(enabled low priority 2)
4.
PCMU
(enabled low priority 2)
5.
PCMA
(disabled 1)
6.
speex
ultrawideband (disabled 1)
7.
opus
ultrawideband (disabled 1)
8.
opus
narrowband (disabled 1)
9.
speex
narrowband (disabled 1)
10. GSM (disabled 1)
11. iLBC (disabled 0)
To prefer a codec you just have to set it’s
priority to 3 (use_myfaworitecodec=3).
This will automatically enable and put your selected codec as the highest
priority one.
If you set all codec with the same priority, then the real priority will be the
following:
1.
Opus
wideband
2.
Speex
wideband
3.
G729
4.
G711
5.
Gsm
6.
Opus
narrowband
7.
Speex
narrowband
8.
Ilbc
(lowest priority)
Note:
·
It
is not guaranteed that the endpoints will consider the codec order but normally
the other endpoint usually will pick up the first codec, or AJVoIP will pick-up
the first in this list from the list of codec’s sent by the other peer
·
Not
all codec is available in the Basic and Standard license (The Advanced and Gold
license contains all codec)
Method A:
Just set the prefcodec parameter.
Method B:
If you prefer to use the use_xxx parameters for the codec settings, then just
set the desired codec priority to 3 and set the priority for all other codes to
2. In this case you preferred codec will be used whenever the other endpoint
supports it and other codec’s are used only if otherwise the call would fail.
For example the following parameters will set g.729 as the preferred codec and
will enable also pcmu and gsm:
-use_g729=3
-use_pcmu=2
-use_pcma=1
-use_gsm=2
-use_speex=1
-use_speexwb=1
-use_speexuwb=1
-use_opus=1
-use_opuswb=1
-use_opusuwb=1
-use_opusswb=1
-use_ilbc=1
The disconnect
reasons are reported in the following format: code
text. (So you have the text after a space)
Code:
Is a
SIP disconnect request or answer code including BYE, CANCEL or any SIP response
code above 300.
If
no disconnect message were received or sent then the code is -1.
Text:
The
text is one of the followings:
1.
local
disconnect reasons (listed below)
2.
disconnect
reason extracted from SIP Warning or Reason headers
3.
response
text extracted from the first line of SIP responses (textual representation of
the response code)
4.
textual
representation of the disconnect code
The local disconnect reasons can be one of
the followings (extra details might be appended and new disconnect texts might
be added in the future):
·
notaccepted
·
User
Hung Up
·
bye
received
·
cancel
received
·
authentication
failed
·
endpoint
destroy
·
no
response
·
call
setup timeout
·
ring
timeout
·
media
timeout
·
endpoint
timeout
·
tunneling
calltime limit
·
call
max timer expired
·
max
call time expired
·
max
speech time expired
·
not
acked connection expired
·
disconnect
on transfer
·
transferalways
·
transfer
timeout
·
transfer
fail
·
transfer
done
·
transfer
terminated
·
transfer
(other)
·
refer
received
·
cannot
start media
·
not
encrypted
·
srtp
fail
·
srtp
init fail
·
disc
resend
·
failed
media
·
forward
·
forwardonbusy
·
forwardonnoanswer
·
forwardalways
·
rejectbusy
·
rejectonphonebusy
·
call
rejected by peer
·
rejected
by the peer
·
rejected
·
autoreject
·
autoignore
·
ignored
You can easily
integrate your app with any other external service, Android service. These as
nothing to do with services offered by a SIP library thus it has to be handled
by yourself, however further integration with SIP can be easily handled by the
AJVoIP capabilities as described in this documentation.
For example you
might add tight integration with your or third-party apps or services by launching other
activities, handling links, interacting with other apps,
consuming HTTP API’s or displaying web
content from your website in your app.
Native integrations
means extending the native phone services with SIP capabilities by integrating
your app with the Android OS.
For example you can
easily implement native call integrations means handling calls made from the
standard android dialer. With other words you can capture calls initiated by
the native android dialer and handle it with your SIP application instead of
the mobile service network.
We haven’t added
this functionalities inside the library since it requires user interface
integration which is not suitable for a headless SDK, however we wrote a Android Native SIP Call
Integration guide to help you with these tasks, covering the most important
topics.
Beyond SIP call
integration, this guide also covers some other topics such as managing the
Android phone call history or acquiring the user phone number.
This FAQ point is to
help you with managing contacts if that is required for your needs.
Basic contact management API is included also in AJVoIP for your
convenience, however usually it is recommended to handle this in your app after
your specific requirements as it is usually highly coupled with user interface
thus not much to do with a headless SIP library.
Below we will
present a few simple code examples for your convenience:
a.
Get contacts list
b.
Get one contact
details
c.
Create a contact
d.
Open native
contact editor
e.
Call history
For the below
examples to work, you will need READ_CONTACTS and WRITE_CONTACTS permissions.
a)
Let’s start by
getting the contact list with the below code
// retrieving contact list (id and name)
// if "searchName" parameter is not an empty String, then it will
search for the contacts which names contain the specified String
public void GetContactsList(String
searchName)
{
Cursor cur = null;
ContentResolver cr = MyApplication.getAppContext().getContentResolver();
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = 1";
if (searchName
!= null &&
searchName.length() > 0) { selection += "
AND " + ContactsContract.Contacts.DISPLAY_NAME + " LIKE \"%" + searchName + "%\""; }
String[] projection = new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME };
// query the Contacts database and return
contacts in Ascending order by name
cur = cr.query(
ContactsContract.Contacts.CONTENT_URI,
projection,
selection,
null,
ContactsContract.Contacts.DISPLAY_NAME
+ "
ASC");
if (cur != null && cur.getCount() > 0)
{
// iterate through the cursor and get each
contact ID and name
while (cur.moveToNext())
{
if (cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID)) != null &&
cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)) !=
null)
{
// one single contact ID and name
String contactId =
cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String contactName =
cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
}
}
if(cur
!= null){
cur.close(); cur = null; }
}
b)
Once we have the
contact list, we can get any contact details by ID. In the following example we
are querying just for the contact phone number, but any other field of interest
can be queried the same way:
// get numbers and number types from a contact
public void GetContactPhoneNumbers(String contactId)
{
ContentResolver cr = MyApplication.getAppContext().getContentResolver();
Cursor cur = null;
// get phone numbers and phone number types
cur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
new String[]{contactId}, null);
int i = 0;
if (cur != null && cur.getCount() > 0)
{
while (cur.moveToNext())
{
// a contact can have multiple phone numbers associated to it
// for more details about phne number type, check the documentation here: https://developer.android.com/reference/android/provider/ContactsContract.CommonDataKinds.Phone
String phoneNumber = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String numberType = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
String numberId = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
}
}
if(cur != null){ cur.close(); cur = null; }
}
c)
We can also
create new contacts using the below code example:
public void CreateContact(String
name, String phone)
{
ContentResolver cr = getContentResolver();
String accountType = null;
String accountName = null;
// create a raw contact and insert its name
ContentValues values = new ContentValues();
values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType);
values.put(ContactsContract.RawContacts.ACCOUNT_NAME, accountName);
Uri rawContactUri = cr.insert(ContactsContract.RawContacts.CONTENT_URI,
values);
long rawContactId
= ContentUris.parseId(rawContactUri);
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
name);
cr.insert(ContactsContract.Data.CONTENT_URI, values);
// insert contact details (phone numbers and
number types)
Uri insertDetailsUri =
Uri.withAppendedPath(rawContactUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
values.clear();
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
values.put(PHONE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
getContentResolver().insert(insertDetailsUri, values);
}
d)
Open native
contact editor
Intent intent = new Intent(Intent.ACTION_EDIT);
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI,
String.valueOf(contactId));
intent.setData(uri);
act.startActivity(intent);
e)
Call history
An example code to manage the native call
history can be found in this guide.
The AJVoIP SIP SDK can be also used from Delphi or C++ Builder, for example to
build a softphone in Embarcadero FireMonkey.
The AJVoIP library was
created with API level suitable for Delphi, using support library for new
features, thus it fulfills to Delphi requirements.
You will need to use the .jar file included in the AJVoIP download
(not the .aar file) and create a native bridge to it using the Java2OP tool.
Follow this guide to add the AJVoIP jar to your Delphi
or C++Builder project.
You can find more examples and guides over the
internet.
Once the AJVoIP.jar
file is added to your project, have a look at the quick start guide first, then check the details from
this documentation.
The sample project was
created for Android Studio, but the logic is the same. The relevant details are
in the MainActivity.java file. Just rewrite it with Delphi or
C++ Builder syntax or implement a similar logic in Delphi / C++ Builder.
You might need such
functionality if you wish to implement a SIP softphone, however there is no
such service provided by the standard SIP protocol thus each service is
handling this functionality in a proprietary way. Usually the softswitch will
expose a simple HTTP API (XML or JSON GET/POST/PUT) for this which you can call
from your application. Contact your service provider or SIP server
documentation for the details about such an API.
Another possibility
would be to integrate your “Sign-Up” webpage into your app as a WebView.
Since this SIP
library is intended to run mainly on SMS capable devices, usually there is no
demand for built-in SMS functionality.
However if you wish
integrate SMS functionality into your application, we can recommend the following
options:
Use the platform
native SMS capabilities
This can be achieved
with a single line of code:
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("sms:"
+ phonenumber)));
In case if you wish
to preset the message text:
Intent intent = new
Intent(Intent.ACTION_VIEW, Uri.parse("sms:" + phoneNumber));
intent.putExtra("sms_body",
message);
startActivity(intent);
You can also send
SMS without user interaction using the android.telephony.SmsManager
capabilities.
In this case you
will need to add the following permission: <uses-permission
android:name="android.permission.SEND_SMS"/>
Use your SIP server
SMS capabilities
It might be possible
that you wish to offer SMS capabilities for your endusers, especially if you
can get offer better pricing than the mobile service provider.
In this case the SMS
are sent usually with one of the following methods:
·
Using
your server API: some SIP servers expose a HTTP API (PUT/POST/GET with clear
text, JSON, XML or other playload) which can be easily integrated with SIP
client applications. Just perform the API call as specified in your server
documentation.
·
Using
standard SIP IM: some SIP server is capable to convert regular SIP text
messages (RFC 3428) to SMS when the
target number is a routable mobile phone number.
In this case you
just need to use the SendSMS API. Optionally you
might set the haschat parameter to 2 to signal to the SIP
server that your intention is to send SMS.
Handing incoming SMS
Special handling of
incoming SMS messages doesn’t have much meaning on an SMS capable devices since
the OS is already capable to handle this task.
In case if your SIP
server might send SMS over IP, then you have a few possibilities to handle it:
·
Using
the SIP protocol to handle SMS message (RFC 3428). In this case you don’t need to do
anything special as the messages are processed like regular IM extra. This
should be the preferred delivery method of SMS messages in SIP networks.
·
PUSH:
you can use a server initiated push protocol for SMS delivery. The most
effective is the usage of the cloud based push notifications
·
Polling:
this means requesting a server API from a timer to see if there is any new
message arrived. Ineffective as it consumes extra CPU on both the server and
client side thus it is not recommended especially in large networks, however
due to its easy implementation this might be convenient in specific apps with a
smaller user base if your SIP server (softswitch/PBX) doesn’t support any other
method
·
Other
protocols: you might handle incoming SMS with other proprietary or standard protocol
like XMPP
IM (Instant
message/chat) is well supported by AJVoIP. Make sure that your server has
support for SIP MESSAGE.
Basic IM:
The core chat
functionality can be implemented very easily:
·
To
send a text message just use the SendChat function. Example: SendChat(-1,
"john", "", "Hi!")
·
Incoming
text messages can be cached by the CHAT notifications.
Example: “CHAT,1,john,Hi!”
Usually you will
have to maintain a separate thread with each peer (displaying the conversations
on a separate page by peer).
Optional features:
Once the simple chat
send/receive is working, you might add some extra functionalities:
·
Handle
delivery success/failure:
o You might parse the CHATREPORT notifications to
notify the user if the message was delivered successfully or failed.
·
Typing
notifications:
o You might use the
SendChatIsComposing function to send typing notification to the peer.
o Also parse the
incoming CHATCOMPOSING messages (usually displaying
something like “John is typing…”.
·
Group
chat:
o If you wish to
implement group chat, then you should send/accept the group name which is
usually the members separated by | . Example: "emma | john | linda"
o When sending, use
the group parameter of the SendChat. Example: SendChat(-1, "emma",
"emma | john | linda ", "Hi")
o For receiving, check
if the message begins with the "GROUP: xy:" substring where xy is the
group.
o Usually you have to
display each group as a separate thread (separate window for each group name).
If group name doesn't exists, then use the peername.
·
Offline
messaging:
Offline messaging
means queuing messages for later deliver when immediate delivery fails.
Offline
messaging is automatically handled by AJVoIP unless you set the offlinechat parameter to 0.
Beyond the IM SIP
protocol offered by AJVoIP, chat is mostly about user interface. Implement a
nice GUI with handy features such as threaded messaging, send picture (using
the file send API), emoticons and any other features for your users.
Push-to-talk
or press-to-transmit (PTT) is an one-way communication method to mimic legacy
half-duplex communication lines using a using a button to switch from voice reception
mode to transmit mode. The feature is often used for door phones, walkie-talkies
or industrial control functions.
PTT can
be implemented by using the Hold function.
If
somehow call hold is not well supported by your server or the remote peer, then
you might use Mute instead.
Other related functions and
parameters which you might use are the followings:
IsMuted, IsOnHold, HoldChange,
automute, autohold, holdtypeonhold, muteonhold, defmute, sendrtponmuted
For outgoing calls
the Caller ID (CLI)/A number display is controlled by the server and the
application at the peer side (be it a VoIP softphone or a pstn/mobile phone).
Caller-ID means the remote username, extension number or real phone number as
sent by your SIP server. The SIP server might or might not forward the remote
real caller-id or might replace it to any arbitrary value (such as the CLI
number associated to the user, the user extension or auth id).
You can use the
following parameters to influence the caller id display at the remote end:
-username
-authusername/sipusername
-displayname
Some VoIP server
will suppress the CLI if you are calling to pstn and the number is not a valid
DID number or AJVoIP account doesn’t have a valid DID number assigned (You can
buy DID numbers from various providers. This is up to your SIP server
configuration and has nothing to do with AJVoIP).
The CLI is usually
suppressed if you set the caller name to “Anonymous” (hide CLI).
For incoming calls
the Java softphone will use the caller username, name or display name to
display the Caller ID. (SIP From, Contact and Identity fields extracted from
the incoming INVITE).
You can also use
headers such as preferred-identity to control the Caller ID display.
The Caller-ID is
received with the STATUS notifications or you can query it with the GetCallerID
API. You can also use the GetIncomingDisplay API which can return some more
details about the caller such as the display name.
Example (fields
containing information about the caller name or number highlighted with bold):
INVITE sip:bob@biloxi.com
SIP/2.0
Via: SIP/2.0/UDP
pc33.atlanta.com;branch=z9hG4brn7wmmo4h
Max-Forwards: 35
To: Bob
<sip:bob@biloxi.com>
From: Alice <sip:alice@atlanta.com>;tag=871822
Call-ID: a82c41f1b65
CSeq: 1 INVITE
Contact: <sip:alice@pc33.atlanta.com>
P-Asserted-Identity: "Cullen
Alice" <sip:alice@atlanta.com>
P-Asserted-Identity: tel:+14095361002
Content-Type: application/sdp
Content-Length: 142
...sdp content...
You can learn more here and here.
IM (Instant
message/chat) is well supported by AJVoIP. Make sure that your server has
support for SIP MESSAGE.
Basic IM:
The core chat
functionality can be implemented very easily:
·
To
send a text message just use the SendChat function. Example:
SendChat(-1, "john", "", "Hi!")
·
Incoming
text messages can be cached by the CHAT notifications.
Example: “CHAT,1,john,Hi!”
Usually you will
have to maintain a separate thread with each peer (displaying the conversations
on a separate page by peer).
Optional features:
Once the simple chat
send/receive is working, you might add some extra functionalities:
·
Handle
delivery success/failure:
o You might parse the CHATREPORT notifications to
notify the user if the message was delivered successfully or failed.
·
Typing
notifications:
o You might use the
SendChatIsComposing function to send typing notification to the peer.
o Also parse the
incoming CHATCOMPOSING messages (usually displaying
something like “John is typing…”.
·
Group
chat:
o If you wish to
implement group chat, then you should send/accept the group name which is
usually the members separated by | . Example: "emma | john | linda"
o When sending, use
the group parameter of the SendChat. Example: SendChat(-1, "emma",
"emma | john | linda ", "Hi")
o For receiving, check
if the message begins with the "GROUP: xy:" substring where xy is the
group.
o Usually you have to
display each group as a separate thread (separate window for each group name).
If group name doesn't exists, then use the peername.
·
Offline
messaging:
Offline messaging
means queuing messages for later deliver when immediate delivery fails.
Offline
messaging is automatically handled by AJVoIP unless you set the offlinechat parameter to 0.
Beyond the IM SIP
protocol offered by AJVoIP, chat is mostly about user interface. Implement a
nice GUI with handy features such as threaded messaging, send picture (using
the file send API), emoticons and any other features for your users.
How to use AJVoIP
for peer-to-peer calls?
Registering to a SIP
server has various advantages, but JVoIP can be
used also for peer to peer calls without using any SIP server for example to
make direct calls between two AJVoIP instances or between AJVoIP and any other
SIP endpoint (such as a third-party softphone on your local LAN).
In this case just set
the register parameter to 0 and
set the serveraddress parameter to the
peer SIP endpoint address (IP:port) or use full SIP URI to make calls such as Call(-1, '1111@192.168.1.8:5678').
To make AJVoIP
reachable for incoming calls, you should set a fix value for the signalingport.
For example if your
phone IP address is 192.168.1.8 and you have set the signalingport to 5678,
then remote peers can reach your AJVoIP instance by calling to sip:1111@192.168.1.8:5678.
IMS USSD (Unstructured
Supplementary Service Data) messages are described in the 3GPP TS 24.390 standard.
This service
provides the support for UE or network initiated MMI strings including single
requests and dialogs.
It is commonly used
to send quick feature codes to/from mobile networks used for various purposes
such as balance request, callback, MMI supplementary services and other
operations.
First of all, make
sure to enable USSD by setting the ims3gpp_ussd parameter to 1 or the ims3gpp
parameter to 2 as described here.
Use the SendUSSD function to send USSD strings.
Received USSD
strings can be cached by the USSD notifications.
A simple USSD
message exchange looks like this:
1.
API
function call: SendUSSD(-1, "INVITE",
"*135#"); //initiate USSD dialog
(for example ask for available credit)
2.
notification:
USSD,1,1,sent //message
successfully sent
3.
notification:
USSD,1,2,Enter PIN code //incoming USSD message (for example network asking for
extra info)
4.
API
function call: SendUSSD(1, "INFO",
"1234"); //send USSD answer with
INFO
5.
notification:
USSD,1,1,sent //message
successfully sent
6.
notification:
USSD,1,2,Your credit is 5 USD //incoming USSD message (for example final answer
received in BYE)
7.
API
function call: Hangup(1); //just for sure in case if somehow the call was not
disconnected by the server
DTMF means Dual-tone
multi-frequency signaling and it is commonly used to send touch tones to the
server or the other peer. On phone user interface this is usually handled by
handling key press or presenting a phone interface to the user who can press
the digits to be sent.
Using the SIP protocol,
there are multiple ways to send DTMF digits which can be set by the dtmfmode parameter.
If you are using the
built-in user interface then you can send DTMF digits by pressing the number
buttons during a call and if a dtmf digit is received, then you will see it
displayed on the user interface notification area.
DTMF digits can be
sent using the Dtmf API.
Feedback about the
delivery can be obtained by watching for the INFO notifications (you will receive INFO,OK when the
message was successfully sent or INFO,ERROR if failed).
On incoming DTMF you
will receive a DTMF notification.
You can send and
receive custom SIP INFO messages in the SIP signaling as described in RFC 2976.
Note: If you are looking to send or
receive DTMF digits, then you should look at the above FAQ point instead.
To send a custom
INFO message, use the Info function.
Feedback about the
delivery (if necessary) can be obtained by watching for the INFO notifications (you will receive INFO,OK when the
message was successfully sent or INFO,ERROR if failed).
INFO notifications are also triggered for incoming SIP INFO
messages (INFO,REC).
Call transfer is about
transferring a connected call with SIP REFER.
If you are looking to
forward a (not yet connected) incoming call then you should use the Forward function instead.
The
transfer mode can be set with the transfertype parameter and the calls can be
transferred with the Transfer function.
The call
transfer is handled with the SIP REFER method as described in RFC 3515, RFC 5589 and RFC 6665.
With unattended
transfer using transfertype 1 the transfer will be executed immediately
once you call the Transfer function (blind transfer; only a SIP
REFER is sent).
With unattended
transfer using transfertype 6 and holdontransfer 1 or 2 the call might be
put on hold before transfer and reloaded on transfer fail.
With attended
transfer (transfertype 5) you can use the following call-flow, supposing
that you are working at A side and wish to transfer B to C:
With
unattended transfer the transfer will be executed immediately once you call the
Transfer function.
With
attended transfer (transfertype 5) you can use the following call-flow
(supposing that you are working at A side and wish to transfer B to C):
1.
A call B
(outgoing) or B call to A (incoming)
A speaking with B
2.
Call Transfer (-1,C)
The call between A and B will be put on hold by A
A will call to C and connect (consultation call; if call
fails, then the call between A and C will be un-hold automatically)
A speaking with C
3.
The actual call
transfer will be initiated when A disconnect the call (Hangup)
REFER message will be sent to B (which tells to B to call C.
usually by automatically replacing the A-B call with A-C)
4.
After transfer
events:
-If transfer fails (B can’t call C) the call between A and B
will be will be un-hold automatically (if server sends proper notifications)
-If the transfer succeeds (B called C) the call between A
and B will be will be disconnected automatically (if server sends proper
notifications)
-If the server doesn’t support NOTIFY, then the call can be
un-hold or disconnected from the API (Hold(-2,false), Hangup(-1))
5.
B speaking with C
at this point if the transfer was successful
There are
a few optional parameters related to call transfer which you might set after
your needs:
transfertype, transfwithreplace, allowreplace, discontransfer,
disconincomingrefer, transferdelay, checksubscriptionstate,
subscribefortransfer, holdontransfer, calltransferalways
For
simple use-case the line parameter for the
API functions almost always can be just set to -1.
More details:
The line parameter is part of most of the API
functions and means
the channel number.
With this parameter you
can specify the session for which a function call to be applied (such as a
specific call if there are multiple simultaneous calls).
The following values
are defined:
Ø -2: all channels
Ø -1: the current channel set
previously by SetLine API or by other functions. Usually this will mean the
first channel (1)
Ø 0 : undefined (this should not be
received/sent for endpoints in call, but might be used for other endpoints such
as register endpoints)
Ø 1: first channel
Ø 2 : second channel
Ø etc (you can control the max number
of the channels with the maxlines parameter which is set to 4 by default)
Most commonly, you will
have to always pass -1 as the channel number. You will have to use other values
only if you will present a GUI were the user can select different lines or if
you have some special requirement to handle the lines explicitly.
Otherwise, AJVoIP can do this automatically allocating new channels when
needed.
The line parameter is also part for most of the notifications to inform you which session
triggered the notification.
See the “Multiple
lines” FAQ point below if you wish to handle the lines explicitly.
Multi-line
means the capability to handle more than one call at the same time (multiple
channels).
Multi-lines
are handled automatically by default and you can skip this description if you
don’t wish to explicitly manipulate the different lines (for example allowing
the enduser to hold/forward/transfer or do any other action per line
separately).
This can
be managed by the line parameter of the API functions (most functions has a
line parameter) and by checking the line parameter of the STATUS and other
notifications (most notifications has a line number).
By
default you don't need to do anything to have multi-line functionality as this is managed automatically with
each new call on the first “free” line. This means that you just need to pass
-1 as the line number with any function call and look only the notifications
with the line number set to -1 (the global phone state).
If you
wish to manage the lines explicitly, then you should pass the desired line
numbers with the API calls and also look for the notifications received from
the individual lines (such as the line parameter of the STATUS notification).
This is necessary for example if you wish to create a user interface where the
users can select/change to a specific line (line selector or line buttons).
Multi-line
vs multi-account
Multiple accounts refers to the feature when you might
have more than one SIP account (on the same or separate SIP servers).
Multi-lines
is described here and refers to the feature when you might need to handle
multiple phone channels usually for multiple simultaneous calls or call
transfer.
You can
also have multi-accounts and multi-lines at the same time (multiple
simultaneous calls via multiple accounts).
Multi-line
vs Conference
When we
refer to “multi-line” we mean the capability to have multiple calls in progress
at the same time. This doesn’t necessarily means conference calls. You can
initiate multiple calls by just using the Call API
multiple times (to initiate calls to more than one user/phone), so you can talk
with remote peers independently (all pears will hear you unless you use hold on
some lines, but the peers will not hear each-others).
To turn
multiple calls into a conference, you need to use the Conf API (or use the conference button from the softphone.html).
When you have multiple peers in a conference, all peers can hear each-other.
Usage
o Just set the line parameter to -1 for
all/most function calls and parse only notifications with line -1 if you don’t
wish to deal with multiple lines explicitly.
In this case AJVoIP will handle all the details and will guess which lines to
use.
o However, if you have some special
requirements to handle the lines/calls in a different way, then try to be
strict with the line numbers:
try to always pass the correct line parameter for the API calls and process the
notifications from different lines according to your app requirements.
Enable
multi-line
There is
nothing to be done to enable multi-line functionality as it is enabled and
handled by default.
Optionally
you might set the following parameters if your use-case requires multiple
simultaneous calls:
o aec: 0
o aec2: 0
o agc: 0
o focusaudio: 1
Disable
multi-line
You can
disable multi-line functionality with the following settings:
o set the “multilinegui”
parameter to 0
o set the "rejectonbusy" setting to "true"
Other
related parameters are the "automute"
and "autohold" settings.
Channel
settings
Individual
lines are initialized with the global parameters and their behavior might
change depending on the circumstances and usage.
Some
parameters can be also set line by line using the SetLineParameter function (avoid using this when
possible and use the other API’s instead to influence the behavior of specific
individual lines).
API
Most API
functions has a line parameter which you can set to specify the line number.
Some API’s such as the GetLineStatus have been implemented to help you
using multiple lines.
Also
there are two specific API to set/get the current active line:
o SetLine(line); // Will set the current line. Just set it before other API
calls and the next API calls will be applied for the selected line
o GetLine();
//Will return the current active line number. This should be
the line which you have set previously except after incoming and outgoing calls
(will automatically switch the active line to a new free line for these if the
current active line is already occupied by a call)
The
active line is also switched automatically on new outgoing or incoming calls
(to the line where the new call is handled).
Notifications
Check the
line parameter for the STATUS and other notifications and update your line state machine
accordingly and/or change your user interface accordingly.
Channels
The
following line numbers are defined:
o -3: in some functions you can refer
to the next session with the line parameter set to -3
o -2: all (some API calls can be
applied to all lines. For example calling hangup(-2) will disconnect all
current calls)
o -1: current line (means the currently
selected line or otherwise the “best” line to be used for the respective API)
o 0: undefined (this should not be
received/sent for endpoints in call, but might be used for other endpoints such
as register endpoints)
o 1: first channel
o 2: second channel
o …
o N: channel number X
Note: If you use the SetLine with -2 and -1, it might be
remembered only for a short time; after that the GetLine
will report the real active line or “best” line.
API usage
example:
Call(1,‘1111’); //make a call on the first line
Call (2, ‘2222’); //make a second call on
the second line
//setup conference call between all lines
Conf(); //interconnect current lines
//put first call on hold
Hold (1,true);
//disconnect the second call
Hangup(2, true);
How to get the audio stream?
The Android
VoIP SDK is capable to stream the received/sent media to a custom local port.
This is
useful if you wish to make some processing on the audio streams such as speech
to text or other analysis.
Just
launch an UDP socket on any port and set this port number as the sendmediain_to
and/or sendmediaout_to parameter for the SDK. Then you will receive the media
streams from the calls being made.
Parameters:
sendmedia_type
Specify the media stream format:
0: raw wave format (linear PCM) for narrowbad (8 kHz 16 bit
mono PCM files at 128 kbits - 15 kb/sec) or 16 kHz for wideband.
1: for RTP format (RTP header + payload with the actual
media codec)
2: convert sample rate to raw PCM 8kHz (useful if original
stream is in 16kHz format such as Opus or Speex wideband, but you need 8kHz
PCM)
3: convert sample rate to raw PCM 16kHz (useful if original
stream is in narrowband 8kHz format but you need 16kHz PCM)
4: RTP data only, without RTP header (raw codec format)
Default is 0.
Note:
It is recommended to set this to 0 or 1 and force a codec to match your needs
(use OPUS or Speex if you need 16kHz PCM wideband or other codec if you need
8kHz PCM narrowband), however if you need raw audio in other sample rate then
you might set it to 2 or 3 for sample rate conversion.
sendmediain_to
Specify your UDP port where you wish to receive remote audio
(received from other peer for playback on local speaker)
Default is 0 which means no streaming.
sendmediaout_to
Specify your UDP port where you wish to receive local audio
(recorded from mic which is sent to the other end)
Default is 0 which means no streaming.
Notes:
You might force G.711 codec
for the AJVoIP to simplify the audio formats conversion (disable all codec’s
except PCMU and PCMA)
This is about streaming to
your own or to a third-party application.
If you need to stream audio
to a remote SIP endpoint, then use the PlaySound or the StreamSoundBuff
function instead.
If you
have set audio streaming as it was discussed above, then you have the following
possibilities to handle it:
1.
Third
party software:
Use some
third-party software which is capable to playback raw PCM packets.
2.
RTP
stream:
If you
have a software which is capable to process RTP packets then just set the
sendmedia_type to 1 so the AJVoIP will emit RTP packets which can be processed
as is by such software.
3.
PCM
stream:
Use the
default PCM stream if you don't have any ready to use software and you have to
write it yourself.
The
packet emitted by the SIP media stack can be processed as-is by any audio
player module.
4.
Wave
files:
If you
don't need real-time audio, then just use the voicerecording and related parameters to obtain
voice files in wave or other formats at the end of each call.
5.
Barge-In:
If you
just wish to listen into conversation, then you can use the AJVoIP itself for
the job. Its barge-in feature allows you to bare into any call and create a
hidden conference endpoint, so you can hear the conversation. This is often
used in callcenters by supervisors. Contact our support if you need this
module.
6.
SIP media
streaming:
Use the PlaySound function if you need to stream an audio file to a remote SIP endpoint.
If you
wish to use the library only for call recording and/or streaming and you don’t
need recording/playback from/to the local audio device, then you might set the
following parameters:
o useaudiodevicerecord: false
o useaudiodeviceplayback: false
o audiomanagermode: -8
o focusaudio: 1
o checkvolumesettings: 0
o vibrate: 0
o playring: 0
o ringincall: 0
o beeponconnect: 0
o agc: 0
o aec: 0
o denoise: 0
o syncvoicerec: 0
o mediatimeout: 0
AJVoIP is
implemented mostly in pure Java, however it also includes some native libraries
for codec and audio processing.
The SDK
works fine even without these native libraries since all of them has Java
failback implemented.
The
following ABI’s are included by default, which will cover 99% of the devices
with native audio and codec support:
·
armeabi-v7a
·
arm64-v8a
We found
that this is the optimal set of libraries to be able to cover
all platforms with minimal additional size.
The rest
will failback to java code (thus you will have 100% device coverage!)
A good
estimation about the market can be learn from here. See the CPU models chart at the
bottom of the page.
·
armeabi-v7a: this
alone covers 98% of all devices on the market
·
arm64-v8a: this
is for the 64bit ARM architecture which is required by the Google Play
·
x86: less then 1%
of devices are using Intel x86 devices and they can use the java implementation
·
mips: we include
only fake support for mips so the Google Play will not exclude these kind of
devices. MIPS market size is near 0% and on these kind of devices AJVoIP will
just failback to pure java code
·
armeabi: not
supported. This is a very old architecture so we haven’t included armeabi libs due
to size considerations as its market size is near 0% and also Android removed ARMv5/ARMv6 support since Android 4.4 (API level 19). We
neither included a fake library because we found that if included then some
devices might load the armeabi library even if they have support for armeabi-v7a
·
x86_64: there are
no such devices on the market and it can failback to java if required by some
new devices released in the future
·
mips64: there are
no such devices on the market and anyway it is covered with the fake mips
support with Java fallback
If
somehow you wish to change the included native libraries, you can download the
whole set from here. For example you might include the
armeabi libs if your app uses some other native library and you wish to
provide support for these ancient devices for some reason.
AJVoIP
uses one or more of the following Android libraries, depending on your build
(listing here in case if somehow you encounter some incompatibility issues due
to other versions used by your app):
·
android.jar
·
com.android.support:multidex:1.0.3
(classes.jar, to split the output)
·
androidx.legacy:legacy-support-v4:1.0.0
Old libraries (not required anymore in latest version, but you might
use some of these in your app):
·
firebase-messaging-10.0.1.aar
(in classes.jar, might be required for push notifications)
·
firebase-core-10.0.1.aar
(in classes.jar, might be required for push notifications)
·
firebase-analytics-10.0.1.aar
(in classes.jar, might be required for push notifications)
·
firebase-analytics-impl-10.0.1.aar
(in classes.jar, might be required for push notifications)
·
firebase-iid-10.0.1.aar
(in classes.jar, might be required for push notifications)
·
firebase-common-10.0.1.aar
(in classes.jar, might be required for push notifications)
·
play-services-tasks-10.0.1.aar
(classes.jar)
·
play-services-basement-10.0.1.aar
(classes.jar)
·
support-v4-24.0.0.aar
(in classes.jar, might be required for forward compatibility)
·
support-v4-24.0.0.aar
(in internal_impl-24.0.0.jar, might be required for forward compatibility)
·
support-annotations-24.0.0.jar
(might be required for forward compatibility)
·
org.apache.http.legacy.jar
(might be required for backward compatibility)
Set the loglevel parameter to 5 and then the logs
will appear on the Logcat (or can be polled with the GetLogs() function call).
You might
look at the followings in the logs:
·
Search for “catch”,
“ERROR” and “WARNING” messages to find any issues. Please note that logs
generated with loglevel 3 or higher will often includes lot’s of not so
important “WARNING” messages which can be safely ignored
·
Check for the SIP
signaling. You can find out register or call issues by just following the SIP
signaling logs. (Find out the suspicious message then search for it’s Call-ID
value across the log to walk trough the messages which belongs to the same
session)
·
Search for “call
details” to get a high level overview about your calls(s). A “call details”
statistics is generated after each call.
·
Other log
messages might be too specific or technical but you might still be able to have
a gasp about the cause of the problems by looking at the logs
If you set AJVoIP loglevel higher than 1 than you will receive messages that
are useful only for debug. A lot of ERROR and WARNING message cannot be
considered as a fault. Some of them will appear also under normal circumstances
and you should not take special attention for these messages. If there are any
issue affecting the normal usage, please send the detailed logs to Mizutech support (info@mizu-voip.com) in a text file attachment.
Some internal
exceptions (such as “java.lang.NumberFormatException”) are normal in some
circumstances and can be safely ignored.
RTP warning in my server log
AJVoIP will send a
few (maximum 10) short UDP packets (\r\n) to open the media path (also the NAT
if any).
For this reason you might see the following or similar Asterisk log entries:
WARNING[8860]: res_rtp_asterisk.c:2019 ast_rtp_read: RTP Read
too short
Unknown RTP Version 1
These packets are
simply dropped by Asterisk which is the expected behavior. This is not a AJVoIP
or Asterisk error and will not have any negative impact for the calls. You can
safely skip this issue.
You might turn this
off by the “natopenpackets” parameter (set to 0). You might also set the “keepaliveival”
to 0 and modify the “keepaliveival” (all these might have an impact on AJVoIP
NAT traversal capability)
Recording errors
You might see the
following errors if AJVoIP doesn’t have permission for the audio device:
E/AudioRecord: AudioFlinger could not create record track,
status: -1
E/AudioRecord-JNI: Error creating AudioRecord instance:
initialization check failed with status -1.
E/android.media.AudioRecord: Error code -20 when initializing
native AudioRecord object.
WARNING,recorder state is 0
Solution: make sure
that the app has RECORD_AUDIO permissions.
Method exceeds
compiler instruction limit
You should enable
multidex as described here:
dependencies
{
implementation
'com.android.support:multidex:1.0.3'
}
If you
have any problem with the Android SIP library, Mizutech support most probably
will ask you to send a problem description (your question, bug report or any
integration issue) and logs about the problem.
For this
the loglevel parameter must be set to 5 and then the logs will appear on the logcat with the severity level set to
“Verbose” (or can be polled with the GetLogs() function call or logs written to
file).
Once you
reproduced the problem, send the content of the logs to info@mizu-voip.com as email text file attachment and an
exact description of the problem (also include instructions for reproductions
if possible).
Make sure
that the log contains also the AJVoIP startup (send the logs from the very
beginning, not only the part when the problem might appear).
If the
problem is call related, then make sure to have only one call in the log. That
one in which the problem was reproduced.
In
addition to the log file, Mizutech support might ask one or two SIP account
valid on your server to be able to reproduce the problem.
In case
if AJVoIP is integrated into your app, make sure that your app has some debug
functionality, capable to collect and save/export/send AJVoIP logs, implementing
some kind of log upload functionality in your app (uploading the logs to a web
service, uploading to FTP or sending it by email).
This can
be useful if some issue can’t be reproduced at development (when you have your
IDE with logcat), so the users can report problems with logs.
You can
collect the logs in the following ways:
o Set the events parameter to 3 and collect the log
events (EVENT and LOG
notifications) in your app (write to file or store some in memory)
o Configure AJVoIP to write logs to
file by setting the canlogtofile parameter to true. Use the GetLogPath()
function to get the log file path
o Set the logpolling
parameter to 1 and use the GetLogs() API function to get the logs as String
This
should be configurable in your app (when turned on, set the loglevel parameter to 5 and use some of the above
methods to collect the logs)
Android VoIP SDK home-page
Android VoIP SDK Download
Sample project
Quick Start Guide
Documentation (PDF)
Documentation (HTML)
Documentation (WinHelp)
Javadoc (download)
Javadoc (online)
Native integration
For help, contact info@mizu-voip.com
This is the old documentation
using notification strings instead of SIPNotification event objects.
You should use the new documentation instead if you are using SIPNotification
event objects.
Copyright © Mizutech
SRL