您的位置:首页 > 移动开发 > Android开发

android之Radio状态

2015-11-21 22:36 591 查看
android 5.1

在Java层,Radio只有三种状态:

enum RadioState {
RADIO_OFF, /* Radio explicitly powered off (eg CFUN=0) */
RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */
RADIO_ON; /* Radio is on */

public boolean isOn() /* and available...*/ {
return this == RADIO_ON;
}

public boolean isAvailable() {
return this != RADIO_UNAVAILABLE;
}
}
在C层,radio有多个状态:

状态转换在RIL.java中的getRadioStateFromInt方法中

第一,在rild和RILJ中,radio初始状态都是UNAVAILABLE

rild进程启动时,radio的状态默认会设置为RADIO_STATE_UNAVAILABLE

reference-ril.c

static RIL_RadioState sState = RADIO_STATE_UNAVAILABLE;

RILJ初始化时,Radio状态为RADIO_UNAVAILABLE

BaseCommands.java

protected RadioState mState = RadioState.RADIO_UNAVAILABLE;

第二,rild进程初始化过程中,设置radio状态为OFF

1. rild.cpp main()

rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");
funcs = rilInit(&s_rilEnv, argc, rilArgv);

2. reference-ril.c
ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);
RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);
static void initializeCallback(void *param __unused)
setRadioState (RADIO_STATE_OFF);
第三,rild中,radio状态切换为OFF后,会通知RILJ

RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
NULL, 0);
// Sim state can change as result of radio state change
RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
NULL, 0);

第四,RILJ收到radio的新状态,会去通知关心RadioStateChange和RadioAvailable的订阅者
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
/* has bonus radio state int */
RadioState newState = getRadioStateFromInt(p.readInt());
if (RILJ_LOGD) unsljLogMore(response, newState.toString());

switchToRadioState(newState);

private void switchToRadioState(RadioState newState) {
    setRadioState(newState);
}

protected void setRadioState(RadioState newState) {
    mRadioStateChangedRegistrants.notifyRegistrants();

    if (mState.isAvailable() && !oldState.isAvailable()) {
        mAvailRegistrants.notifyRegistrants();
        onRadioAvailable();
    }
}


第五,只有ServiceStateTracker关心RadioStateChange,它会请求RILJ去打开radio
忽略RadioAvailable的订阅者,同时也忽略CDMA,只关注GSM

GsmServiceStateTracker.java

public GsmServiceStateTracker(GSMPhone phone) {
mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
    // system setting property AIRPLANE_MODE_ON is set in Settings.
    int airplaneMode = Settings.Global.getInt(
            phone.getContext().getContentResolver(),
            Settings.Global.AIRPLANE_MODE_ON, 0);
    mDesiredPowerState = ! (airplaneMode > 0);
}

case EVENT_RADIO_STATE_CHANGED:
// This will do nothing in the radio not
// available case
setPowerStateToDesired();
pollState();
break;

protected void setPowerStateToDesired() {
    // If we want it on and it's off, turn it on
    if (mDesiredPowerState && mCi.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
        mCi.setRadioPower(true, null);
    }
}


第六,RILJ去和rild通信,请求打开radio:RIL_REQUEST_RADIO_POWER
注意:GSMSST虽然通过RILJ向rild发送request,但它并不关心返回的结果,所以Msg是null,它是通过订阅来得到相应的结果

setRadioPower(boolean on, Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);
rr.mParcel.writeInt(1);
rr.mParcel.writeInt(on ? 1 : 0);
send(rr);
}

第七,rild去打开radio
通过AT命令打开radio:AT+CFUN=1

检查radio当前的状态:AT+CFUN?

最重要的是setRadioState(RADIO_STATE_ON);

它会通知到RILJ,radio状态又改变啦

RILJ向rild的每个Request,rild都会发回RESPONSE_SOLICITED给RILJ,但对于radio,RILJ不关心SOLICITE,只关心RESPONSE_UNSOLICITED

reference-ril.c
static void onRequest (int request, void *data, size_t datalen, RIL_Token t)
{
case RIL_REQUEST_RADIO_POWER:
requestRadioPower(data, datalen, t);
break;
}

static void requestRadioPower(void *data, size_t datalen, RIL_Token t)
{
    int onOff = ((int *)data)[0];
    if (onOff > 0 && sState == RADIO_STATE_OFF) {
        err = at_send_command("AT+CFUN=1", &p_response);
        if (err < 0|| p_response->success == 0) {
            // Some stacks return an error when there is no SIM,
            // but they really turn the RF portion on
            // So, if we get an error, let's check to see if it
            // turned on anyway

            if (isRadioOn() != 1) {
                goto error;
            }
        }
        setRadioState(RADIO_STATE_ON);
    }

    at_response_free(p_response);
    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
    return;
}

/** returns 1 if on, 0 if off, and -1 on error */
static int isRadioOn()
{
    err = at_send_command_singleline("AT+CFUN?", "+CFUN:", &p_response);
    line = p_response->p_intermediates->line;
    err = at_tok_start(&line);
    err = at_tok_nextbool(&line, &ret);

    return (int)ret;
}


第八,rild又要去通知RILJ
于之前setradio OFF不同的是,此时可以去获取SIM卡的状态啦

static void setRadioState(RIL_RadioState newState)
{
RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);

if (sState == RADIO_STATE_ON) {
onRadioPowerOn();
}
}

static void onRadioPowerOn()
{
pollSIMState(NULL);
}

第九,RILJ要把事件发给订阅radostatechanged的和radioon的
protected void setRadioState(RadioState newState) {
mRadioStateChangedRegistrants.notifyRegistrants();
if (mState.isOn() && !oldState.isOn()) {
mOnRegistrants.notifyRegistrants();
}
}但这一回,GSMSST什么也没必要干了,除了再重新去pollState()

说说关心radio avaliable的吧:GSMPhone.java

在radio avaliable之后,去获取一些重要信息:BasebandVersion,IMEI,IMEISV,RadioCapability

mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);

case EVENT_RADIO_AVAILABLE: {
mCi.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));
mCi.getIMEI(obtainMessage(EVENT_GET_IMEI_DONE));
mCi.getIMEISV(obtainMessage(EVENT_GET_IMEISV_DONE));
mCi.getRadioCapability(obtainMessage(EVENT_GET_RADIO_CAPABILITY));
}

说说关心radio on的吧:UiccController.java
这是SIM卡管理的核心类,看这注释你就直到它有多重要

* Following is class diagram for uicc classes:
*
* UiccController
* #
* |
* UiccCard
* # #
* | ------------------
* UiccCardApplication CatService
* # #
* | |
* IccRecords IccFileHandler
* ^ ^ ^ ^ ^ ^ ^ ^
* SIMRecords---- | | | | | | ---SIMFileHandler
* RuimRecords----- | | | | ----RuimFileHandler
* IsimUiccRecords--- | | -----UsimFileHandler
* | ------CsimFileHandler
* ----IsimFileHandler

可以说,所有关于SIM相关的最重要的类,都在这里管理
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: