简介:
VoLTE是基于IMS的语音业务,它是一种IP数据,就是我们熟知的高清语音通话。
第一部分 拨出流程(MO)
IMS通话流程可以在GSM的通话流程的基础上进行研究,整体流程都差不多,就是在一些关键点上进行判断,IMS通话和GSM通话判断主要在GsmCdmaPhone类中;
@Override
public Connection dial(String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras) throws CallStateException {
if (!isPhoneTypeGsm() && uusInfo != null) {
throw new CallStateException("Sending UUS information NOT supported in CDMA!");
}
boolean isEmergency = PhoneNumberUtils.isEmergencyNumber(getSubId(), dialString);
Phone imsPhone = mImsPhone;
CarrierConfigManager configManager =
(CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
boolean alwaysTryImsForEmergencyCarrierConfig = configManager.getConfigForSubId(getSubId())
.getBoolean(CarrierConfigManager.KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL);
boolean imsUseEnabled = isImsUseEnabled()
&& imsPhone != null
&& (imsPhone.isVolteEnabled() || imsPhone.isWifiCallingEnabled() ||
(imsPhone.isVideoEnabled() && VideoProfile.isVideo(videoState)))
&& (imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE);
boolean useImsForEmergency = imsPhone != null
&& isEmergency
&& alwaysTryImsForEmergencyCarrierConfig
&& ImsManager.isNonTtyOrTtyOnVolteEnabled(mContext)
&& imsPhone.isImsAvailable();
String dialPart = PhoneNumberUtils.extractNetworkPortionAlt(PhoneNumberUtils.
stripSeparators(dialString));
boolean isUt = (dialPart.startsWith("*") || dialPart.startsWith("#"))
&& dialPart.endsWith("#");
boolean useImsForUt = imsPhone != null && imsPhone.isUtEnabled();
Phone.checkWfcWifiOnlyModeBeforeDial(mImsPhone, mContext);
if ((imsUseEnabled && (!isUt || useImsForUt)) || useImsForEmergency) {
try {
return imsPhone.dial(dialString, uusInfo, videoState, intentExtras);
} catch (CallStateException e) {
// Do not throw a CallStateException and instead fall back to Circuit switch
// for emergency calls and MMI codes.
if (Phone.CS_FALLBACK.equals(e.getMessage()) || isEmergency) {
logi("IMS call failed with Exception: " + e.getMessage() + ". Falling back "
+ "to CS.");
} else {
CallStateException ce = new CallStateException(e.getMessage());
ce.setStackTrace(e.getStackTrace());
throw ce;
}
}
}
if (mSST != null && mSST.mSS.getState() == ServiceState.STATE_OUT_OF_SERVICE
&& mSST.mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE && !isEmergency) {
throw new CallStateException("cannot dial in current state");
}
// Check non-emergency voice CS call - shouldn't dial when POWER_OFF
if (mSST != null && mSST.mSS.getState() == ServiceState.STATE_POWER_OFF /* CS POWER_OFF */
&& !VideoProfile.isVideo(videoState) /* voice call */
&& !isEmergency /* non-emergency call */) {
throw new CallStateException(
CallStateException.ERROR_POWER_OFF,
"cannot dial voice call in airplane mode");
}
// Check for service before placing non emergency CS voice call.
// Allow dial only if either CS is camped on any RAT (or) PS is in LTE service.
if (mSST != null
&& mSST.mSS.getState() == ServiceState.STATE_OUT_OF_SERVICE /* CS out of service */
&& !(mSST.mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
&& ServiceState.isLte(mSST.mSS.getRilDataRadioTechnology())) /* PS not in LTE */
&& !VideoProfile.isVideo(videoState) /* voice call */
&& !isEmergency /* non-emergency call */) {
throw new CallStateException(
CallStateException.ERROR_OUT_OF_SERVICE,
"cannot dial voice call in out of service");
}
if (DBG) logd("Trying (non-IMS) CS call");
if (isPhoneTypeGsm()) {
return dialInternal(dialString, null, VideoProfile.STATE_AUDIO_ONLY, intentExtras);
} else {
return dialInternal(dialString, null, videoState, intentExtras);
}
第二部分 MT流程
4. About AT command for IMS call:
1> Hangup connection: AT+CHLD = 1x ? x = call id
2> Hangup all: AT+CHLD=6
3> Hangup waiting or background: AT+CHLD=0
4> Force release : AT+ECHUP=x
5> Answer : ATA
6> Hold call: AT+ECCTRL=x,131 ? x = call id
7> Resume call: AT+ECCTRL=x,132 ? x = call id
8> Call indication : AT+EAIC=mode,callId,seqNumber
9> Request conference (normal merge normal): AT+CHLD=3
10> Request conference (normal merge conference):
AT+ECONF=conference_call_id, ”x”, normal_call_id ? x = 0(add),(remove)
11> Dial : ATD/ATDE
12> Request DTMF : AT+EVTS=0, “c”, AT+EVTS=1 ? c = 0~9, #, *
MT流程解析: