Android Question Bug in SIP Library?

Marcos Alves

Well-Known Member
Licensed User
Longtime User
Hello,

I'm trying to use the SIP B4A library and found some situations those looks to be serious issues. See:

- When placing a call, if I try to cancel before it have been answered I got an error:

CallError, ErrorCode=-4, ErrorMessage=Call/Transaction Does Not Exist (481)

- During the ring (when calling), there is no ringback audio. If I try to call :
B4X:
Sub SIP_Calling
    Log("Calling")
    CurrentCall.StartAudio
End Sub

in order to start audio before answering (to hear the ringback or any network fail message) I get the error:

CallError, ErrorCode=-4, ErrorMessage=mPeerSd = null

These two problems make impossible to use the SIP library... because in the first, the user can't give up a placing call if desists before answering and in the second there is no audible feedback that the call is being placed (some network erros which are sent before the answer signal are also inaudible) ...

Does anybody in the forum is having the same problems? Any fix?
 

Marcos Alves

Well-Known Member
Licensed User
Longtime User
1. It is not clear. Are you calling SipAudioCall.EndCall? You can also try to call SIP.Close.

2. This is how the Android built-in SIP feature works.
Hello @Erel . Thanks for answering! Let's go:
1. It is not clear. Are you calling SipAudioCall.EndCall? You can also try to call SIP.Close.
- You can try SIP.Close or SipAudioCall.EndCall . The SIP.Close destroys the SIP stack and the call persists as a "ghost call" until the remote side hangs up, and the SipAudioCall.EndCall causes the error mentioned and the control of the SIP object over the ongoing call is lost. In any way, if you try to abort a call while ringing (before to be answered by remote side), you get an error. In some Android devices there is a direct access to the native SIP stack using the Android phone call button (if you have a SIP account registered the system raises a box allowing the user to choose if it's a VoIP standard network call). Using this resource it's possible to abort an ongoing call before to be answered... as this uses the same object (native sip stack), I think that it's possible to...

2. This is how the Android built-in SIP feature works.
- I really don't think so... to be able to hear the remote audio and abort it before the call be answered is clearly an important feature and its unavailability could make the native sip stack unusable. There is something in the library related to the object method that allows the audio streaming to start that could be changed no?

Thanks again!
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Longtime User
Starting the audio is done with a call to SipAudioCall.startAudio. As its documentation says it should be called after the call is established: https://developer.android.com/reference/android/net/sip/SipAudioCall.html#startAudio()
Hello @Erel ,

Ok, but looking for the complete set of methods in Android I can see that it's possible to have full control over the call flow even when the call isn't answered yet. See:
SipAudioCall.Listener
Kotlin |Java
public static class SipAudioCall.Listener
extends Object
java.lang.Object

↳ android.net.sip.SipAudioCall.Listener

Listener for events relating to a SIP call, such as when a call is being recieved ("on ringing") or a call is outgoing ("on calling").
Many of these events are also received by SipSession.Listener.

With this method and the SipSession.Listener and SipSession.State it's possible to receive the remote side signaling and eventually produce an audible feedback to the user...
And if it's required to abort a call, the method endCall hasn't any restriction to be used before the call be answered (as it's happening in library, taking to the loss of the control over the ongoing call...) see:

endCall
Added in API level 9
public void endCall ()

Ends a call.

Throws
SipException if the SIP service fails to end the call

My main area is telecommunications engineering and I've been working with SIP and other telecom protocols the last 20 years. If you could publish or give me a SIP class (like you did with httpservice class) instead of a library could be good to access directly the native calls and eventually build some workaround on methods that could be generating problems...

Thanks for your attention as always!

Regards!
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. SipAudioCall.EndCall calls that method.

2. The listener is implemented in the library and all of its methods raise the various events:
B4X:
static class AudioListener extends Listener {
       private final BA ba;
       private final String eventName;
       public AudioListener(BA ba, String eventName) {
           this.ba = ba;
           this.eventName = eventName;
       }
       @Override
       public void onCallEstablished(SipAudioCall call) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_callestablished", false, null);
       }

       @Override
       public void onCallEnded(SipAudioCall call) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_callended", false, null);
       }
       @Override
       public void onCallBusy(SipAudioCall call) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_callbusy", false, null);
       }
       @Override
       public void onCalling(SipAudioCall call) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_calling", false, null);
       }
       @Override
       public void onError(SipAudioCall call, int errorCode, String errorMessage) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_callerror", false, new Object[] {errorCode, errorMessage});
       }
   }
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Longtime User
1. SipAudioCall.EndCall calls that method.

2. The listener is implemented in the library and all of its methods raise the various events:
B4X:
static class AudioListener extends Listener {
       private final BA ba;
       private final String eventName;
       public AudioListener(BA ba, String eventName) {
           this.ba = ba;
           this.eventName = eventName;
       }
       @Override
       public void onCallEstablished(SipAudioCall call) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_callestablished", false, null);
       }

       @Override
       public void onCallEnded(SipAudioCall call) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_callended", false, null);
       }
       @Override
       public void onCallBusy(SipAudioCall call) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_callbusy", false, null);
       }
       @Override
       public void onCalling(SipAudioCall call) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_calling", false, null);
       }
       @Override
       public void onError(SipAudioCall call, int errorCode, String errorMessage) {
           ba.raiseEventFromDifferentThread(call
                   , null, 0, eventName + "_callerror", false, new Object[] {errorCode, errorMessage});
       }
   }
