RIL 机制---消息从RILJ到RIL

RILJ发送子线程需要关注两点:

1、如何把数据发送到mSenderThread中;

2、mSenderThread是如何把请求发送给RIL的。

在创建mSenderThread线程的时候,先是通过getLooper得到子线程的Looper,

然后用这个Looper去创建了Handler对象,因此得到的这个Handler对象就是子线程的Handler,也就是RILSender对象。

4.1 Send方法

各种发送消息的方法最后都要通过send方法来发送,例如进行拨号, dial方法如下,

@Override
    public void
    dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);

        rr.mParcel.writeString(address);
        rr.mParcel.writeInt(clirMode);

        if (uusInfo == null) {
            rr.mParcel.writeInt(0); // UUS information is absent
        } else {
            rr.mParcel.writeInt(1); // UUS information is present
            rr.mParcel.writeInt(uusInfo.getType());
            rr.mParcel.writeInt(uusInfo.getDcs());
            rr.mParcel.writeByteArray(uusInfo.getUserData());
        }

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

        send(rr);
    }

使用RIL_REQUEST_DIAL 表示拨号的消息码。

通过mSender对象生成(obtainMessage)了一个EVENT_SEND的消息,

同时把请求包装为RILRequest对象,连同EVENT_SEND消息一同发送(sendToTarget)给了子线程。

4.2 RILSender处理

RILSender中handleMessage方法有关EVENT_SEND消息处理如下,

case EVENT_SEND:
       try {
              LocalSocket s;
 s = mSocket;
if (s == null) {
 rr.onError(RADIO_NOT_AVAILABLE, null);
                     rr.release();
                     decrementWakeLock();
                     return;
               }
synchronized (mRequestList) {
                     mRequestList.append(rr.mSerial, rr);
               }
byte[] data;
data = rr.mParcel.marshall();
               rr.mParcel.recycle();
               rr.mParcel = null;
               if (data.length > RIL_MAX_COMMAND_BYTES) {//data长度不能超过8kb
                    throw new RuntimeException(
                                    "Parcel larger than max bytes allowed! "
                                                          + data.length);
                        }

                        // parcel length in big endian
                    // byte[] dataLength = new byte[4];
                  dataLength[0] = dataLength[1] = 0;
                  dataLength[2] = (byte)((data.length >> 8) & 0xff);
                 dataLength[3] = (byte)((data.length) & 0xff);
                        //Rlog.v(RILJ_LOG_TAG, "writing packet: " + data.length + " bytes");
                 s.getOutputStream().write(dataLength);//发送data长度信息
                 s.getOutputStream().write(data);//发送数据。
                    } catch (IOException ex) {
                        Rlog.e(RILJ_LOG_TAG, "IOException", ex);
                        req = findAndRemoveRequestFromList(rr.mSerial);
                        // make sure this request has not already been handled,
                        // eg, if RILReceiver cleared the list.
                        if (req != null) {
                            rr.onError(RADIO_NOT_AVAILABLE, null);
                            rr.release();
                            decrementWakeLock();
                        }
                    } catch (RuntimeException exc) {
                        Rlog.e(RILJ_LOG_TAG, "Uncaught exception ", exc);
                        req = findAndRemoveRequestFromList(rr.mSerial);
                        // make sure this request has not already been handled,
                        // eg, if RILReceiver cleared the list.
                        if (req != null) {
                            rr.onError(GENERIC_FAILURE, null);
                            rr.release();
                            decrementWakeLock();
                        }
                    }

      break;

发送的过程很简单,就是通过Socket通道把数据长度(dataLength)信息和数据(data)发送出去。

小结:RILJ首先对消息进行封装,然后在发送线程中通过Socket通道把数据长度信息和数据发送出去。

RILJ和rild守护进程一次通信的数据不大于8kb,通信的消息码分别保存在RILConstants.java和ril.h中。


 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
 

你可能感兴趣的:(---【RIL机制分析】)