I need to include a walki talkie in my app. I am always getting a registration failure -9 error code. I created 2 free Sip account (sip2sip.info, sip.linphone.org) and 1 commercial one (onsip.com). I added all those permission:
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_SIP" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
and the following features:
<uses-feature android:name="android.hardware.sip.voip" android:required="true" />
<uses-feature android:name="android.hardware.wifi" android:required="true" />
<uses-feature android:name="android.hardware.microphone" android:required="true" />
I am calling the above fonction in the onCreate:
void log_and_register()
{
try
{
c.DEBUG().ftrace("VOIP Supported: " + SipManager.isVoipSupported(c.ma()));
c.DEBUG().ftrace("SIP API Supported: " + SipManager.isApiSupported(c.ma()));
mSipManager = SipManager.newInstance(c.ma());
SipProfile.Builder builder = new SipProfile.Builder(c.config().getSIP_UserName(), c.config().getSIP_Domain());
builder.setPassword(c.config().getSIP_Password());
//builder.setProtocol("UDP"); //"TCP");
//builder.setPort(5060); //5080 5070
builder.setAutoRegistration(true);
mSipProfile = builder.build();
}
catch (ParseException pe)
{
c.DEBUG().ftrace("incapable of parsing domain name, username or password!");
c.DEBUG().ASSERT(0 == 1);
}
try
{
Intent intent = new Intent();
intent.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(c.ma(), 0, intent, Intent.FILL_IN_DATA);
mSipManager.open(mSipProfile, pendingIntent, null);
}
catch (SipException se)
{
c.DEBUG().ftrace("WALKIE TALKIE NOT WORKING - Sip Exception!!");
c.DEBUG().ASSERT(0 == 1);
}
if (ContextCompat.checkSelfPermission(c.ma(), Manifest.permission.USE_SIP) == PackageManager.PERMISSION_GRANTED)
c.DEBUG().ftrace("GRANTED!!!");
else
ActivityCompat.requestPermissions(c.ma(), new String[]{Manifest.permission.USE_SIP}, 1);
try
{
if (mSipManager.isRegistered(mSipProfile.getUriString()))
{
c.DEBUG().ftrace("already registered !!" + mSipManager.isRegistered(mSipProfile.getUriString()));
return;
}
}
catch (Exception e)
{
c.DEBUG().ftrace("NO!!");
}
try
{
//mSipManager.register(mSipProfile, 30, new SipRegistrationListener(){
//mSipManager.register(mSipProfile, 30000, new SipRegistrationListener(){
c.DEBUG().ftrace("THIS IS THE TRACE BEFORE REGISTATION : " + mSipProfile.getUriString());
mSipManager.setRegistrationListener(mSipProfile.getUriString(), new SipRegistrationListener()
{
public void onRegistering(String localProfileUri)
{
c.DEBUG().ftrace("Registering with SIP Server...");
}
// next version has it!!
public void onRegistrationTimeout() {}
public void onRegistrationDone(String localProfileUri, long expiryTime)
{
c.DEBUG().ftrace("SIP Ready");
}
public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage)
{
// -9 signifie qu'il y a un appel en cours
c.DEBUG().ftrace("CANNOT REGISTER domain=" + c.config().getSIP_Domain() + " / username=" + c.config().getSIP_UserName());
c.DEBUG().ftrace("SIP ERROR MSG : localProfileUri=" + localProfileUri + " errorCode=" + errCode(errorCode) + " errorMessage=" + errorMessage);
}
});
}
catch (Exception e)
{
c.DEBUG().ftrace("Cannot initialise wakie talkie!");
c.DEBUG().ASSERT(0 == 1);
}
// https:github.com/aosp-mirror/platform_development/commit/a025796211f15c2796f8ea3208c066801aa250b6
initiateCall();
}
public SipAudioCall call = null;
public void initiateCall() {
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// Much of the client's interaction with the SIP Stack will
// happen via listeners. Even making an outgoing call, don't
// forget to set up a listener to set things up once the call is established.
@Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
}
@Override
public void onCallEnded(SipAudioCall call) {
}
};
c.DEBUG().ftrace("rafael - Format="+mSipProfile.getUriString());
//call = mSipManager.makeAudioCall(mSipProfile.getUriString(), sipAddress, listener, 30);
call = mSipManager.makeAudioCall(mSipProfile.getUriString(), "sip:rafael.hogue@sip2sip.info", listener, 30);
} catch (Exception e) {
Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);
if (mSipProfile != null) {
try {
mSipManager.close(mSipProfile.getUriString());
} catch (Exception ee) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", ee);
ee.printStackTrace();
}
}
if (call != null) {
call.close();
}
}
}
I compile for Nougat because I am using deprecated function. Then I modified my code to compile with Oreo. I used Firewall Voip Checker to check my connection with my SIP server and the test 1 is successful but the second one seam to be in an infinite loop. One of the result of the test one is captured my attention but I don't know what it means:
Check NAT type
100% / Blocked or could not reach STUN server (but it's green so I guess it pass the test??). I had the flag :
android.useDeprecatedNdk=true
I change it to false... and I always get the return code "registration faild"
I hadded this fonction to see what the -9 error code was:
// FOR MORE DETAILS SEE // Sip Error while registration // How to send instant message via SIP //https://developer.android.com/reference/android/net/sip/SipErrorCode private String errCode(int iErrorCode) { String sErr = "";
switch (iErrorCode)
{
case CLIENT_ERROR:
sErr = "client error!!";
break;
case CROSS_DOMAIN_AUTHENTICATION:
sErr = "cross domain authentification!!";
break;
case DATA_CONNECTION_LOST:
sErr = "data connection lost!!";
break;
case INVALID_CREDENTIALS:
sErr = "invalid credentials!!";
break;
case INVALID_REMOTE_URI:
sErr = "invalid remote uri!!";
break;
case IN_PROGRESS:
sErr = "In progress!!";
break;
case NO_ERROR:
sErr = "No error!!";
break;
case PEER_NOT_REACHABLE:
sErr = "peer not reachable!!";
break;
case SERVER_ERROR:
sErr = "server error!!";
break;
case SERVER_UNREACHABLE:
sErr = "server unreachable!!";
break;
case SOCKET_ERROR:
sErr = "socket error!!";
break;
case TIME_OUT:
sErr = "time out!!";
break;
case TRANSACTION_TERMINTED:
sErr = "No transaction terminated!!";
break;
default:
sErr = "No error detected!!";
break;
}
return (sErr);
}
The error message is "In progress..." witch means that he is busy already but I don't know what it means.
I when thru the error code on Wikipedia to have clues of the potential problem:
https://en.wikipedia.org/wiki/List_of_SIP_response_codes#4xx.E2.80.94Client_Failure_Responses
I tried to find a SDK of a higher lever to implement my walki talki and found.
I search for the app wireshark but I only found it for a laptop and not for my android smartphone.
It's important for me to implement the walki talkie because I am creating a app to increase the security of primary school daycare and we need to communicate with each other.
I tried to change the port and the communication protocol and I tried the AutoRegistration flag to true.
I tried to make a phone call after the registration failed in case the open statement did the registration assuming it could be trying to register a second time.
I have no more idea!!