Android 5.0 呼叫流程--SIP呼出

来源:互联网 发布:php sae环境 编辑:程序博客网 时间:2024/06/01 19:33

 

4.2.1.  5.0 SIP呼叫MO流程

 

SIP MO呼叫流程如下图所示(为了便于看清,分两段截图):

 

 

 

3.6.2.1.    SIP呼叫App层处理流程

 

SIP呼叫在App层的处理流程和普通呼叫流程一样,只是号码uri的参数scheme不一样。

 

 

3.6.2.2.    SIP呼叫telecom层处理流程

 

在telecom层,SIP呼叫和普通呼叫不同的地方开始于ConnectionService。

 

在ConnectionService服务端,onCreateOutgoingConnection会被调用到,这个方法被SipConnectionService重写,TelephonyConnectionService是ConnectionService的子类和最终要实例化的类,所以ConnectionService实例的onCreateOutgoingConnection方法在TelephonyConnectionService执行,这个方法代码较多,最终它会调用 placeOutgoingConnection(),需要注意的是其中的phone实例的获取,对于普通的呼叫,其实例是GSMPhone或CDMAPhone,对于IMS呼叫,其实例是IMSPhone,这会决定到后面的调用流程,关于Phone实例的获取,有兴趣可以自行研究。

    public Connection onCreateOutgoingConnection(

            PhoneAccountHandle connectionManagerPhoneAccount,

            final ConnectionRequest request) {

        final Phone phone = getPhoneForAccount(request.getAccountHandle(), isEmergencyNumber);

        final TelephonyConnection connection =

                createConnectionFor(phone, null, true /* isOutgoing */);

            placeOutgoingConnection(connection, phone, request);

}

 

 

在ConnectionService端,onCreateOutgoingConnection会被调用到,这个方法被SipConnectionService重写,SipConnectionService是ConnectionService的子类和最终要实例化的类,所以ConnectionService实例的onCreateOutgoingConnection方法在SipConnectionService执行,这个方法里会创建一个SipConnection实例,再调用 createConnectionForProfile(),

 

createConnectionForProfile则获取到SipPhone实例,然后调用startCallWithPhone,startCallWithPhone代码如下,它通过Phone.dial进行拨号,并返回一个com.android.internal.telephony.Connection类型的连接,

    private void placeOutgoingConnection(

            TelephonyConnection connection, Phone phone, ConnectionRequest request) {…

            originalConnection = phone.dial(number, request.getVideoState());

        if (originalConnection == null) {…

        } else {

            connection.setOriginalConnection(originalConnection);

        }

    }

 

 

3.6.2.3.    SIP呼叫流程SipPhone层

 

SipPhone.dail设置当前状态为DIALING,调用SipManager.makeAudioCall进行呼叫,并设置监听器,

        void dial() throws SipException {

            setState(Call.State.DIALING);

            mSipAudioCall = mSipManager.makeAudioCall(mProfile, mPeer, null,

                    TIMEOUT_MAKE_CALL);

            mSipAudioCall.setListener(mAdapter);

        }

 

 

SipManager的makeAudioCall则新建一个SipAudioCall实例,同时创建一个SipSession实例,并使用SipAudioCall.makeCall进行呼叫,

    public SipAudioCall makeAudioCall(SipProfile localProfile,

            SipProfile peerProfile, SipAudioCall.Listener listener, int timeout)

            throws SipException {

        if (!isVoipSupported(mContext)) {

            throw new SipException("VOIP API is not supported");

        }

        SipAudioCall call = new SipAudioCall(mContext, localProfile);

        call.setListener(listener);

        SipSession s = createSipSession(localProfile, null);

        call.makeCall(peerProfile, s, timeout);

        return call;

    }

后者会调用sipSession.makeCall,这里的处理方式和IMS呼叫比较相似。

 

 

3.6.2.4.    SIP呼叫流程Sip接口层

 

SipSession.makeCall则使用了一个AIDL接口ISipSession,ISipSession接口的实现是在SipSessionGroup.java,(frameworks\opt\net\voip\src\java \com\android\server\sip),

class SipSessionGroup implements SipListener {

class SipSessionImpl extends ISipSession.Stub {

        public void makeCall(SipProfile peerProfile, String sessionDescription,

                int timeout) {

            doCommandAsync(new MakeCallCommand(peerProfile, sessionDescription,

                    timeout));

        }

…}

}

这里调用doCommandAsync,进而启动一个线程,执行processCommand,再到process,根据SipSession.State,我们选择READY_TO_CALL,

        public boolean process(EventObject evt) throws SipException {

                switch (mState) {

                case SipSession.State.REGISTERING:

                case SipSession.State.DEREGISTERING:

                    processed = registeringToReady(evt);

                    break;

                case SipSession.State.READY_TO_CALL:

                    processed = readyForCall(evt);

                    break;

                case SipSession.State.INCOMING_CALL:

                    processed = incomingCall(evt);

                    break;

                case SipSession.State.INCOMING_CALL_ANSWERING:

                    processed = incomingCallToInCall(evt);

                    break;

                case SipSession.State.OUTGOING_CALL:

                case SipSession.State.OUTGOING_CALL_RING_BACK:

                    processed = outgoingCall(evt);

                    break;

                case SipSession.State.OUTGOING_CALL_CANCELING:

                    processed = outgoingCallToReady(evt);

                    break;

                case SipSession.State.IN_CALL:

                    processed = inCall(evt);

                    break;

                case SipSession.State.ENDING_CALL:

                    processed = endingCall(evt);

                    break;

                default:

                    processed = false;

                }

                return (processed || processExceptions(evt));

            }

        }

}

 

在readyForCall()方法里面,根据事件类型是MakeCallCommand,我们判断执行的代码如下,主要是使用mSipHelper.sendInvite向SIP协议栈发起呼叫请求,再进行本地会话管理,最后通过监听器通知状态变化。

        private boolean readyForCall(EventObject evt) throws SipException {

            // expect MakeCallCommand, RegisterCommand, DEREGISTER

            if (evt instanceof MakeCallCommand) {

                mState = SipSession.State.OUTGOING_CALL;

                MakeCallCommand cmd = (MakeCallCommand) evt;

                mPeerProfile = cmd.getPeerProfile();

                if (mReferSession != null) {

                    mSipHelper.sendReferNotify(mReferSession.mDialog,

                            getResponseString(Response.TRYING));

                }

                mClientTransaction = mSipHelper.sendInvite(

                        mLocalProfile, mPeerProfile, cmd.getSessionDescription(),

                        generateTag(), mReferredBy, mReplaces);

                mDialog = mClientTransaction.getDialog();

                addSipSession(this);

                startSessionTimer(cmd.getTimeout());

                mProxy.onCalling(this);

                return true;

            }

 

后续就是sip协议栈的响应处理,有兴趣可以研究sip协议栈的流程和内容。

 

 

 

0 0
原创粉丝点击