之前在《MTK IMS框架简析(1)——代码架构及模块初始化》 中已经分析了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_ENABLERIL_REQUEST_SET_IMS_VOICE_ENABLERIL_REQUEST_SET_IMS_ENABLE
这里就从用户打开界面开关开始分析。
ImsManager::setAdvanced4GMode方法为volte功能的开关,设置界面即通过此接口实现volte开关。
1. 向ImsConfig设置了feature(ImsConfig::setFeatureValue)
2. 打开ims (turnOnIms)。
private void setAdvanced4GMode(boolean turnOn) throws ImsException { checkAndThrowExceptionIfServiceUnavailable(); try { 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(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
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; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
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.javapublic void setFeatureValue(int feature, int network, int value, ImsConfigListener listener) { try { try { //将设置值保存到数据库 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: ... break; case ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI: ... break; 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); } } } break; default: break; } ... } catch (ImsException e) { ... } } catch (RemoteException e) { throw new RuntimeException(e); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
ImsConfig处理完成,继续执行ImsManager::turnOnIms,这同样是aidl调用,实际操作由ImsService.turnOnIms执行。
private void turnOnIms() throws ImsException { checkAndThrowExceptionIfServiceUnavailable(); try { 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。
@Override 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; } else { } }
下发了这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; break;
在《MTK IMS框架简析(1)——代码架构及模块初始化》 中提到过,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并没有开源:
#READMEIMS relay module, handling NAS bearer, P-CSCF address discovery, IMS AKA and relay message among IMCB/IMSA/MAL moduleshandle the request from IMCB/IMSA/MAL moduleSend 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.javapublic void enableImsAdapter() { synchronized (ImsEnabledThreadLock) { if (!misImsAdapterEnabled) { if (mIO.connectSocket() == true) { mImsEventDispatcher.enableRequest(); misImsAdapterEnabled = true; synchronized (mIO.VaSocketIOThreadLock) { mIO.VaSocketIOThreadLock.notify(); } enableImsStack(); } else { sendMessageDelayed( obtainMessage(MSG_IMSA_RETRY_IMS_ENABLE), IMSA_RETRY_SOCKET_TIME); } } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
DataDispatcher负责建立承载相关处理,直接看DataDispatcher.enableRequest()方法的处理:
注册DATA_CONNECTION_STATE_CHANGED和SIM_STATE_CHANGED的监听。监听这2个消息是为了维护ims的连接,响应Data和SIM卡的变动。
DataDispatcher.javapublic 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); return; }
消息的定义如下:
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.javaprivate 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); return; } mHandler.removeMessages(MSG_ON_NOTIFY_ACTIVE_DATA_TIMEOUT); mHandler.sendMessageDelayed(mHandler.obtainMessage( MSG_ON_NOTIFY_ACTIVE_DATA_TIMEOUT, param), MAX_NETWORK_ACTIVE_TIMEOUT_MS); } else { return; } } if (requestNwRequest(apnType, phoneId) < 0) { rejectDefaultBearerDataConnActivation(param, FAILCAUSE_UNKNOWN, 0); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
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].nwRequest; releaseNwRequest(requestApnType); synchronized (mAPNStatuses) { ApnStatus apnStatus = mAPNStatuses.get(requestApnType); apnStatus.mName = requestApnType;//IMS apnStatus.mStatus = TelephonyManager.DATA_DISCONNECTED; apnStatus.isSendReq = true; apnStatus.ifaceName = ""; //发起request getConnectivityManager().requestNetwork(nwRequest, nwCb, ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS); } ... return nRet; }private static final int[] APN_CAP_LIST = new int[] { NetworkCapabilities.NET_CAPABILITY_IMS, NetworkCapabilities.NET_CAPABILITY_EIMS };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
接下来SETUP_DATA_CALL的工作由ConnectivityService和telephony数据模块完成。返回成功后,检查手机的网络接口发现新建了一个Interface——ccmni4
root@x6:/ lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope: Host UP LOOPBACK RUNNING MTU:65536 Metric:1 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 ccmni4 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 MTU:1410 Metric:1 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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
ccmni4是mtk在底层指定的ims默认承载接口的名称,连接建立后DataDispatcher还需要检查这个Interface的名字是否正确,最后发送ACT消息通知volte_imsm连接已经建立
//DataDispatcher.javaprivate 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); } ... } ... } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
这部分的代码量较多,理解了设计意图后其实结构和流程都比较简单,同样以流程图总结:
注册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) { AsyncResult ar; Intent intent; int phoneId = getMainCapabilityPhoneId(); switch (msg.what) { case EVENT_IMS_REGISTRATION_INFO: ar = (AsyncResult) msg.obj; /** * 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) { break; } int newImsRegInfo = ServiceState.STATE_POWER_OFF; if (((int[]) ar.result)[0] == 1) { newImsRegInfo = ServiceState.STATE_IN_SERVICE; } else { newImsRegInfo = ServiceState.STATE_OUT_OF_SERVICE; } int newImsExtInfo = ((int[]) ar.result)[1]; mImsRegInfo = newImsRegInfo; notifyRegistrationStateChange(mImsRegInfo); if ((mImsRegInfo == ServiceState.STATE_IN_SERVICE)) { mImsExtInfo = newImsExtInfo; } else { mImsExtInfo = 0; } notifyRegistrationCapabilityChange(mImsExtInfo); break; ... } ...}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
从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 mServiceClass; private ImsConnectionStateListener mListener; public ImsRegistrationListenerProxy(int serviceClass, ImsConnectionStateListener listener) { mServiceClass = serviceClass; mListener = listener; } ... @Override public void registrationConnected() { if (mListener != null) { mListener.onImsConnected(); } } @Override public void registrationProgressing() { if (mListener != null) { mListener.onImsProgressing(); } } @Override public void registrationDisconnected(ImsReasonInfo imsReasonInfo) { if (mListener != null) { mListener.onImsDisconnected(imsReasonInfo); } } @Override public void registrationResumed() { if (mListener != null) { mListener.onImsResumed(); } } @Override public void registrationSuspended() { if (mListener != null) { mListener.onImsSuspended(); } } @Override public void registrationFeatureCapabilityChanged(int serviceClass, int[] enabledFeatures, int[] disabledFeatures) { if (mListener != null) { mListener.onFeatureCapabilityChanged(serviceClass, enabledFeatures, disabledFeatures); } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
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() { @Override public void onImsConnected() { mPhone.setServiceState(ServiceState.STATE_IN_SERVICE); mPhone.setImsRegistered(true); } @Override 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()); } } @Override public void onImsProgressing() { } @Override public void onImsResumed() { mPhone.setServiceState(ServiceState.STATE_IN_SERVICE); } @Override public void onImsSuspended() { mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE); } @Override public void onFeatureCapabilityChanged(int serviceClass, int[] enabledFeatures, int[] disabledFeatures) { if (serviceClass == ImsServiceClass.MMTEL) { boolean tmpIsVideoCallEnabled = isVideoCallEnabled(); for (int 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; } else { } } if (tmpIsVideoCallEnabled != isVideoCallEnabled()) { mPhone.notifyForVideoCapabilityChanged(isVideoCallEnabled()); } for (ImsPhoneConnection connection : mConnections) { connection.updateWifiState(); } mPhone.onFeatureCapabilityChanged(); broadcastImsStatusChange(); } } };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
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注册过程来说并不完整,核心部分的协议及信令流程许多对上层来说是透明的,需要对这些部分深入了解后再做补充。