Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
244 views
in Technique[技术] by (71.8m points)

java - Sip Error while registration

I am using native methods of sip calling and it is working fine but some time it is giving registration error IN_PROGRESS (Error Code -9 ) .I have search in Sip Error codes but dint find any error code of this kind . Here is my code for sip registration .PLease tell me if any one have idea about this error please tell me .

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.*;
import android.net.sip.*;
import java.text.ParseException;
/**
 * Handles all calling, receiving calls, and UI interaction in the WalkieTalkie app.
 */
public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {

    public String sipAddress = null;
    public static SipManager manager = null;
    public static SipProfile me = null;
    public SipAudioCall call = null;
    public SipErrorCode sipcode;
    public SipException sipexeception;
    public static WalkieTalkieActivity walkiy;

    public static WalkieTalkieActivity getInstance() {
        if (walkiy == null) {
            walkiy = new WalkieTalkieActivity();
        }
        return walkiy;
    }

    @
    Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        Log.e("onCreate", "onCreate");
        initializeManager(this);
    }

    @
    Override
    public void onStart() {
        super.onStart();
        // When we get back from the preference setting Activity, assume
        // settings have changed, and re-login with new auth info.
    }

    @
    Override
    public void onDestroy() {

        super.onDestroy();
        if (call != null) {
            call.close();
        }
        closeLocalProfile();
    }

    @
    Override
    protected void onResume() {
        initializeManager(this);
        super.onResume();
    }

    public void initializeManager(Context ctx) {

        Log.e("inilitize", "initialize manager");

        if (manager == null) {
            manager = SipManager.newInstance(ctx);

        }
        initializeLocalProfile(ctx);
    }

    /**
     * Logs you into your SIP provider, registering this device as the location to
     * send SIP calls to for your SIP address.
     */
    public void initializeLocalProfile(final Context ctx) {
        Log.e("inilitize", "initialize profile");
        if (manager == null) {

            Log.e("inilitize", "return in profile");
            updateStatus("we are unable to establish this feature on your device ", ctx);
            Log.e("Wifi state", "" + SipManager.isSipWifiOnly(ctx));
            return;
        }
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
        String username = prefs.getString("namePref", "XYZ");
        String domain = prefs.getString("domainPref", "236.343.230.2");
        String password = prefs.getString("passPref", "XYZ");

        try {
            Log.e("inilitize", "building profile ");
            SipProfile.Builder builder = new SipProfile.Builder(username, domain);
            builder.setPassword(password);
            me = builder.build();
            manager.open(me);

            Log.e("alredy registered1", "" + manager.isRegistered(me.getUriString()));
            try {
                if (manager.isRegistered(me.getUriString())) {

                    Log.e("alredy registered2", "" + manager.isRegistered(me.getUriString()));
                    updateStatus("Ready", ctx);
                    return;
                }

            } catch (SipException e) {
                // TODO Auto-generated catch block
                closeLocalProfile();
                e.printStackTrace();
            }

            manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
                public void onRegistering(String localProfileUri) {

                    Log.e("Sip restration", "Registering with SIP Server..." + me.getUriString());
                    updateStatus("Registering with SIP Server...", ctx);
                }

                public void onRegistrationDone(String localProfileUri, long expiryTime) {
                    Log.e("Sip restration", "Ready");
                    updateStatus("Ready", ctx);

                }

                public void onRegistrationFailed(String localProfileUri, int errorCode,
                    String errorMessage) {
                    Log.e("Error Code Registration ", SipErrorCode.toString(errorCode) + " " + errorCode);
                    updateStatus(SipErrorCode.toString(errorCode), ctx);
                }
            });
        } catch (ParseException pe) {
            updateStatus("Connection Error.", ctx);
        } catch (SipException se) {
            updateStatus("Connection error.", ctx);
        }
    }

    /**
     * Closes out your local profile, freeing associated objects into memory
     * and unregistering your device from the server.
     */
    public void closeLocalProfile() {
        if (manager == null) {
            return;
        }
        try {
            if (me != null) {
                manager.unregister(me, new SipRegistrationListener() {

                    @
                    Override
                    public void onRegistrationFailed(String localProfileUri, int errorCode,
                        String errorMessage) {
                        // TODO Auto-generated method stub
                        Log.e("unregister failed", "unregister failed");

                    }

                    @
                    Override
                    public void onRegistrationDone(String localProfileUri, long expiryTime) {
                        // TODO Auto-generated method stub
                        Log.e("unregister done", "unregister done");
                    }

                    @
                    Override
                    public void onRegistering(String localProfileUri) {
                        // TODO Auto-generated method stub
                        Log.e("unregistering", "unregistering");
                    }
                });
                manager.close(me.getUriString());
            }
        } catch (Exception ee) {
            Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
        }
    }

    /**
     * Make an outgoing call.
     */
    public void initiateCall(String number, final Context ctx, final View v) {


        Log.d("Number", "" + number);
        sipAddress = number;

        Log.e("initiating call", "initiating call");
        try {



            SipAudioCall.Listener listener = new SipAudioCall.Listener() {@
                Override
                public void onCallBusy(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("buzy", "buzy");
                    super.onCallBusy(call);
                }

                @
                Override
                public void onCallHeld(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("held", "held");
                    super.onCallHeld(call);
                }

                @
                Override
                public void onCalling(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("calling", "calling");
                    super.onCalling(call);
                }

                @
                Override
                public void onChanged(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("changed", "changed");
                    super.onChanged(call);
                }

                @
                Override
                public void onError(SipAudioCall call, int errorCode,
                    String errorMessage) {
                    // TODO Auto-generated method stub

                    Log.e("call error", "error" + SipErrorCode.toString(errorCode) + " " + errorCode);
                    CallingScreen.fa.finish();
                    super.onError(call, errorCode, errorMessage);
                }

                @
                Override
                public void onReadyToCall(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("ready to call", "ready to call ");
                    super.onReadyToCall(call);
                }

                @
                Override
                public void onRinging(SipAudioCall call, SipProfile caller) {
                    // TODO Auto-generated method stub
                    Log.e("ringing", "ringing");

                    super.onRinging(call, caller);
                }

                @
                Override
                public void onRingingBack(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("ringing back", "ringing back");

                    super.onRingingBack(call);
                }

                // 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) {

                    Log.e("call established", "call established");
                    call.startAudio();
                    updateTime(true, ctx);
                }

                @
                Override
                public void onCallEnded(SipAudioCall call) {
                    Log.e("call ended", "call ended");

                    updateTime(false, ctx);
                    CallingScreen.fa.finish();
                }
            };

            Log.e("param 1 ", "" + me.getUriString());
            call = manager.makeAudioCall(me.getUriString(), sipAddress + "@216.245.200.2:5060", listener, 30);
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);
            if (me != null) {
                try {
                    closeLocalProfile();
                } catch (Exception ee) {
                    ee.printStackTrace();
                    Log.i("WalkieTalkieActivity/InitiateCall",
                        "Error when trying to close manager.", ee);
                    ee.printStackTrace();
                }
            }
            if (call != null) {
                call.close();
            }
        }
    }


    public void updateStatus(final String status, final Context context) {
        // Be a good citizen.  Make sure UI changes fire on the UI thread.
        this.runOnUiThread(new Runnable() {
            public void run() {
                generateNotification(context, status);

            }
        });
    }

    public void updateTime(final Boolean status, final Context context) {
        // Be a good citizen.  Make sure UI changes fire on the UI thread.
        this.runOnUiThread(new Runnable() {
            public void run() {

                if (status) {
                    CallingScreen.fa.calling_screen_text.setVisibility(View.GONE);
                    CallingScreen.fa.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

SIP is a transaction based protocol, this means, every negotiation process is a transaction (e.g. a basic registration process would imply sending a REISTER request and receive 200 OK response). I posted a small example in this response.

IN_PROGRESS error initially indicates that you tried to start a new transaction, in your scenario you're trying to send a REGISTER request, when client is already in another related one.

A quite typical scenario is, in a fast logout/login, trying to register when unregistration process is still running (no 200 OK final response has been received).

Main problem regarding Android's SIP implementation and this error code is that it's used when as generic error when processing a SIP request fails so, previous meaning loses its significance.

Because of previous problem you would need to check logcat to get more information (you should see something like "~~~~~ SipSessionGroup:: processing ") but, best way to handle this, would be working with different listeners provided by the stack.

The stack provides two listeners that can get registration errors: SipRegistrationListener and SipSession.Listener. Both provides onRegistrationFailed callback but, later one, also provides onRegistrationTimeout, that can be quite helpful. Actually, you already used SipRegistrationListener in your code but I don't really get why you say that it should be set after open because open would try to automatically register and, if some error occurs, you won't be notified.

On the other hand, main problem with this listeners is that registration can fail because of several reason (you can check a list of different error responses here) and current implementation only notifies of error codes >= 500 (those are server and global failures) but not others like quite common 406. This is, in my opinion, an important bug in this stack.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...