zoukankan      html  css  js  c++  java
  • Android天线信号刷新流程

     

    初次接触android的代码,花2天时间把android的RIL以及向上的延伸比如天线信号刷新的流程理一下。

    我把这个流程分成3个部分:

    1.       RIL的实现流程;

    2.       自动上报的信号强度如何实现在屏幕上的刷新;

    3.       信号强度的主动读取流程;

    其一,RIL实现流程,这个在去年有抽一点点时间看过,不过当时因为时间和心情的关系没有看明白,感觉是一头雾水。这一次算是把整体的ril梳理了一下。这里仅仅描述大概的流程:

    1.首先了解串口数据的接收和处理

    动态加载ril库,取出ril_INIT函数-》创建mainloop线程-》创建readerlooper线程,readerlooper线程主要用于处理串口的数据,先读取串口的数据然后对数据进行解析,分为两种:自动上报的AT数据,AT的反馈数据【主动发送的AT数据,然后接收到modem的返回】。

    主动发送的AT分为如下类型:

    ->NO RESULT------无返回

    ->SIGNALLINE----返回为单条命令

    ->NUMBERIC----数字(基本没有用到)

    ->MUTILINE----返回为多行命令

    ->SMS---短信PDU

    因为每个AT的发送都会收到OK或者非OK的返回,主要是用于验证通讯是否正常。返回ok也仅仅表示发送的at modem已经成功收到。针对返回的是ok还是非ok来填充respone结构体中的success变量。然后根据当前AT指令发送的类型进行解析,把返回的值填到respone里面。

    2.AT的发送

    AT发送会调用writeline函数将数据写到串口,然后阻塞该线程,等待返回。等待的条件是接收函数processline处理后释放的。在android的代码中是无限等待的,没有做超时处理。

    当接收到返回值后根据返回值进行消息的发放。

    4.       这里要提一下RIL CLASS。要清楚熟悉该class的所有方法。该class继承了basecommands父类,并实现了commandinterface中的方法。还需要注意到RILsender和RILreceiver以及readRilmessgae。

    接下来我们来观察如果modem自动上报一个信号强度的AT指令FW如何处理。

    先注意:

    static CommandInfo s_commands[] = {

    #include "ril_commands.h" //返回的AT处理函数注册

    };

    static UnsolResponseInfo s_unsolResponses[] = {

    #include "ril_unsol_commands.h" //自动上报的AT处理函数注册

    };

    首先会不断从串口读取数据,当收到的数据属于自动上报型的AT的时候用函数onUnsolicited处理。我现在的代码是没有处理自动上报的信号强度AT的,需要我们自己在这个函数中添加。RIL_onUnsolicitedResponse处理接收到的自动上报数据,根据s_unsolResponses里面的对应处理调用相应函数:

        ret = s_unsolResponses[unsolResponseIndex]

                    .responseFunction(p, data, datalen);

    之后用函数sendResponse将数据写入文件。

    Ril class中的rilreceiver class执行run方法readRilMessage读取数据,然后调用processrespone函数中processUnsolicited实现自动上报AT的解析和处理。

    RIL_UNSOL_SIGNAL_STRENGTH为respone值。会执行

                    if (mSignalStrengthRegistrant != null) {

                        mSignalStrengthRegistrant.notifyRegistrant(

                                            new AsyncResult (null, ret, null));

                    }

    其中mSignalStrengthRegistrant是ServiceStateTracker CLASS在析构函数中创建的对象:

    cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);

    上面所说的mSignalStrengthRegistrant.notifyRegistrant。执行的是Registrant CLASS 中方法notifyRegistrant。该方法把EVENT_SIGNAL_STRENGTH_UPDATE的notify用message发送出去。

    接下来会是ServiceStateTracker CLASS中的handleMessage方法对该event进行处理:

                case EVENT_SIGNAL_STRENGTH_UPDATE:

                    // This is a notification from

                    // CommandsInterface.setOnSignalStrengthUpdate

                    ar = (AsyncResult) msg.obj;

                    // The radio is telling us about signal strength changes

                    // we don't have to ask it

                    dontPollSignalStrength = true;

                    onSignalStrengthResult(ar);

                    break;

    onSignalStrengthResult函数会把返回值进行解析放到变量RSSI里面。如果返回的rssi值与当前的值不一样则调用phone.notifySignalStrength();通知信号发生变化。调用DefaultPhoneNotifier CLASS中notifySignalStrength方法,先把当前rssi值作为mRegistry.notifySignalStrength(sender.getSignalStrengthASU())函数的形参传递过去。执行的是TelephonyRegistry CLASS中notifySignalStrength方法。该方法调用broadcastSignalStrengthChanged(signalStrengthASU);将ACTION_SIGNAL_STRENGTH_CHANGED作为intent发送给android的框架。之后PhoneStateIntentReceiver CLASS会收到并用onReceive对其进行处理:

                if (TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED.equals(action)) {

                    mAsu = intent.getIntExtra(INTENT_KEY_ASU, mAsu);

                    if (DBG) Log.d(LOG_TAG, "onReceiveIntent: set asu=" + mAsu);

                   

                    if (mTarget != null && getNotifySignalStrength()) {

                        Message message = Message.obtain(mTarget, mAsuEventWhat);

                        mTarget.sendMessage(message);

                    }

    }

    其中mAsuEventWhat 为EVENT_SIGNAL_STRENGTH_CHANGED。在RadioInfo ativity中设置:

    mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED);

    事件EVENT_SIGNAL_STRENGTH_CHANGED会被RadioInfo CLASS的mHandler处理:

                    case EVENT_SIGNAL_STRENGTH_CHANGED:

                        updateSignalStrength();

                        break;

    其中updateSignalStrength实现了信号的更新。至此,处理信号的强度流程完毕。

    下面我们再来看下主动读取信号强度的流程:

    当ServiceStateTracker收到EVENT_SIM_READY的消息的时候,调用handleMessage处理:

    其中调用                queueNextSignalStrengthPoll();延时2s后发送EVENT_POLL_SIGNAL_STRENGTH消息,处理为:

                case EVENT_POLL_SIGNAL_STRENGTH:

                    // Just poll signal strength...not part of pollState()

                   cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));

                    break;

    getSignalStrength在ril中定义:

    getSignalStrength (Message result)

        {

            RILRequest rr

                    = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result);

            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));

            send(rr);

    }

    其中send发送EVENT_SEND信息,由rilsender处理。建立SocketOutputStream对象,存放数据。这些数据有谁来处理呢?其实register函数里面会先注册:

        ril_event_set (&s_listen_event, s_fdListen, false,

                    listenCallback, NULL);

    RIL_startEventLoop(void)函数创建了一个线程eventLoop用于处理ril event。firePending函数最终会调用listenCallback-》processCommandBuffer调用s_commands对应的dispatchFunction函数执行,该函数会执行onrequest。

    之后onRequest函数处理:

            case RIL_REQUEST_SIGNAL_STRENGTH:

                requestSignalStrength(data, datalen, t);

                break;

    requestSignalStrength给串口发送AT+CSQ,等待返回。返回后调用RIL_onRequestComplete处理:调用sendResponseRaw将数据写到文件中。

    RILReceiver会调用readRilMessage不断去读取返回的数据。processResponse处理数据,processSolicited处理等待返回的数据:将其发送出去。

                if (rr.mResult != null) {

                    AsyncResult.forMessage(rr.mResult, null, tr);

                    rr.mResult.sendToTarget();

                }

    ServiceStateTracker收到并做如下处理:

                case EVENT_GET_SIGNAL_STRENGTH:

                    // This callback is called when signal strength is polled

                    // all by itself

                    if (!(cm.getRadioState().isOn())) {

                        // Polling will continue when radio turns back on

                        return;

                    }

                    ar = (AsyncResult) msg.obj;

                    onSignalStrengthResult(ar); //通知已经改变了值

                    queueNextSignalStrengthPoll();//继续读取值

                    break;

  • 相关阅读:
    树形数据深度排序处理示例(递归法).sql
    12种JavaScript MVC框架之比较
    逐级汇总示例(用户定义函数法).sql
    名次查询的处理示例.sql
    实现删除指定结点及所有子节点的处理触发器.sql
    memcpy和memmove的区别
    据说是月薪2W的笔试题
    C++重点知识
    Java初学者需掌握的30个概念
    (转)微软面试题
  • 原文地址:https://www.cnblogs.com/chengliu/p/3636434.html
Copyright © 2011-2022 走看看