Android 5.0 呼叫流程--SIP呼出

原创 2015年04月22日 20:39:37

 

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协议栈的流程和内容。

 

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

SIP呼叫流程典型流程图解及其详细解释

1.注册流程:... 12.注销流程:... 33.基本呼叫建立过程:... 44.会话更改流程:... 55.正常呼叫释放过程:... 66.被叫忙呼叫释放:... 77.被叫无应答流程一:... ...
  • braveyly
  • braveyly
  • 2011年05月14日 20:55
  • 34509

SIP呼叫流程典型流程图解及其详细解释 .

[+] 注册流程注销流程基本呼叫建立过程会话更改流程正常呼叫释放过程被叫忙呼叫释放被叫无应答流程一被叫无应答流程二遇忙呼叫前转无应答呼叫前转流程呼叫保持呼叫等等 1.注册流程:... 1 2.注销...
  • dxpqxb
  • dxpqxb
  • 2014年01月23日 17:10
  • 5024

几款sip phone整理

因为要做个跟sip phone相关又跟TTS扯点关系的东西;忙活了3周了初步拿着源码可以拨电话放个录音了,因此把些东西整理下。因为要求是使用Java,当然最初定的是jain-sip sip-servl...
  • w7849516230
  • w7849516230
  • 2012年06月15日 16:28
  • 10037

个人推荐的SIP software Phone

开源免费的LinPhone,国内很多人基于他继续二次开发http://www.linphone.org/Zoiper 有免费的,有收费的,有SDK,支持SIP/IAX(没有NAT问题)官方下载的免费版...
  • berryreload
  • berryreload
  • 2012年11月10日 20:27
  • 5558

Android 5.0 呼叫流程--呼出

11 5.       Android 5.0 呼叫流程 5.1         MO call 我们先给出MO起呼过程的示例流程图,然后结合该图做代码流程的分析: 5.1.1   拨号请求(C...
  • xiashaohua
  • xiashaohua
  • 2014年12月01日 22:30
  • 7502

SIP phone开源代码(linphone)

  • 2012年07月11日 13:35
  • 7.95MB
  • 下载

[Linphone Android]Linphone介绍

Linphone是一款基于标准SIP的开源VoIP电话工具,它能够让你通过internet来查询朋友的IP,并通过IP给他打电话的软件,功能非常强大,既支持桌面系统,也支持移动终端,还能支持WEB浏览...
  • Kandy_Ye
  • Kandy_Ye
  • 2016年01月10日 11:42
  • 5126

Android 开发 voip/sip 程序

首先说明一下相关概念,voip 和Sip ,voip 的意思是网络电话,会话发起协议(SIP)是建立VOIP连接的IETF标准。SIP是一种应用层控制协议,用于和一个或多个参与者创建、修改和终止会话。...
  • huang_rong12
  • huang_rong12
  • 2016年04月26日 17:30
  • 7311

SIP 中的Dialog,call,session 和 transaction

如果你对Sip协议中Call, Dialog, Transaction和Message之间的关系感觉到迷惑,那么,那么我可以告诉你,你并不孤单,因为大多数初学者对于这些名词之间的关系都会感到疑惑. ...
  • wind19
  • wind19
  • 2012年04月03日 13:04
  • 14194

android sip通话实现流程分析

sip协议的核心是SipService,它的注册与一般服务的注册不同,绝大多数Service都是之间在SysetmServer中进行注册,而SipService是在TeleService apk中注册...
  • zhanxiaoqi
  • zhanxiaoqi
  • 2017年03月29日 16:03
  • 1910
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 5.0 呼叫流程--SIP呼出
举报原因:
原因补充:

(最多只允许输入30个字)