IMS2注册过查看商标是否被注册吗?还有哪些分类可以注册?

之前在中已经分析了ims代码的构成和重点类的初始化,接下来以启用VOLTE子功能为例,具体分析AP侧IMS服务的注册过程。
IMS注册前提是系统启用了volte或wifi calling等功能,Volte开关一般在网络设置界面会提供(如下图),用户切换开关状态将触发ims的注册或注销。
启用Volte后的消息传递序列(这里时序图避免复杂化,只表现消息的正向传递,忽略消息的返回)
Created with Rapha?l 2.1.0frameworkframeworkims appims apprild imsrild imsvolte_imsmvolte_imsmrildrildTurn on IMS feature打开IMS子功能RIL_REQUEST_SET_VOLTE_ENABLERIL_REQUEST_SET_IMS_VOICE_ENABLERIL_REQUEST_SET_IMS_ENABLERIL_UNSOL_IMS_ENABLE_STARTIMS_SERVICE_UPMSG_ID_IMS_ENABLE_INDMSG_ID_WRAP_IMSM_IMSPA_PDN_ACT_REQRequest Network建立IMS承载SETUP_DATA_CALL(ims apn)MSG_ID_WRAP_IMSPA_IMSM_PDN_ACT_ACK_RESP成功建立承载RIL_UNSOL_IMS_REGISTRATION_INFO上报IMS注册状态
整个过程大致分为3步:
1. 设置并启用ims
2. 建立ims承载
3. 注册ims服务
接下来结合代码详细分析。
IMS注册过程
从界面启用ims
此过程会向rild-ims下发3个消息,通知rild需要打开哪些ims业务,然后开启ims服务:
RIL_REQUEST_SET_VOLTE_ENABLE
RIL_REQUEST_SET_IMS_VOICE_ENABLE
RIL_REQUEST_SET_IMS_ENABLE
这里就从用户打开界面开关开始分析。
ImsManager::setAdvanced4GMode方法为volte功能的开关,设置界面即通过此接口实现volte开关。
1. 向ImsConfig设置了feature(ImsConfig::setFeatureValue)
2. 打开ims (turnOnIms)。
private void setAdvanced4GMode(boolean turnOn) throws ImsException {
checkAndThrowExceptionIfServiceUnavailable();
ImsConfig config = getConfigInterface();
if (config != null) {
config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, null);
} catch (ImsException e) {
if (turnOn) {
turnOnIms();
} else if (isImsTurnOffAllowed()) {
turnOffIms();
ImsConfig::setFeatureValue 作用是告诉ril目前要启用ims的哪些功能.
当前讨论的例子是打开volte,因此参数为”FEATURE_TYPE_VOICE_OVER_LTE”。
其他业务的定义在ImsConfig.java中:
public static class FeatureConstants {
public static final int FEATURE_TYPE_UNKNOWN = -1;
* FEATURE_TYPE_VOLTE supports features defined in 3GPP and
* GSMA IR.92 over LTE.
public static final int FEATURE_TYPE_VOICE_OVER_LTE = 0;
* FEATURE_TYPE_LVC supports features defined in 3GPP and
* GSMA IR.94 over LTE.
public static final int FEATURE_TYPE_VIDEO_OVER_LTE = 1;
* FEATURE_TYPE_VOICE_OVER_WIFI supports features defined in 3GPP and
* GSMA IR.92 over WiFi.
public static final int FEATURE_TYPE_VOICE_OVER_WIFI = 2;
* FEATURE_TYPE_VIDEO_OVER_WIFI supports features defined in 3GPP and
* GSMA IR.94 over WiFi.
public static final int FEATURE_TYPE_VIDEO_OVER_WIFI = 3;
ImsConfig实际上是ims app/ImsConfigImpl的代理,setFeatureValue方法具体逻辑在ImsConfigImpl中。
这里传入的feature为FEATURE_TYPE_VOICE_OVER_LTE,因此会向rild-ims下发2个消息:RIL_REQUEST_SET_VOLTE_ENABLE及RIL_REQUEST_SET_IMS_VOICE_ENABLE。
//ImsConfigImpl.java
public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener) {
//将设置值保存到数据库
mStorage.setFeatureValue(feature, network, value);
//不同的feature需要不同的设置,这里只分析volte的处理
switch(feature) {
case ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE:
case ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI:
case ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI:
case ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE:
int oldVoLTEValue = SystemProperties.getInt(PROPERTY_VOLTE_ENALBE, 0);
int wfcEnable = SystemProperties.getInt(PROPERTY_WFC_ENALBE, 0);
if (value != oldVoLTEValue) {
if (value == ImsConfig.FeatureValueConstants.ON) {
//设置property
SystemProperties.set(PROPERTY_VOLTE_ENALBE,"1");
//向rild-ims下发RIL_REQUEST_SET_VOLTE_ENABLE
mRilAdapter.turnOnVolte(null);
if (wfcEnable == 0){
//向rild-ims下发RIL_REQUEST_SET_IMS_VOICE_ENABLE
mRilAdapter.turnOnImsVoice(null);
} else {//关闭
SystemProperties.set(PROPERTY_VOLTE_ENALBE,"0");
mRilAdapter.turnOffVolte(null);
if (wfcEnable == 0){
mRilAdapter.turnOffImsVoice(null);
} catch (ImsException e) {
} catch (RemoteException e) {
throw new RuntimeException(e);
ImsConfig处理完成,继续执行ImsManager::turnOnIms,这同样是aidl调用,实际操作由ImsService.turnOnIms执行。
private void turnOnIms() throws ImsException {
checkAndThrowExceptionIfServiceUnavailable();
mImsService.turnOnIms(mPhoneId);
} catch (RemoteException e) {
throw new ImsException("turnOnIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
turnOnIms同样是向rild-ims下发消息:RIL_REQUEST_SET_IMS_ENABLE。
public void turnOnIms(int phoneId) {
if (mActivePhoneId != phoneId) {
mActivePhoneId = phoneId;
if (mImsState != PhoneConstants.IMS_STATE_ENABLE) {
mImsRILAdapter.turnOnIms(mHandler.obtainMessage(EVENT_SET_IMS_ENABLED_DONE));
mImsState = PhoneConstants.IMS_STATE_ENABLING;
下发了这3条消息后,等待ImsRilAdapter上报RIL_UNSOL_IMS_ENABLE_START来确认IMS服务已经启用。
ImsService在构造方法中注册了RIL_UNSOL_IMS_ENABLE_START消息的监听,消息上报后便会由它处理。
mImsRILAdapter.registerForImsEnableStart(mHandler, EVENT_IMS_ENABLING_URC, null);
ImsService中对RIL_UNSOL_IMS_ENABLE_START的处理如下:
1. 发送ACTION_IMS_SERVICE_UP广播;
2. 调用enableImsAdapter()
case EVENT_IMS_ENABLING_URC:
if (mActivePhoneId != phoneId) {
mActivePhoneId = phoneId;
intent = new Intent(ImsManager.ACTION_IMS_SERVICE_UP);
intent.putExtra(ImsManager.EXTRA_PHONE_ID, mActivePhoneId);
mContext.sendBroadcast(intent);
enableImsAdapter();
mImsState = PhoneConstants.IMS_STATE_ENABLE;
在中提到过,ACTION_IMS_SERVICE_UP会触发ImsPhone和相关telephony类的初始化,因此这里跳过。
而ImsAdatper的流程涉及到建立ims承载,在第二节中继续分析。
以流程图小结这部分:
建立IMS PDN连接
在ims注册之前,需要建立专用的数据连接。连接的建立由volte_imsm.so来触发,与普通数据连接一样,通过ConnectivityManager请求网络,并由telephony发起SETUP_DATA_CALL。
先了解下volte_imsm.so的作用。根据readme文件的描述,volte_imsm.so库用于建立承载,P-CSCF,鉴权等过程,MTK并没有开源:
IMS relay module, handling NAS bearer, P-CSCF address discovery, IMS AKA and relay message among IMCB/IMSA/MAL modules
handle the request from IMCB/IMSA/MAL module
Send the event to IMCB/IMSA/MAL module, and receive the Response
ims app负责与volte_imsm.so对接,一张图来表示相关的工作过程。
VaSocketIO运作在线程中,负责维护socket和输入输出,循环从socket中读取消息交由ImsEventDispatcher。
ImsEventDispatcher根据消息的类型分发给对应的VaEventDispatcher处理。
实现了VaEventDispatcher的类共有4个,分别负责:通话,数据,补充业务还有Timer(具体作用尚需研究)。
ImsAdapter负责控制功能的总开关。
大概清楚这块流程后,下面接着第一节的思路,继续分析ImsAdapter:enableImsAdapter()方法。
ImsAdapter.java
public void enableImsAdapter() {
synchronized (ImsEnabledThreadLock) {
if (!misImsAdapterEnabled) {
if (mIO.connectSocket() == true) {
mImsEventDispatcher.enableRequest();
misImsAdapterEnabled = true;
synchronized (mIO.VaSocketIOThreadLock) {
mIO.VaSocketIOThreadLock.notify();
enableImsStack();
sendMessageDelayed(
obtainMessage(MSG_IMSA_RETRY_IMS_ENABLE),
IMSA_RETRY_SOCKET_TIME);
DataDispatcher负责建立承载相关处理,直接看DataDispatcher.enableRequest()方法的处理:
注册DATA_CONNECTION_STATE_CHANGED和SIM_STATE_CHANGED的监听。监听这2个消息是为了维护ims的连接,响应Data和SIM卡的变动。
DataDispatcher.java
public void enableRequest() {
synchronized (mHandler) {
Arrays.fill(mSimStatus, false);
IntentFilter filter = new IntentFilter();
filter.addAction(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);
mIsEnable = true;
返回到ImsAdapter继续看enableImsStack()方法。从方法的命名上看,作用是启用ims栈,
向volte_imsm发送MSG_ID_IMS_ENABLE_IND消息:
private void enableImsStack() {
VaEvent event = new VaEvent(Util.getDefaultVoltePhoneId(), MSG_ID_IMS_ENABLE_IND);
mIO.writeEvent(event);
消息的定义如下:
int MSG_ID_IMS_ENABLE_IND = 900003;
int MSG_ID_IMS_DISABLE_IND = 900004;
从Log看,MSG_ID_WRAP_IMSPA_IMSM_ENABLE_IND消息的作用应该是初始化volte_imsm相关模块,VoLTE Stack/UA/REG等模块被初始化:
volte_imsm随后会上报MSG_ID_WRAP_IMSM_IMSPA_PDN_ACT_REQ,通知上层发起IMS PDN连接,消息由DataDispatcher处理。
消息分发到DataDispatcher::handleDefaultBearerActivationRequest方法:
将请求数据封装成TransactionParam,设置超时处理,最后调用requestNwRequest方法。这里能看到请求的apn类型是IMS。
DataDispatcher.java
private void handleDefaultBearerActivationRequest(VaEvent event) {
String apnType = PhoneConstants.APN_TYPE_IMS;
int phoneId = event.getPhoneId();
DataDispatcherUtil.PdnActivationInd actInd = mDataDispatcherUtil
.extractDefaultPdnActInd(event);
TransactionParam param = new TransactionParam(actInd.transactionId,
event.getRequestID(), phoneId, apnType);
putTransaction(param);
if (apnType == PhoneConstants.APN_TYPE_IMS) {
int subId = SubscriptionManager.getSubIdUsingPhoneId(phoneId);
if (mSimStatus[phoneId] || subId & 0) {
mSimStatus[phoneId] = true;
if (!isImsApnExists(phoneId)) {
rejectDefaultBearerDataConnActivation(param, FAILCAUSE_UNKNOWN, 500);
mHandler.removeMessages(MSG_ON_NOTIFY_ACTIVE_DATA_TIMEOUT);
mHandler.sendMessageDelayed(mHandler.obtainMessage(
MSG_ON_NOTIFY_ACTIVE_DATA_TIMEOUT, param),
MAX_NETWORK_ACTIVE_TIMEOUT_MS);
if (requestNwRequest(apnType, phoneId) & 0) {
rejectDefaultBearerDataConnActivation(param, FAILCAUSE_UNKNOWN, 0);
requestNwRequest方法实例化NetworkRequest并填充数据后,通过ConnectivityManager.requestNetwork发起连接请求。
private int requestNwRequest(String requestApnType, int phoneId) {
NetworkCallback nwCb = mDataNetworkRequests[pos].nwCb;
Builder builder = new NetworkRequest.Builder();
//IMS & EIMS
builder.addCapability(APN_CAP_LIST[pos]);
builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
//指定为当前subId
builder.setNetworkSpecifier(String.valueOf(subId));
mDataNetworkRequests[pos].nwRequest = builder.build();
NetworkRequest nwRequest = mDataNetworkRequests[pos].nwR
releaseNwRequest(requestApnType);
synchronized (mAPNStatuses) {
ApnStatus apnStatus = mAPNStatuses.get(requestApnType);
apnStatus.mName = requestApnT//IMS
apnStatus.mStatus = TelephonyManager.DATA_DISCONNECTED;
apnStatus.isSendReq =
apnStatus.ifaceName = "";
//发起request
getConnectivityManager().requestNetwork(nwRequest, nwCb,
ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS);
private static final int[] APN_CAP_LIST = new int[] {
NetworkCapabilities.NET_CAPABILITY_IMS,
NetworkCapabilities.NET_CAPABILITY_EIMS
接下来SETUP_DATA_CALL的工作由ConnectivityService和telephony数据模块完成。返回成功后,检查手机的网络接口发现新建了一个Interface——ccmni4
Link encap:Local Loopback
inet addr:127.0.0.1
Mask:255.0.0.0
inet6 addr: ::1/128 Scope: Host
UP LOOPBACK RUNNING
RX packets:46 errors:0 dropped:0 overruns:0 frame:0
TX packets:46 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3992 TX bytes:3992
Link encap:Ethernet
HWaddr 12:7A:92:06:07:BE
inet6 addr: 2409:8809:8590:da21:279:6506:7e0d:afdc/64 Scope: Global
inet6 addr: fe80::279:6506:7e0d:afdc/64 Scope: Link
UP RUNNING NOARP
RX packets:26 errors:0 dropped:0 overruns:0 frame:0
TX packets:29 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:17494 TX bytes:18434
ccmni4是mtk在底层指定的ims默认承载接口的名称,连接建立后DataDispatcher还需要检查这个Interface的名字是否正确,最后发送ACT消息通知volte_imsm连接已经建立
//DataDispatcher.java
private static final String IMS_INTERFACE_NAME = "ccmni4";
private void handleDefaultBearerActivationResponse(Network network, String type) {
TransactionParam deacTrans = findTransaction
(VaConstants.MSG_ID_WRAP_IMSM_IMSPA_PDN_DEACT_REQ, type);
synchronized (mAPNStatuses) {
ApnStatus apnStatus = mAPNStatuses.get(type);
if (deacTrans == null) {
apnStatus.mStatus = TelephonyManager.DATA_CONNECTED;
ConnectivityManager cm = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
LinkProperties mLink = cm.getLinkProperties(network);
apnStatus.ifaceName = mLink.getInterfaceName();
//检查iface名字是否为"ccmni4"
if (IMS_INTERFACE_NAME.equals(apnStatus.ifaceName)
|| EMERGENCY_INTERFACE_NAME.equals(apnStatus.ifaceName)) {
//发送MSG_ID_WRAP_IMSM_IMSPA_PDN_ACT_REQ通知volte_imsm
responseDefaultBearerDataConnActivated(
findTransaction(VaConstants.MSG_ID_WRAP_IMSM_IMSPA_PDN_ACT_REQ, type),
network.netId, apnStatus.ifaceName);
这部分的代码量较多,理解了设计意图后其实结构和流程都比较简单,同样以流程图总结:
注册IMS服务
IMS注册基于SIP,这部分由ims核心模块处理,需要分析协议和模块设计,这里先不作深入探讨。
注册成功后,返回200 OK。
rild_ims将注册状态及capability通过RIL_UNSOL_IMS_REGISTRATION_INFO消息上报:
ImsService在构造方法中注册过对RIL_UNSOL_IMS_REGISTRATION_INFO的监听,因此处理方法就在ImsService的handler中能找到。
mImsRILAdapter.registerForImsRegistrationInfo(mHandler, EVENT_IMS_REGISTRATION_INFO, null);
ImsService 处理:
从EVENT_IMS_REGISTRATION_INFO中读取到ims注册状态和Capability,并通知监听者。
private static final int IMS_VOICE_OVER_LTE = 1;
private static final int IMS_RCS_OVER_LTE = 2;
private static final int IMS_SMS_OVER_LTE = 4;
private static final int IMS_VIDEO_OVER_LTE = 8;
private static final int IMS_VOICE_OVER_WIFI = 16;
public void handleMessage(Message msg) {
int phoneId = getMainCapabilityPhoneId();
switch (msg.what) {
case EVENT_IMS_REGISTRATION_INFO:
ar = (AsyncResult) msg.
* According to 3GPP TS 27.007 +CIREGU format
* AsyncResult.result is an Object[]
* ((Object[])AsyncResult.result)[0] is integer type to indicate the IMS regiration status.
0: not registered
1: registered
* ((Object[])AsyncResult.result)[1] is numeric value in hexadecimal format to indicate the IMS capability.
1: RTP-based transfer of voice according to MMTEL (see 3GPP TS 24.173 [87])
2: RTP-based transfer of text according to MMTEL (see 3GPP TS 24.173 [87])
4: SMS using IMS functionality (see 3GPP TS 24.341[101])
8: RTP-based transfer of video according to MMTEL (see 3GPP TS 24.183 [87])
int socketId = ((int[]) ar.result)[2];
if (socketId != mActivePhoneId) {
int newImsRegInfo = ServiceState.STATE_POWER_OFF;
if (((int[]) ar.result)[0] == 1) {
newImsRegInfo = ServiceState.STATE_IN_SERVICE;
newImsRegInfo = ServiceState.STATE_OUT_OF_SERVICE;
int newImsExtInfo = ((int[]) ar.result)[1];
mImsRegInfo = newImsRegI
notifyRegistrationStateChange(mImsRegInfo);
if ((mImsRegInfo == ServiceState.STATE_IN_SERVICE)) {
mImsExtInfo = newImsExtI
mImsExtInfo = 0;
notifyRegistrationCapabilityChange(mImsExtInfo);
从LOG来看,此次CIREGU指令返回的结果是“1,5”,按照定义,1表示已注册,5代表同时支持IMS_VOICE_OVER_LTE和IMS_SMS_OVER_LTE,即语音和短信业务。
AT& +CIREGU: 1,5
注册状态的同步
ImsManager获得注册状态和capability后,回调ImsPhoneCallTracker中实例化的ImsConnectionStateListener,数据最终将传递到ImsPhone。
ImsPhone中有ServiceState实例来标记data和ims voice服务状态,并有布尔值mImsRegistered来标记ims注册情况。
private class ImsRegistrationListenerProxy extends IImsRegistrationListener.Stub {
private int mServiceC
private ImsConnectionStateListener mL
public ImsRegistrationListenerProxy(int serviceClass,
ImsConnectionStateListener listener) {
mServiceClass = serviceC
mListener =
public void registrationConnected() {
if (mListener != null) {
mListener.onImsConnected();
public void registrationProgressing() {
if (mListener != null) {
mListener.onImsProgressing();
public void registrationDisconnected(ImsReasonInfo imsReasonInfo) {
if (mListener != null) {
mListener.onImsDisconnected(imsReasonInfo);
public void registrationResumed() {
if (mListener != null) {
mListener.onImsResumed();
public void registrationSuspended() {
if (mListener != null) {
mListener.onImsSuspended();
public void registrationFeatureCapabilityChanged(int serviceClass,
int[] enabledFeatures, int[] disabledFeatures) {
if (mListener != null) {
mListener.onFeatureCapabilityChanged(serviceClass,
enabledFeatures, disabledFeatures);
ImsPhoneCallTracker如何处理注册信息和capability的上报:
1. 注册状态同步到ImsPhone;
2. Capability同步到mImsFeatureEnabled数组中,标记可用的ims业务;
3. 最后发出ACTION_IMS_STATE_CHANGED广播。
ImsPhoneCallTracker.java
* Listen to the IMS service state change
private ImsConnectionStateListener mImsConnectionStateListener =
new ImsConnectionStateListener() {
public void onImsConnected() {
mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
mPhone.setImsRegistered(true);
public void onImsDisconnected(ImsReasonInfo imsReasonInfo) {
mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
mPhone.setImsRegistered(false);
mPhone.processDisconnectReason(imsReasonInfo);
if (imsReasonInfo != null && imsReasonInfo.getExtraMessage() != null
&& !imsReasonInfo.getExtraMessage().equals("")) {
mImsRegistrationErrorCode = Integer.parseInt(imsReasonInfo.getExtraMessage());
public void onImsProgressing() {
public void onImsResumed() {
mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
public void onImsSuspended() {
mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
public void onFeatureCapabilityChanged(int serviceClass,
int[] enabledFeatures, int[] disabledFeatures) {
if (serviceClass == ImsServiceClass.MMTEL) {
boolean tmpIsVideoCallEnabled = isVideoCallEnabled();
i = ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE;
i &= ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI; i++) {
if (enabledFeatures[i] == i) {
mImsFeatureEnabled[i] = true;
} else if (enabledFeatures[i]
== ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
mImsFeatureEnabled[i] = false;
if (tmpIsVideoCallEnabled != isVideoCallEnabled()) {
mPhone.notifyForVideoCapabilityChanged(isVideoCallEnabled());
for (ImsPhoneConnection connection : mConnections) {
connection.updateWifiState();
mPhone.onFeatureCapabilityChanged();
broadcastImsStatusChange();
ImsPhone更新ServiceState的Log:
06-02 16:47:44.925 D/ImsPhone( 2170): updateDataServiceState:
defSs = 0 0 voice home data home 中国移动 中国移动 46000 中国移动 中国移动 46000
LTE LTE_CA CSS not supported 0 0 RoamInd=-1 DefRoamInd=-1 EmergOnly=false Ril Voice Regist state: 1 Ril Data Regist state: 1 mProprietaryDataRadioTechnology: 0 VoiceRejectCause: 0 DataRejectCause: -1 IsDataRoamingFromRegistration=false
imsSs = 0 0 voice home data home null null null null null null
Unknown LTE_CA CSS not supported -1 -1 RoamInd=-1 DefRoamInd=-1 EmergOnly=false Ril Voice Regist state: 0 Ril Data Regist state: 0 mProprietaryDataRadioTechnology: 0 VoiceRejectCause: -1 DataRejectCause: -1 IsDataRoamingFromRegistration=false
以上分析只分析了AP侧流程,相对于完整的ims注册过程来说并不完整,核心部分的协议及信令流程许多对上层来说是透明的,需要对这些部分深入了解后再做补充。
Android 7.0 IMS框架详解
本文主要讲解IP Multimedia Subsystem (IMS)在Android 7.0上由谷歌Android实现的部分内容。
从APP侧一直到Telephony Framework,是不区分...
IMS基本概念之 注册和呼叫发起
3. IMS中的一些概念3.1 概述本章以IP多媒体子系统(IMS)的注册和会话建立的初步介绍开始,并且描述了涉及到的IMS实体。目的不是去做全方位的解释,而是给读者以总体的认识,并有助于读者理解本章...
【VOLTE】VOLTE的注册和去注册过程
这里主要对信令流程做简要概述,不做逐条讲解
VOLTE注册过程分为两部分,一部分是LTE的注册/LTE承载建立过程,第二部分是VOLTE注册过程。在VOLTE中信令组合情况非常多,这里介...
MTK IMS框架简析(1)——代码架构及模块初始化
1.前言随着4G技术的诞生和国内运营商网络的全面升级,以往流量贵上网慢的问题不再有,而类似微信这类即时通讯软件也得到快速的普及,互联网行业的发展还延伸到金融/零售等线上线下的各行各业,短短几年内国内I...
Andorid6.0 ——
一:短信签名(在 vendor 下)
diff --git a/mediatek/proprietary/packages/apps/Mms/res/values-zh...
https://blog.csdn.net/wilschan0201/article/details/
http://www.miui.com/thread--1.html
https://blog.csdn.net/wilschan0201/article/details/
Terminology : 模块名称:
Maui[英]['maui][美]['ma?i]...google可知为夏威夷的小岛。
MAUI wap browser是mtk(联发科)的手机平台上的游览...
没有更多推荐了,之前在中已经分析了ims代码的构成和重点类的初始化,接下来以启用VOLTE子功能为例,具体分析AP侧IMS服务的注册过程。
IMS注册前提是系统启用了volte或wifi calling等功能,Volte开关一般在网络设置界面会提供(如下图),用户切换开关状态将触发ims的注册或注销。&
启用Volte后的消息传递序列(这里时序图避免复杂化,只表现消息的正向传递,忽略消息的返回)
frameworkframeworkims appims apprild imsrild imsvolte_imsmvolte_imsmrildrildTurn on IMS feature打开IMS子功能RIL_REQUEST_SET_VOLTE_ENABLERIL_REQUEST_SET_IMS_VOICE_ENABLERIL_REQUEST_SET_IMS_ENABLERIL_UNSOL_IMS_ENABLE_STARTIMS_SERVICE_UPMSG_ID_IMS_ENABLE_INDMSG_ID_WRAP_IMSM_IMSPA_PDN_ACT_REQRequest
Network建立IMS承载SETUP_DATA_CALL(ims apn)MSG_ID_WRAP_IMSPA_IMSM_PDN_ACT_ACK_RESP成功建立承载RIL_UNSOL_IMS_REGISTRATION_INFO上报IMS注册状态
整个过程大致分为3步:&
1. 设置并启用ims&
2. 建立ims承载&
3. 注册ims服务&
接下来结合代码详细分析。
IMS注册过程
从界面启用ims
此过程会向rild-ims下发3个消息,通知rild需要打开哪些ims业务,然后开启ims服务:
RIL_REQUEST_SET_VOLTE_ENABLE
RIL_REQUEST_SET_IMS_VOICE_ENABLE
RIL_REQUEST_SET_IMS_ENABLE12345
这里就从用户打开界面开关开始分析。&
ImsManager::setAdvanced4GMode方法为volte功能的开关,设置界面即通过此接口实现volte开关。&
1. 向ImsConfig设置了feature(ImsConfig::setFeatureValue)&
2. 打开ims (turnOnIms)。
private void setAdvanced4GMode(boolean turnOn) throws ImsException {
checkAndThrowExceptionIfServiceUnavailable();
ImsConfig config = getConfigInterface();
if (config != null) {
config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, null);
} catch (ImsException e) {
if (turnOn) {
turnOnIms();
} else if (isImsTurnOffAllowed()) {
turnOffIms();
}12345678910111213141516171819
ImsConfig::setFeatureValue 作用是告诉ril目前要启用ims的哪些功能.&
当前讨论的例子是打开volte,因此参数为”FEATURE_TYPE_VOICE_OVER_LTE”。&
其他业务的定义在ImsConfig.java中:
public static class FeatureConstants {
public static final int FEATURE_TYPE_UNKNOWN = -1;
* FEATURE_TYPE_VOLTE supports features defined in 3GPP and
* GSMA IR.92 over LTE.
public static final int FEATURE_TYPE_VOICE_OVER_LTE = 0;
* FEATURE_TYPE_LVC supports features defined in 3GPP and
* GSMA IR.94 over LTE.
public static final int FEATURE_TYPE_VIDEO_OVER_LTE = 1;
* FEATURE_TYPE_VOICE_OVER_WIFI supports features defined in 3GPP and
* GSMA IR.92 over WiFi.
public static final int FEATURE_TYPE_VOICE_OVER_WIFI = 2;
* FEATURE_TYPE_VIDEO_OVER_WIFI supports features defined in 3GPP and
* GSMA IR.94 over WiFi.
public static final int FEATURE_TYPE_VIDEO_OVER_WIFI = 3;
}12345678910111213141516171819202122232425262728
ImsConfig实际上是ims app/ImsConfigImpl的代理,setFeatureValue方法具体逻辑在ImsConfigImpl中。&
这里传入的feature为FEATURE_TYPE_VOICE_OVER_LTE,因此会向rild-ims下发2个消息:RIL_REQUEST_SET_VOLTE_ENABLE及RIL_REQUEST_SET_IMS_VOICE_ENABLE。
//ImsConfigImpl.java
public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener) {
//将设置值保存到数据库
mStorage.setFeatureValue(feature, network, value);
//不同的feature需要不同的设置,这里只分析volte的处理
switch(feature) {
case ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE:
case ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI:
case ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI:
case ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE:
int oldVoLTEValue = SystemProperties.getInt(PROPERTY_VOLTE_ENALBE, 0);
int wfcEnable = SystemProperties.getInt(PROPERTY_WFC_ENALBE, 0);
if (value != oldVoLTEValue) {
if (value == ImsConfig.FeatureValueConstants.ON) {
//设置property
SystemProperties.set(PROPERTY_VOLTE_ENALBE,&1&);
//向rild-ims下发RIL_REQUEST_SET_VOLTE_ENABLE
mRilAdapter.turnOnVolte(null);
if (wfcEnable == 0){
//向rild-ims下发RIL_REQUEST_SET_IMS_VOICE_ENABLE
mRilAdapter.turnOnImsVoice(null);
} else {//关闭
SystemProperties.set(PROPERTY_VOLTE_ENALBE,&0&);
mRilAdapter.turnOffVolte(null);
if (wfcEnable == 0){
mRilAdapter.turnOffImsVoice(null);
} catch (ImsException e) {
} catch (RemoteException e) {
throw new RuntimeException(e);
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
ImsConfig处理完成,继续执行ImsManager::turnOnIms,这同样是aidl调用,实际操作由ImsService.turnOnIms执行。
private void turnOnIms() throws ImsException {
checkAndThrowExceptionIfServiceUnavailable();
mImsService.turnOnIms(mPhoneId);
} catch (RemoteException e) {
throw new ImsException(&turnOnIms() &, e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
}12345678910
turnOnIms同样是向rild-ims下发消息:RIL_REQUEST_SET_IMS_ENABLE。
public void turnOnIms(int phoneId) {
if (mActivePhoneId != phoneId) {
mActivePhoneId = phoneId;
if (mImsState != PhoneConstants.IMS_STATE_ENABLE) {
mImsRILAdapter.turnOnIms(mHandler.obtainMessage(EVENT_SET_IMS_ENABLED_DONE));
mImsState = PhoneConstants.IMS_STATE_ENABLING;
}12345678910111213
下发了这3条消息后,等待ImsRilAdapter上报RIL_UNSOL_IMS_ENABLE_START来确认IMS服务已经启用。&
ImsService在构造方法中注册了RIL_UNSOL_IMS_ENABLE_START消息的监听,消息上报后便会由它处理。
mImsRILAdapter.registerForImsEnableStart(mHandler, EVENT_IMS_ENABLING_URC, null);12
ImsService中对RIL_UNSOL_IMS_ENABLE_START的处理如下:&
1. 发送ACTION_IMS_SERVICE_UP广播;&
2. 调用enableImsAdapter()
case EVENT_IMS_ENABLING_URC:
if (mActivePhoneId != phoneId) {
mActivePhoneId = phoneId;
intent = new Intent(ImsManager.ACTION_IMS_SERVICE_UP);
intent.putExtra(ImsManager.EXTRA_PHONE_ID, mActivePhoneId);
mContext.sendBroadcast(intent);
enableImsAdapter();
mImsState = PhoneConstants.IMS_STATE_ENABLE;
break;1234567891011121314
在中提到过,ACTION_IMS_SERVICE_UP会触发ImsPhone和相关telephony类的初始化,因此这里跳过。&
而ImsAdatper的流程涉及到建立ims承载,在第二节中继续分析。
以流程图小结这部分:&
建立IMS PDN连接
在ims注册之前,需要建立专用的数据连接。连接的建立由volte_imsm.so来触发,与普通数据连接一样,通过ConnectivityManager请求网络,并由telephony发起SETUP_DATA_CALL。
先了解下volte_imsm.so的作用。根据readme文件的描述,volte_imsm.so库用于建立承载,P-CSCF,鉴权等过程,MTK并没有开源:
IMS relay module, handling NAS bearer, P-CSCF address discovery, IMS AKA and relay message among IMCB/IMSA/MAL modules
handle the request from IMCB/IMSA/MAL module
Send the event to IMCB/IMSA/MAL module, and receive the Response1234567
ims app负责与volte_imsm.so对接,一张图来表示相关的工作过程。&
VaSocketIO运作在线程中,负责维护socket和输入输出,循环从socket中读取消息交由ImsEventDispatcher。&
ImsEventDispatcher根据消息的类型分发给对应的VaEventDispatcher处理。&
实现了VaEventDispatcher的类共有4个,分别负责:通话,数据,补充业务还有Timer(具体作用尚需研究)。&
ImsAdapter负责控制功能的总开关。
大概清楚这块流程后,下面接着第一节的思路,继续分析ImsAdapter:enableImsAdapter()方法。
ImsAdapter.java
public void enableImsAdapter() {
synchronized (ImsEnabledThreadLock) {
if (!misImsAdapterEnabled) {
if (mIO.connectSocket() == true) {
mImsEventDispatcher.enableRequest();
misImsAdapterEnabled = true;
synchronized (mIO.VaSocketIOThreadLock) {
mIO.VaSocketIOThreadLock.notify();
enableImsStack();
sendMessageDelayed(
obtainMessage(MSG_IMSA_RETRY_IMS_ENABLE),
IMSA_RETRY_SOCKET_TIME);
}123456789101112131415161718192021
DataDispatcher负责建立承载相关处理,直接看DataDispatcher.enableRequest()方法的处理:&
注册DATA_CONNECTION_STATE_CHANGED和SIM_STATE_CHANGED的监听。监听这2个消息是为了维护ims的连接,响应Data和SIM卡的变动。
DataDispatcher.java
public void enableRequest() {
synchronized (mHandler) {
Arrays.fill(mSimStatus, false);
IntentFilter filter = new IntentFilter();
filter.addAction(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);
mIsEnable = true;
}1234567891011
返回到ImsAdapter继续看enableImsStack()方法。从方法的命名上看,作用是启用ims栈,&
向volte_imsm发送MSG_ID_IMS_ENABLE_IND消息:
private void enableImsStack() {
VaEvent event = new VaEvent(Util.getDefaultVoltePhoneId(), MSG_ID_IMS_ENABLE_IND);
mIO.writeEvent(event);
消息的定义如下:
int MSG_ID_IMS_ENABLE_IND = 900003;
int MSG_ID_IMS_DISABLE_IND = 900004; 12
从Log看,MSG_ID_WRAP_IMSPA_IMSM_ENABLE_IND消息的作用应该是初始化volte_imsm相关模块,VoLTE Stack/UA/REG等模块被初始化:&
volte_imsm随后会上报MSG_ID_WRAP_IMSM_IMSPA_PDN_ACT_REQ,通知上层发起IMS PDN连接,消息由DataDispatcher处理。&
消息分发到DataDispatcher::handleDefaultBearerActivationRequest方法:&
将请求数据封装成TransactionParam,设置超时处理,最后调用requestNwRequest方法。这里能看到请求的apn类型是IMS。
DataDispatcher.java
private void handleDefaultBearerActivationRequest(VaEvent event) {
String apnType = PhoneConstants.APN_TYPE_IMS;
int phoneId = event.getPhoneId();
DataDispatcherUtil.PdnActivationInd actInd = mDataDispatcherUtil
.extractDefaultPdnActInd(event);
TransactionParam param = new TransactionParam(actInd.transactionId,
event.getRequestID(), phoneId, apnType);
putTransaction(param);
if (apnType == PhoneConstants.APN_TYPE_IMS) {
int subId = SubscriptionManager.getSubIdUsingPhoneId(phoneId);
if (mSimStatus[phoneId] || subId & 0) {
mSimStatus[phoneId] = true;
if (!isImsApnExists(phoneId)) {
rejectDefaultBearerDataConnActivation(param, FAILCAUSE_UNKNOWN, 500);
mHandler.removeMessages(MSG_ON_NOTIFY_ACTIVE_DATA_TIMEOUT);
mHandler.sendMessageDelayed(mHandler.obtainMessage(
MSG_ON_NOTIFY_ACTIVE_DATA_TIMEOUT, param),
MAX_NETWORK_ACTIVE_TIMEOUT_MS);
if (requestNwRequest(apnType, phoneId) & 0) {
rejectDefaultBearerDataConnActivation(param, FAILCAUSE_UNKNOWN, 0);
}1234567891011121314151617181920212223242526272829303132333435
requestNwRequest方法实例化NetworkRequest并填充数据后,通过ConnectivityManager.requestNetwork发起连接请求。
private int requestNwRequest(String requestApnType, int phoneId) {
NetworkCallback nwCb = mDataNetworkRequests[pos].nwCb;
Builder builder = new NetworkRequest.Builder();
//IMS & EIMS
builder.addCapability(APN_CAP_LIST[pos]);
builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
//指定为当前subId
builder.setNetworkSpecifier(String.valueOf(subId));
mDataNetworkRequests[pos].nwRequest = builder.build();
NetworkRequest nwRequest = mDataNetworkRequests[pos].nwR
releaseNwRequest(requestApnType);
synchronized (mAPNStatuses) {
ApnStatus apnStatus = mAPNStatuses.get(requestApnType);
apnStatus.mName = requestApnT//IMS
apnStatus.mStatus = TelephonyManager.DATA_DISCONNECTED;
apnStatus.isSendReq =
apnStatus.ifaceName = &&;
//发起request
getConnectivityManager().requestNetwork(nwRequest, nwCb,
ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS);
private static final int[] APN_CAP_LIST = new int[] {
NetworkCapabilities.NET_CAPABILITY_IMS,
NetworkCapabilities.NET_CAPABILITY_EIMS
};123456789101112131415161718192021222324252627282930
接下来SETUP_DATA_CALL的工作由ConnectivityService和telephony数据模块完成。返回成功后,检查手机的网络接口发现新建了一个Interface——ccmni4
Link encap:Local Loopback
inet addr:127.0.0.1
Mask:255.0.0.0
inet6 addr: ::1/128 Scope: Host
UP LOOPBACK RUNNING
RX packets:46 errors:0 dropped:0 overruns:0 frame:0
TX packets:46 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3992 TX bytes:3992
Link encap:Ethernet
HWaddr 12:7A:92:06:07:BE
inet6 addr: 2409:8809:8590:da21:279:6506:7e0d:afdc/64 Scope: Global
inet6 addr: fe80::279:6506:7e0d:afdc/64 Scope: Link
UP RUNNING NOARP
RX packets:26 errors:0 dropped:0 overruns:0 frame:0
TX packets:29 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:17494 TX bytes:18434
12345678910111213141516171819
ccmni4是mtk在底层指定的ims默认承载接口的名称,连接建立后DataDispatcher还需要检查这个Interface的名字是否正确,最后发送ACT消息通知volte_imsm连接已经建立
//DataDispatcher.java
private static final String IMS_INTERFACE_NAME = &ccmni4&;
private void handleDefaultBearerActivationResponse(Network network, String type) {
TransactionParam deacTrans = findTransaction
(VaConstants.MSG_ID_WRAP_IMSM_IMSPA_PDN_DEACT_REQ, type);
synchronized (mAPNStatuses) {
ApnStatus apnStatus = mAPNStatuses.get(type);
if (deacTrans == null) {
apnStatus.mStatus = TelephonyManager.DATA_CONNECTED;
ConnectivityManager cm = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
LinkProperties mLink = cm.getLinkProperties(network);
apnStatus.ifaceName = mLink.getInterfaceName();
//检查iface名字是否为&ccmni4&
if (IMS_INTERFACE_NAME.equals(apnStatus.ifaceName)
|| EMERGENCY_INTERFACE_NAME.equals(apnStatus.ifaceName)) {
//发送MSG_ID_WRAP_IMSM_IMSPA_PDN_ACT_REQ通知volte_imsm
responseDefaultBearerDataConnActivated(
findTransaction(VaConstants.MSG_ID_WRAP_IMSM_IMSPA_PDN_ACT_REQ, type),
network.netId, apnStatus.ifaceName);
}1234567891011121314151617181920212223242526272829
这部分的代码量较多,理解了设计意图后其实结构和流程都比较简单,同样以流程图总结:&
注册IMS服务
IMS注册基于SIP,这部分由ims核心模块处理,需要分析协议和模块设计,这里先不作深入探讨。&
注册成功后,返回200 OK。&
rild_ims将注册状态及capability通过RIL_UNSOL_IMS_REGISTRATION_INFO消息上报:&
ImsService在构造方法中注册过对RIL_UNSOL_IMS_REGISTRATION_INFO的监听,因此处理方法就在ImsService的handler中能找到。
mImsRILAdapter.registerForImsRegistrationInfo(mHandler, EVENT_IMS_REGISTRATION_INFO, null);1
ImsService 处理:&
从EVENT_IMS_REGISTRATION_INFO中读取到ims注册状态和Capability,并通知监听者。
private static final int IMS_VOICE_OVER_LTE = 1;
private static final int IMS_RCS_OVER_LTE = 2;
private static final int IMS_SMS_OVER_LTE = 4;
private static final int IMS_VIDEO_OVER_LTE = 8;
private static final int IMS_VOICE_OVER_WIFI = 16;
public void handleMessage(Message msg) {
int phoneId = getMainCapabilityPhoneId();
switch (msg.what) {
case EVENT_IMS_REGISTRATION_INFO:
ar = (AsyncResult) msg.
* According to 3GPP TS 27.007 +CIREGU format
* AsyncResult.result is an Object[]
* ((Object[])AsyncResult.result)[0] is integer type to indicate the IMS regiration status.
0: not registered
1: registered
* ((Object[])AsyncResult.result)[1] is numeric value in hexadecimal format to indicate the IMS capability.
1: RTP-based transfer of voice according to MMTEL (see 3GPP TS 24.173 [87])
2: RTP-based transfer of text according to MMTEL (see 3GPP TS 24.173 [87])
4: SMS using IMS functionality (see 3GPP TS 24.341[101])
8: RTP-based transfer of video according to MMTEL (see 3GPP TS 24.183 [87])
int socketId = ((int[]) ar.result)[2];
if (socketId != mActivePhoneId) {
int newImsRegInfo = ServiceState.STATE_POWER_OFF;
if (((int[]) ar.result)[0] == 1) {
newImsRegInfo = ServiceState.STATE_IN_SERVICE;
newImsRegInfo = ServiceState.STATE_OUT_OF_SERVICE;
int newImsExtInfo = ((int[]) ar.result)[1];
mImsRegInfo = newImsRegI
notifyRegistrationStateChange(mImsRegInfo);
if ((mImsRegInfo == ServiceState.STATE_IN_SERVICE)) {
mImsExtInfo = newImsExtI
mImsExtInfo = 0;
notifyRegistrationCapabilityChange(mImsExtInfo);
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
从LOG来看,此次CIREGU指令返回的结果是“1,5”,按照定义,1表示已注册,5代表同时支持IMS_VOICE_OVER_LTE和IMS_SMS_OVER_LTE,即语音和短信业务。
AT& +CIREGU: 1,51
注册状态的同步
ImsManager获得注册状态和capability后,回调ImsPhoneCallTracker中实例化的ImsConnectionStateListener,数据最终将传递到ImsPhone。&
ImsPhone中有ServiceState实例来标记data和ims voice服务状态,并有布尔值mImsRegistered来标记ims注册情况。
private class ImsRegistrationListenerProxy extends IImsRegistrationListener.Stub {
private int mServiceC
private ImsConnectionStateListener mL
public ImsRegistrationListenerProxy(int serviceClass,
ImsConnectionStateListener listener) {
mServiceClass = serviceC
mListener =
public void registrationConnected() {
if (mListener != null) {
mListener.onImsConnected();
public void registrationProgressing() {
if (mListener != null) {
mListener.onImsProgressing();
public void registrationDisconnected(ImsReasonInfo imsReasonInfo) {
if (mListener != null) {
mListener.onImsDisconnected(imsReasonInfo);
public void registrationResumed() {
if (mListener != null) {
mListener.onImsResumed();
public void registrationSuspended() {
if (mListener != null) {
mListener.onImsSuspended();
public void registrationFeatureCapabilityChanged(int serviceClass,
int[] enabledFeatures, int[] disabledFeatures) {
if (mListener != null) {
mListener.onFeatureCapabilityChanged(serviceClass,
enabledFeatures, disabledFeatures);
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
ImsPhoneCallTracker如何处理注册信息和capability的上报:&
1. 注册状态同步到ImsPhone;&
2. Capability同步到mImsFeatureEnabled数组中,标记可用的ims业务;&
3. 最后发出ACTION_IMS_STATE_CHANGED广播。
ImsPhoneCallTracker.java
* Listen to the IMS service state change
private ImsConnectionStateListener mImsConnectionStateListener =
new ImsConnectionStateListener() {
public void onImsConnected() {
mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
mPhone.setImsRegistered(true);
public void onImsDisconnected(ImsReasonInfo imsReasonInfo) {
mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
mPhone.setImsRegistered(false);
mPhone.processDisconnectReason(imsReasonInfo);
if (imsReasonInfo != null && imsReasonInfo.getExtraMessage() != null
&& !imsReasonInfo.getExtraMessage().equals(&&)) {
mImsRegistrationErrorCode = Integer.parseInt(imsReasonInfo.getExtraMessage());
public void onImsProgressing() {
public void onImsResumed() {
mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
public void onImsSuspended() {
mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
public void onFeatureCapabilityChanged(int serviceClass,
int[] enabledFeatures, int[] disabledFeatures) {
if (serviceClass == ImsServiceClass.MMTEL) {
boolean tmpIsVideoCallEnabled = isVideoCallEnabled();
i = ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE;
i &= ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI; i++) {
if (enabledFeatures[i] == i) {
mImsFeatureEnabled[i] = true;
} else if (enabledFeatures[i]
== ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
mImsFeatureEnabled[i] = false;
if (tmpIsVideoCallEnabled != isVideoCallEnabled()) {
mPhone.notifyForVideoCapabilityChanged(isVideoCallEnabled());
for (ImsPhoneConnection connection : mConnections) {
connection.updateWifiState();
mPhone.onFeatureCapabilityChanged();
broadcastImsStatusChange();
};12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
ImsPhone更新ServiceState的Log:
06-02 16:47:44.925 D/ImsPhone( 2170): updateDataServiceState:
defSs = 0 0 voice home data home 中国移动 中国移动 46000 中国移动 中国移动 46000
LTE LTE_CA CSS not supported 0 0 RoamInd=-1 DefRoamInd=-1 EmergOnly=false Ril Voice Regist state: 1 Ril Data Regist state: 1 mProprietaryDataRadioTechnology: 0 VoiceRejectCause: 0 DataRejectCause: -1 IsDataRoamingFromRegistration=false
imsSs = 0 0 voice home data home null null null null null null
Unknown LTE_CA CSS not supported -1 -1 RoamInd=-1 DefRoamInd=-1 EmergOnly=false Ril Voice Regist state: 0 Ril Data Regist state: 0 mProprietaryDataRadioTechnology: 0 VoiceRejectCause: -1 DataRejectCause: -1 IsDataRoamingFromRegistration=false1234
以上分析只分析了AP侧流程,相对于完整的ims注册过程来说并不完整,核心部分的协议及信令流程许多对上层来说是透明的,需要对这些部分深入了解后再做补充。
客户需求国外的客户要求,手机只有在漫游的情况下才显示网络数据图标E G H 3G 4G 等。无语的客户。实现方案具体的修改文件在framework中
MobileSignalController.j...
IMS的基础常识:
https://www.cnblogs.com/moon-lights/p/7018789.html
http://www.360doc.com/content/15/0624...
在文章《Android无线电信息管理开篇准备工作》中介绍 PhoneInterfaceManager 的作用,在文章《初识com.android.phone》中介绍了PhoneInterfaceMan...
一、什么是国际漫游
23.122协议规定,终端注册的VPLMN既不属于HPLMN也不属于EHPLM时,那么终端就是在漫游状态。
二、LTE网络架构
1.1非漫游场景架构
国际漫游...
Android的开发现在是如火如荼,逞现在不是很忙了,学习了下,这里记录下了在windows在如何搭建Android开发环境,对自己是个记录,对新入门的兄弟姐妹们可以参考一下!(1)安装JDK,省略。...
IMS总体架构
如上图所示,IMS总体架构通常分为三层,接入层、呼叫控制层、业务应用层:
接入层:接入层将各种接入网络汇总到IMS核心网中,完成对...
1.前言随着4G技术的诞生和国内运营商网络的全面升级,以往流量贵上网慢的问题不再有,而类似微信这类即时通讯软件也得到快速的普及,互联网行业的发展还延伸到金融/零售等线上线下的各行各业,短短几年内国内I...
一个IMS是一种模型,在这种模型中,网络操作员和业务分别提供方控制网络和业务的接入,与此同时消费者会有消费账单。网络是完全透明的,并且所有的服务由终点(endpoint)提供——这与通...
下面以用户注册为例,如下的图5为一个用户首次注册的流程图: HSS不但作为归属域的用户数据服务器,还作为Diameter服务器,为用户提供AAA服务。 用户注册所依照的参考点为Cx(HSS与CSCF之...
没有更多推荐了,

我要回帖

更多关于 商标注册需要多少钱 的文章

 

随机推荐