android 5.0 呼叫流程--呼出,Android 5.0 呼叫流程--SIP呼出

4.2.1.5.0 SIP呼叫MO流程java

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

a98328b87f4c48d3b44670f231eaa59a.gif

a98328b87f4c48d3b44670f231eaa59a.gif

3.6.2.1.SIP呼叫App层处理流程session

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

3.6.2.2.SIP呼叫telecom层处理流程this

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

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

public Connection onCreateOutgoingConnection(server

PhoneAccountHandle connectionManagerPhoneAccount,blog

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值