本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉。
本文主要介绍GsmServiceStateTracker是怎么管理网络的?手机开机后,怎么去注册网络?网络状态是怎么变换传递的。
Android在ServiceState.java中定义了四种ServiceState状态和16中无线通信网络类型:
public class ServiceState implements Parcelable {
/**
* Normal operation condition, the phone is registered
* with an operator either in home network or in roaming.
*/
public static final int STATE_IN_SERVICE = 0;
/**
* Phone is not registered with any operator, the phone
* can be currently searching a new operator to register to, or not
* searching to registration at all, or registration is denied, or radio
* signal is not available.
*/
public static final int STATE_OUT_OF_SERVICE = 1;
/**
* The phone is registered and locked. Only emergency numbers are allowed. {@more}
*/
public static final int STATE_EMERGENCY_ONLY = 2;
/**
* Radio of telephony is explicitly powered off.
*/
public static final int STATE_POWER_OFF = 3;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_UNKNOWN = 0;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_GPRS = 1;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_EDGE = 2;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_UMTS = 3;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_IS95A = 4;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_IS95B = 5;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_1xRTT = 6;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_EVDO_0 = 7;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_EVDO_A = 8;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_HSDPA = 9;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_HSUPA = 10;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_HSPA = 11;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_EVDO_B = 12;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_EHRPD = 13;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_LTE = 14;
/** @hide */
public static final int RIL_RADIO_TECHNOLOGY_HSPAP = 15;
/**
* GSM radio technology only supports voice. It does not support data.
* @hide
*/
public static final int RIL_RADIO_TECHNOLOGY_GSM = 16;
}
mCi.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
mCi.registerForPsNetworkStateChanged(this, EVENT_PS_NETWORK_STATE_CHANGED, null);
mCi.setOnNITZTime(this, EVENT_NITZ_TIME, null);
mCi.registerForSimPlugOut(this, EVENT_SIM_PLUG_OUT, null);
//MTK-START [ALPS415367]For MR1 Migration
//mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
//MTK-END [ALPS415367]For MR1 Migration
mCi.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
mCi.registerForSIMReady(this, EVENT_SIM_READY, null);//Android原来的,MTK没用这个,用的是我们后面介绍的
mCi.setGprsDetach(this, EVENT_DATA_CONNECTION_DETACHED, null);
mCi.setInvalidSimInfo(this, EVENT_INVALID_SIM_INFO, null);//ALPS00248788
if(mServiceStateExt.isImeiLocked())
mCi.registerForIMEILock(this, EVENT_IMEI_LOCK, null);
mCi.registerForIccRefresh(this,EVENT_ICC_REFRESH,null);
我们从SIM卡的Ready状态开始查看,SIM卡处于ready状态,手机才可以开始注册网络,SIM卡ready状态的监听请查看Android4.4 Telephony流程分析——SIM卡开机时的初始化一文的step33,SIM卡Ready状态的通知请查看Android4.4 Telephony流程分析——SIM卡开机时的数据加载一文的step9,现在我们直接从GsmServiceStateTracker的handleMessage()处理EVENT_SIM_READY事件开始分析。
step2~step3,设置优先选择的网络类型,MTK提供了如下一些类型:
/* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
int NETWORK_MODE_WCDMA_PREF = 0; /* GSM/WCDMA (WCDMA preferred) */
int NETWORK_MODE_GSM_ONLY = 1; /* GSM only */
int NETWORK_MODE_WCDMA_ONLY = 2; /* WCDMA only */
int NETWORK_MODE_GSM_UMTS = 3; /* GSM/WCDMA (auto mode, according to PRL)
AVAILABLE Application Settings menu*/
int NETWORK_MODE_CDMA = 4; /* CDMA and EvDo (auto mode, according to PRL)
AVAILABLE Application Settings menu*/
int NETWORK_MODE_CDMA_NO_EVDO = 5; /* CDMA only */
int NETWORK_MODE_EVDO_NO_CDMA = 6; /* EvDo only */
int NETWORK_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
AVAILABLE Application Settings menu*/
int NETWORK_MODE_LTE_CDMA_EVDO = 8; /* LTE, CDMA and EvDo */
int NETWORK_MODE_LTE_GSM_WCDMA = 9; /* LTE, GSM/WCDMA */
int NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
int NETWORK_MODE_LTE_ONLY = 11; /* LTE Only mode. */
int NETWORK_MODE_LTE_WCDMA = 12; /* LTE/WCDMA */
//for LTE the preferred nw tyep is "4G preferred"
int PREFERRED_NETWORK_MODE = FeatureOption.MTK_LTE_SUPPORT? NETWORK_MODE_LTE_GSM_WCDMA:NETWORK_MODE_WCDMA_PREF;
//int PREFERRED_NETWORK_MODE = NETWORK_MODE_WCDMA_PREF;
//MTK-START: add for LTE
int NETWORK_MODE_MTK_BASE = 30;
// GSM/WCDMA, LTE (for MMDSDC "3G or 2G Preferred" item)
int NETWORK_MODE_GSM_WCDMA_LTE = NETWORK_MODE_MTK_BASE+1;
int NETWORK_MODE_GSM_WCDMA_LTE_MMDC = NETWORK_MODE_MTK_BASE+2;
// for MMDSDC mode = "2/3/4G(auto)" item
int NETWORK_MODE_LTE_GSM_WCDMA_MMDC = NETWORK_MODE_MTK_BASE+3;
// "4G/2G" item (only for EM mode)
int NETWORK_MODE_LTE_GSM = NETWORK_MODE_MTK_BASE+4;
int NETWORK_MODE_LTE_GSM_MMDC = NETWORK_MODE_MTK_BASE+5;
//MTK-END: add for LTE
//MTK-START [mtk04070][111117][ALPS00093395]MTK added
int NETWORK_MODE_GEMINI = 20; /* Gemini Phone */ //ALPS01219851 value cannot conflict with other NETWORK_MODE_xxx
step4,直接发送at命令,来选择小区(这个具体作用不太清楚),
//ALPS00279048
public void setCRO(int mode, Message onComplete) {
String cmdStr[] = {"AT+ECRO=0", ""};
/* ALPS00310187 add mode 2 and 3 support */
if(mode == 0){
cmdStr[0] = "AT+ECRO=0";
}else if(mode == 1){
cmdStr[0] = "AT+ECRO=1";
}else if(mode == 2){
cmdStr[0] = "AT+ECRO=2";
}else if(mode == 3){
cmdStr[0] = "AT+ECRO=3";
}else{
LOGD("Invalid parameter in setCRO:" + mode);
return;
}
this.invokeOemRilRequestStrings(cmdStr,onComplete);
}
step6,设置GPRS连接类型。
我们这个过程是假设射频状态良好,SIM卡处于准备状态的,step8~step11向Modem查询入网状态:
default:
// Issue all poll-related commands at once
// then count down the responses, which
// are allowed to arrive out-of-order
mPollingContext[0]++;//待处理的事件+1
mCi.getOperator(
obtainMessage(
EVENT_POLL_STATE_OPERATOR, mPollingContext));//查询注册的运营商信息
//[MMDC] no need to check ps state in LteDcSST
if (PhoneFactory.isLteDcSupport() && (this instanceof LteDcServiceStateTracker)){
if (DBG) log("LteDcSST ignore get data registerState");
} else {
mPollingContext[0]++;//待处理的事件+1
mCi.getDataRegistrationState(
obtainMessage(
EVENT_POLL_STATE_GPRS, mPollingContext));//查询注册的数据连接状态
}
mPollingContext[0]++;//待处理的事件+1
mCi.getVoiceRegistrationState(
obtainMessage(
EVENT_POLL_STATE_REGISTRATION, mPollingContext));//查询注册的语音通话网络类型
mPollingContext[0]++;//待处理的事件+1
mCi.getNetworkSelectionMode(
obtainMessage(
EVENT_POLL_STATE_NETWORK_SELECTION_MODE, mPollingContext));//查询网络选择状态
break;
step12,获取手机信号,每10s查一次。
private void queueNextSignalStrengthPoll() {
if (mDontPollSignalStrength) {
// The radio is telling us about signal strength changes
// we don't have to ask it
return;
}
Message msg;
msg = obtainMessage();
msg.what = EVENT_POLL_SIGNAL_STRENGTH;
long nextTime;
// TODO Don't poll signal strength if screen is off
sendMessageDelayed(msg, POLL_PERIOD_MILLIS);//POLL_PERIOD_MILLIS定义为10s
}
handleMessage()发起于RIL交互:
case EVENT_POLL_SIGNAL_STRENGTH:
// Just poll signal strength...not part of pollState()
mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
break;
case EVENT_GET_SIGNAL_STRENGTH:
// This callback is called when signal strength is polled
// all by itself
//ALPS01035028 - start
//if (!(mCi.getRadioState().isOn())) {
if (!mRadioState.isOn()) {
//ALPS01035028 - end
// Polling will continue when radio turns back on
return;
}
ar = (AsyncResult) msg.obj;
//MTK-START [ALPS415367]For MR1 Migration
ar = onGsmSignalStrengthResult(ar);
//MTK-END [ALPS415367]For MR1 Migration
onSignalStrengthResult(ar, true);//这里会将手机信号更新通知广播出去
queueNextSignalStrengthPoll();//隔10S后再一次查询信号,循环
break;
step14,处理step8~step11查询的信息:
try {
switch (what) {
case EVENT_POLL_STATE_REGISTRATION:
states = (String[])ar.result;
int lac = -1;
int cid = -1;
int type = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
int regState = ServiceState.RIL_REG_STATE_UNKNOWN;
int reasonRegStateDenied = -1;
int psc = -1;
if (states.length > 0) {
try {
regState = Integer.parseInt(states[0]);
if (states.length >= 3) {
if (states[1] != null && states[1].length() > 0) {
//[ALPS00907900]-START
int tempLac = Integer.parseInt(states[1], 16);
if (tempLac < 0){
log("set Lac to previous value");
tempLac = mCellLoc.getLac();
}
lac = tempLac;
//[ALPS00907900]-END
}
if (states[2] != null && states[2].length() > 0) {
//[ALPS00907900]-START
int tempCid = Integer.parseInt(states[2], 16);
if (tempCid < 0){
log("set Cid to previous value");
tempCid = mCellLoc.getCid();
}
cid = tempCid;
//[ALPS00907900]-END
}
if (states.length >=4 && states[3] != null && states[3].length() > 0) {
//[ALPS01132085] for NetworkType display abnormal
//update network type when screen is on or screen is off but not registered
if (mIsScreenOn || (!mIsScreenOn &&((regState!=1)||(regState!=5)))){
type = Integer.parseInt(states[3]);
mNewSS.setRilVoiceRadioTechnology(type);
}
}
}
} catch (NumberFormatException ex) {
loge("error parsing RegistrationState: " + ex);
}
}
mGsmRoaming = regCodeIsRoaming(regState);//是否漫游
mNewSS.setState (regCodeToServiceState(regState));//网络服务状态
mNewSS.setRegState(regState);//
if (FeatureOption.MTK_GEMINI_SUPPORT) {
if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(mSimState)||
IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(mSimState)) {
log("SIM state is lock or absent, treat as OUT_OF_SERVICE");
mNewSS.setState(ServiceState.STATE_OUT_OF_SERVICE);
//[ALPS01010930] to consistent RegState and ServcieState
mNewSS.setRegState(ServiceState.REGISTRATION_STATE_NOT_REGISTERED_AND_NOT_SEARCHING);
}
}
// LAC and CID are -1 if not avail. LAC and CID will be updated in onNetworkStateChangeResult() when in OUT_SERVICE
if (states.length > 3) {
log("states.length > 3");
/* ALPS00291583: ignore unknown lac or cid value */
if(lac==0xfffe || cid==0x0fffffff)
{
log("unknown lac:"+lac+"or cid:"+cid);
}
else
{
/* AT+CREG? result won't include and when in OUT_SERVICE */
if(regCodeToServiceState(regState) != ServiceState.STATE_OUT_OF_SERVICE){
mNewCellLoc.setLacAndCid(lac, cid);//小区广播信息更新
}
}
}
mNewCellLoc.setPsc(psc);//小区广播信息更新
break;
case EVENT_POLL_STATE_GPRS:
case EVENT_POLL_STATE_GPRS_2G:
case EVENT_POLL_STATE_GPRS_34G:
states = (String[])ar.result;
//[MMDC] for MMDC, in Ps switching state, don't update the service state
PsArbitrator psArbitrator = mCi.getPsArbitrator();
if (PhoneFactory.isLteDcSupport() && LteModemSwitchHandler.getActiveModemType() == LteModemSwitchHandler.MD_TYPE_LTNG
&& PsArbitrator.getIsSwitching() )
{
log("ignore pollstate GPRS when ps switching. psarbitrator");
log("newGPRSState/newps_networkType:" + newGPRSState + "/"+ newps_networkType);
mNewSS.setDataRegState(newGPRSState);
mNewSS.setRilDataRadioTechnology(newps_networkType);
} else if (what == EVENT_POLL_STATE_GPRS_2G && psArbitrator.getCurrentPsMode() != PsArbitrator.PS_MODE_GSM && PhoneFactory.isLteDcSupport()
&& LteModemSwitchHandler.getActiveModemType() == LteModemSwitchHandler.MD_TYPE_LTNG) {
log("EVENT_POLL_STATE_GPRS current mode is 34G but receivce 2G GPRS state, ignore");
mNewSS.setDataRegState(newGPRSState);
mNewSS.setRilDataRadioTechnology(newps_networkType);
} else if (what == EVENT_POLL_STATE_GPRS_34G && psArbitrator.getCurrentPsMode() == PsArbitrator.PS_MODE_GSM && PhoneFactory.isLteDcSupport()
&& LteModemSwitchHandler.getActiveModemType() == LteModemSwitchHandler.MD_TYPE_LTNG){
log("EVENT_POLL_STATE_GPRS current mode is 2G but receivce 34G GPRS state, ignore");
mNewSS.setDataRegState(newGPRSState);
mNewSS.setRilDataRadioTechnology(newps_networkType);
} else {
regState = -1;
mNewReasonDataDenied = -1;
mNewMaxDataCalls = 1;
if (states.length > 0) {
try {
regState = Integer.parseInt(states[0]);
//MTK-ADD Start : for CS not registered , PS regsitered (ex: LTE PS only mode or 2/3G PS only SIM card or CS domain network registeration temporary failure
if (states.length >= 3) {
if (states[1] != null && states[1].length() > 0) {
int tempLac = Integer.parseInt(states[1], 16);
if (tempLac < 0){
log("set Lac to previous value");
tempLac = mCellLoc.getLac();
}
psLac = tempLac;
}
if (states[2] != null && states[2].length() > 0) {
int tempCid = Integer.parseInt(states[2], 16);
if (tempCid < 0){
log("set Cid to previous value");
tempCid = mCellLoc.getCid();
}
psCid = tempCid;
}
}
//MTK-ADD END : for CS not registered , PS regsitered (ex: LTE PS only mode or 2/3G PS only SIM card or CS domain network registeration temporary failure
// states[3] (if present) is the current radio technology
if (states.length >= 4 && states[3] != null) {
newps_networkType = Integer.parseInt(states[3]);
}
if (states.length >= 5 && states[4] != null) {
log(" " + states[4]);
}
if (states.length >= 6 && states[5] != null) {
log(" " + states[5]);
}
if ((states.length >= 7 ) && (regState == 3)) {
mNewReasonDataDenied = Integer.parseInt(states[6]);
}
if (states.length >= 8) {
mNewMaxDataCalls = Integer.parseInt(states[7]);
}
} catch (NumberFormatException ex) {
loge("error parsing GprsRegistrationState: " + ex);
}
}
newGPRSState = regCodeToServiceState(regState);
//for MR2 update Data Registration state
mNewSS.setDataRegState(newGPRSState);//GPRS连接状态
mDataRoaming = regCodeIsRoaming(regState);
//mNewRilRadioTechnology = newps_networkType;
mNewSS.setRilDataRadioTechnology(newps_networkType);//
}
break;
case EVENT_POLL_STATE_OPERATOR:
String opNames[] = (String[])ar.result;
if (opNames != null && opNames.length >= 3) {
log("long:" +opNames[0] + " short:" + opNames[1] + " numeric:" + opNames[2]);
mNewSS.setOperatorName (opNames[0], opNames[1], opNames[2]);//更新运营商名称
}
break;
case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
ints = (int[])ar.result;
mNewSS.setIsManualSelection(ints[0] == 1);
if((mSS.getIsManualSelection() == true) && (mNewSS.getIsManualSelection() == false)){
log("Selection mode change from manual to auto");//手动选择网络
if (FeatureOption.MTK_GEMINI_SUPPORT) {
if (mPhone instanceof GSMPhone){
boolean allPhoneInAutoMode = true;
for(int simIdx=PhoneConstants.GEMINI_SIM_1;simIdx
右键复制图片地址,在浏览器中打开即可查看大图。
未完待续,有不对的地方,请指正。