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

本文深入探讨RILJ中的Send方法和RILSender处理过程。通过Send方法,RILJ将数据封装并利用Handler发送到mSenderThread,接着mSenderThread通过Socket将消息数据和长度发送给RIL。RILJ与rild通信时,单次数据不超过8kb,消息码定义在RILConstants.java和ril.h中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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中。












                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值