4.2.1.5.0 SIP呼叫MO流程java
SIP MO呼叫流程以下图所示(为了便于看清,分两段截图):android
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协议栈的流程和内容。