Ok! That's a start point... then: what happens when we call the endCall method before the call be answered and:

- The call isn't aborted
- The call flow control is lost

Apparently the end call is only destructing the sipAudioCall object definition for B4A without make a real endCall command in sip device stack... that's the cause of the control loose at B4A side... like I told you... is it possible to use this library as a Class? And could you send me or publish this class? If I had the SIP class library I could do some tests with our SIP servers and send to you a feedback.

Thanks!
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Longtime User
No.

The only thing that happens when you call EndCall is:
B4X:
public void EndCall() throws SipException {
           getObject().endCall();
       }
Ok... but, the call isn't really ended (when this method is called before the call be answered) and the control over the call flow is lost by B4A until the app main thread is terminated... this means that the object that controls the call call ignores the command (if the call isn't answered yet) and remains active but out of the B4A control.
If you want, I can:
1. Send to you a detailed flow using a real sip call and the B4A to debug
or
2. I can send to you SIP credentials of one of our servers and you can test...

Or, if you send me the sip lib as a class, I can test here...

could be?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4A SIP library is a wrapper above Android SIP API. You can see the API yourself in the link I posted.
I don't see any relevant methods that are not exposed by the wrapper.

and the control over the call flow is lost by B4A
B4A doesn't control the flow at all. It is done by the internal SPI feature.

Or, if you send me the sip lib as a class, I can test here...
Not sure what you mean. I will not rewrite the library as a class because you don't believe me or the Android documentation... Sorry.

If you like I don't mind sending you the library source code. However I do not provide support for Java code.
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Longtime User
B4A SIP library is a wrapper above Android SIP API. You can see the API yourself in the link I posted.
I don't see any relevant methods that are not exposed by the wrapper.


B4A doesn't control the flow at all. It is done by the internal SPI feature.


Not sure what you mean. I will not rewrite the library as a class because you don't believe me or the Android documentation... Sorry.

If you like I don't mind sending you the library source code. However I do not provide support for Java code.
Hello @Erel ,

We've been working together during the last 7 years (I use B4X since the first version), and be sure that I completely trust on you and B4A - that's a fantastic framework. Is this case of SIP, I would like your attention for only one problem that makes this wrapper almost unusable: if the user wants to abort the call before it have been answered it's not possible. If the endCall method is called, the library cant control the ongoing call anymore and it remains ringing until be answered and eventually hang up by the remote side. That's the problem.
I didn't think that to expose a library as a class could demand a big job and never requested it to you... the only question in this situation is: how can I abort a call before being answered using the sip library?

Again, thanks for all your attention and sorry if it looked that I was not believing on you. My intention is only to fix a problem that seriously impacts the B4A SIP library usability...
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Longtime User
B4A SIP library is a wrapper above Android SIP API. You can see the API yourself in the link I posted.
I don't see any relevant methods that are not exposed by the wrapper.


B4A doesn't control the flow at all. It is done by the internal SPI feature.


Not sure what you mean. I will not rewrite the library as a class because you don't believe me or the Android documentation... Sorry.

If you like I don't mind sending you the library source code. However I do not provide support for Java code.
Would be a BIG honor if I could collaborate and find out what's happening in the endCall method...
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
i guess you´ll not see much there as it is only a thin wrapper over the android sip stack.
As written by Erel the control is completely in the android sip.
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Longtime User
i guess you´ll not see much there as it is only a thin wrapper over the android sip stack.
As written by Erel the control is completely in the android sip.
Hello @DonManfred ... ok, like I told I definitely believe on @Erel . That said, in the SIP wrapper I identified a difference between the phone call being done directly from the device interface (when it's available) and using the library, specially when we try to cancel it before be answered. Of couse that this difference could be something reserved by Google in their "internal methods" for "special developers" (the big ones like FaceBook with WhatsApp ...).
As a telecommunications engineer I followed many situations when the Telecommunications companies influenced the decision to remove SIP stack from android devices and many incomplete internal implementations of this feature in many devices due this fight. But it looks that in Android 8+ this is overcome...
Let's see what I can do ...I'll update the posts here when I have any progress ...
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Longtime User
Don't assume that they use Android built-in SIP feature.
I know, but they should no ? ;) If they "give to us" this path , they should use it... (at least they want that we believe in this) - at least Google that is the "father" of Android should use what they call "Android Public LIbraries"
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Longtime User
Don't assume that they use Android built-in SIP feature.
By the way... about services reliability and "fail proof", I use Firebase to trig a messaging app in Android and WhatsApp is still far more responsive than my app when the phone is sleeping ... In this forum, I read many threads about the existence of "special apis" reserved for the "bigs"... but it's no subject matter of this thread no? ;). Let's go.
 
Upvote 0
Top