目录
一、前言
二、框架
三、什么是RIL
四、RIL请求消息
五、RIL Receiver
六、RIL Sender
一、前言
Android作为一个通用的移动平台,其首要的功能就是通话、短信以及上网等通信功能。那么,从系统的角度来看,Android究竟是怎么实现与网络的交互的了? 就来看一看Android中负责通信功能的Telephony中间层,通常也被称之为RIL(Radio Interface Layer)。
由于 Android 开发者使用的 Modem 是不一样的,各种指令格式,初始化序列都可能不一样,GSM 和 CDMA 就差别更大了,所以为了消除这些差别,Android 设计者将RIL做了一个抽象,使用一个虚拟电话的概念。
这个虚拟电话对象就是GSMPhone、CDMAPhone, Phone 对象所提供的功能协议,以及要求下层的支撑环境都有一个统一的描述,这个底层描述的实现就是靠RIL来完成适配。
// 电话状态跟踪
public abstract class CallTracker extends Handler
// 无线服务状态跟踪
public class ServiceStateTracker extends Handler
// 数据连接状态跟踪
public class DcTracker extends Handler;
以上三个 Tracker 对象负责与 RIL 类的 Java 对象进行交互,而这些交互在 RIL 层中的处理是与 Modem 基于串口连接的AT命令的发送和执行,最终完成语音通话、网络服务状态和网络数据连接的控制和管理。
二、框架
Android手机要实现与网络端的通信,需要跨越两个层:
- RIL Java(RILJ):负责将上层APP的通信请求发送给HAL层;
- RIL C++(RILD):系统守护进程,负责将RILJ的请求命令发送给CP(Communication Processor)
三、什么是RIL
简单的说,RIL(Radio Interface Layer),就是将应用程序的通信请求发送给CP的中间层,其包括两个部分,一个是Java层RILJ,一个是C++层(不妨看作是CP对应的HAL层)RILD。
RILJ属于系统Phone进程的一部分,随Phone进程启动而加载;而RILD守护进程是通过Android的Init进程进行加载的。 下图是一个Android RIL的一个结构图。整个通信过程有四个层:
- 最上层的是应用程序,如通话,短信以及SIM卡管理,它们主要负责将用户的指令发送到RIL Framework(以后统称RILJ);
- RILJ为上层提供了通用的API,如TelephonyManager(包括通话,网络状态; SubscriptionManager(卡状态)以及SmsManager等,同时RILJ还负责维持与RILD的通信,并将上层的请求发送给RILD;
- RILD是系统的守护进程,对于支持通话功能的移动平台是必不可少的。RILD的功能主要功能是将RILJ发送过来的请求继续传递给CP,同时会及时将CP的状态变化发送给RILJ;
- Linux驱动层:kernel驱动层接受到数据后,将指令传给CP,最后由CP发送给网络端,等网络返回结果后,CP将传回给RILD;
四、RIL请求消息
RIL Solicited消息
终端主动请求消息: Dial 拨号、Answer 接听电话、Hangup 挂断电话
public interface RILConstants {
-----------------------------------------
int RIL_REQUEST_GET_SIM_STATUS = 1;
-----------------------------------------
int RIL_REQUEST_DIAL = 10;
int RIL_REQUEST_GET_IMSI = 11;
int RIL_REQUEST_HANGUP = 12;
-----------------------------------------
int RIL_REQUEST_GET_IMEI = 38;
-----------------------------------------
int RIL_REQUEST_UPDATE_ADN_RECORD = 141;
-----------------------------------------
int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
}
RIL?Unsolicited消息
Modem 硬件主动上报的消息: 来电、接通电话、接收短信、基站信息等消息
public interface RILConstants {
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
int RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002;
int RIL_UNSOL_RESPONSE_NEW_SMS = 1003;
int RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT = 1004;
int RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM = 1005;
----------------------------------------------------------
int RIL_UNSOL_RESPONSE_ADN_INIT_DONE = 1047;
int RIL_UNSOL_RESPONSE_ADN_RECORDS = 1048;
}
RILJ CommandsInterface.java
public interface CommandsInterface {
// 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;
}
}
}
BaseCommands.java
public abstract class BaseCommands implements CommandsInterface {
// RegistrantList 注册的消息列表
protected RegistrantList mCallStateRegistrants = new RegistrantList();
protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
}
RIL.Java–RILRequest?
// 请求消息体
class RILRequest {
static AtomicInteger sNextSerial = new AtomicInteger(0); // 下一个 RILRequest 对象编号
private static Object sPoolSync = new Object(); // 用于同步访问
private static RILRequest sPool = null; // 保存下一个处理的 RILRequest 对象
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 4; // 缓存池大小
int mSerial; // 当前请求编号
int mRequest; // RIL 请求类型
Message mResult; // 保存 RIL 请求的Message对象
RILRequest mNext; // 下一个 RILRequest 处理对象
/** * Retrieves a new RILRequest instance from the pool. * * @param request RIL_REQUEST_* * @param result sent when operation completes * @return a RILRequest instance from the pool. */
static RILRequest obtain(int request, Message result) {
RILRequest rr = null;
synchronized(sPoolSync) {
if (sPool != null) {
rr = sPool;
sPool = rr.mNext;
rr.mNext = null;
sPoolSize--;
}
}
if (rr == null) {
rr = new RILRequest();
}
rr.mSerial = sNextSerial.getAndIncrement();
rr.mRequest = request;
rr.mResult = result;
rr.mParcel = Parcel.obtain();
rr.mWakeLockType = RIL.INVALID_WAKELOCK;
rr.mStartTimeMs = SystemClock.elapsedRealtime();
if (result != null && result.getTarget() == null) {
throw new NullPointerException("Message target must not be null");
}
// first elements in any RIL Parcel
rr.mParcel.writeInt(request);
rr.mParcel.writeInt(rr.mSerial);
return rr;
}
// RIL 请求返回异常或者失败的处理
void onError(int error, Object ret) {
CommandException ex;
ex = CommandException.fromRilErrno(error);
if (RIL.RILJ_LOGD) Rlog.d(LOG_TAG, serialString() + "< "
+ RIL.requestToString(mRequest)
+ " error: " + ex + " ret=" + RIL.retToString(mRequest, ret));
if (mResult != null) {
AsyncResult.forMessage(mResult, ret, ex);
mResult.sendToTarget();
}
if (mParcel != null) {
mParcel.recycle();
mParcel = null;
}
}
}
?RIL.Java
public final class RIL extends BaseCommands implements CommandsInterface {
HandlerThread mSenderThread;
RILSender mSender;
Thread mReceiverThread;
RILReceiver mReceiver;
// 请求消息对象列表
// RILJ 发起请求消息时,将 RILRequest 请求对象保存在 mRequestsList 列表中;
// RILC 处理完成返回消息后,将此消息从 mRequestsList 列表移除,
// 这说明正常情况下 Request 和 Response处于一一对应的关系
SparseArray<RILRequest> mRequestList = new SparseArray<RILRequest>();
// 向RILC发出请求消息
class RILSender extends Handler implements Runnable {
@Override
public void handleMessage(Message msg) {
RILRequest rr = (RILRequest)(msg.obj);
RILRequest req = null;
switch (msg.what) {
case EVENT_SEND:
case EVENT_SEND_ACK:
LocalSocket s;
s = mSocket;
---------------------------------------------
// 向 Socket 写入请求消息
s.getOutputStream().write(dataLength);
s.getOutputStream().write(data);
---------------------------------------------
break;
}
}
}
// 接收RILC发出的消息
class RILReceiver implements Runnable {
// 循环监听mSocket上报的消息
@Override
public void run() {
------------------------------------------------------------------
for (;;) {
----------------------------------------------------------
s = new LocalSocket();
l = new LocalSocketAddress(rilSocket,
LocalSocketAddress.Namespace.RESERVED);
s.connect(l);
----------------------------------------------------------
InputStream is = mSocket.getInputStream();
for (;;) {
Parcel p;
length = readRilMessage(is, buffer);
p = Parcel.obtain();
p.unmarshall(buffer, 0, length);
p.setDataPosition(0);
//Rlog.v(RILJ_LOG_TAG, "Read packet: " + length + " bytes");
processResponse(p); // 处理 RILC 上报的消息
p.recycle();
}
}
--------------------------------------------------------------------
}
}
// RILC 返回的消息处理
private void processResponse (Parcel p) {
int type;
type = p.readInt();
if (type == RESPONSE_UNSOLICITED || type == RESPONSE_UNSOLICITED_ACK_EXP) {
// 处理 Modem 主动上报的消息
processUnsolicited (p, type);
} else if (type == RESPONSE_SOLICITED || type == RESPONSE_SOLICITED_ACK_EXP) {
// 处理 RILJ 请求返回的消息
RILRequest rr = processSolicited (p, type);
if (rr != null) {
if (type == RESPONSE_SOLICITED) {
decrementWakeLock(rr);
}
rr.release();
return;
}
} else if (type == RESPONSE_SOLICITED_ACK) {
int serial;
serial = p.readInt();
RILRequest rr;
synchronized (mRequestList) {
rr = mRequestList.get(serial);
}
if (rr == null) {
Rlog.w(RILJ_LOG_TAG, "Unexpected solicited ack response! sn: " + serial);
} else {
decrementWakeLock(rr);
if (RILJ_LOGD) {
riljLog(rr.serialString() + " Ack < " + requestToString(rr.mRequest));
}
}
}
}
// 处理 Modem 主动上报的消息
private void processUnsolicited(Parcel p, int type) {
int response;
Object ret;
response = p.readInt();
// 组装返回对象ret
try {
switch (response) {
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
ret = responseVoid(p);
break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
ret = responseVoid(p);
break;
-----------------------------------------------
}
} catch (Throwable tr) {
Rlog.e(RILJ_LOG_TAG, "Exception processing unsol response: " + response +
"Exception:" + tr.toString());
return;
}
// 发送出 Registant消息通知
switch (response) {
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);
break;
-------------------------------------------------------------------------
case RIL_UNSOL_SIGNAL_STRENGTH:
// Note this is set to "verbose" because it happens
// frequently
if (RILJ_LOGV) unsljLogvRet(response, ret);
// 发出消息通知,此通知是 ServiceStaterTracker接收和处理的
if (mSignalStrengthRegistrant != null) {
mSignalStrengthRegistrant.notifyRegistrant(
new AsyncResult(null, ret, null));
}
break;
}
}
// 处理客户端向 RILC 请求返回的消息
private RILRequest processSolicited(Parcel p, int type) {
int serial, error;
boolean found = false;
serial = p.readInt();
error = p.readInt();
RILRequest rr;
// 从 mRequestList中找到消息,并从列表移除,从而保证请求消息和返回消息的一一对应关系
rr = findAndRemoveRequestFromList(serial);
if (rr == null) {
Rlog.w(RILJ_LOG_TAG, "Unexpected solicited response! sn: "
+ serial + " error: " + error);
return null;
}
----------------------------------------------------------------------
if (error == 0 || p.dataAvail() > 0) {
// either command succeeds or command fails but with data payload
try {
switch (rr.mRequest) {
case RIL_REQUEST_GET_SIM_STATUS:
ret = responseIccCardStatus(p);
break;
case RIL_REQUEST_DIAL:
ret = responseVoid(p);
break;
case RIL_REQUEST_GET_IMSI:
ret = responseString(p);
break;
---------------------------------------------------------------
} catch (Throwable tr) {
// Exceptions here usually mean invalid RIL responses
Rlog.w(RILJ_LOG_TAG, rr.serialString() + "< "
+ requestToString(rr.mRequest)
+ " exception, possible invalid RIL response", tr);
if (rr.mResult != null) {
AsyncResult.forMessage(rr.mResult, null, tr);
rr.mResult.sendToTarget();
}
return rr;
}
}
---------------------------------------------------------------------------
if (error == 0) {
if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
+ " " + retToString(rr.mRequest, ret));
if (rr.mResult != null) {
// 发出消息通知,完成请求消息的回调操作
AsyncResult.forMessage(rr.mResult, ret, null);
rr.mResult.sendToTarget();
}
}
-----------------------------------------------------------------------------
}
// 向 RILC 发送请求消息
private void send(RILRequest rr) {
Message msg;
if (mSocket == null) {
rr.onError(RADIO_NOT_AVAILABLE, null);
rr.release();
return;
}
msg = mSender.obtainMessage(EVENT_SEND, rr);
acquireWakeLock(rr, FOR_WAKELOCK);
msg.sendToTarget();
}
@Override
public void getIMEI(Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEI, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
send(rr);
}
@Override
public void getSignalStrength (Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
send(rr);
}
// 打开移动数据链接
@Override
public void setupDataCall(int radioTechnology, int profile, String apn,
String user, String password, int authType, String protocol,
Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
rr.mParcel.writeInt(7);
rr.mParcel.writeString(Integer.toString(radioTechnology + 2));
rr.mParcel.writeString(Integer.toString(profile));
rr.mParcel.writeString(apn);
rr.mParcel.writeString(user);
rr.mParcel.writeString(password);
rr.mParcel.writeString(Integer.toString(authType));
rr.mParcel.writeString(protocol);
if (RILJ_LOGD) riljLog(rr.serialString() + "> "
+ requestToString(rr.mRequest) + " " + radioTechnology + " "
+ profile + " " + apn + " " + user + " "
+ password + " " + authType + " " + protocol);
mMetrics.writeRilSetupDataCall(mInstanceId, rr.mSerial,
radioTechnology, profile, apn, authType, protocol);
send(rr);
}
}
五、RIL Receiver
接收步骤
- 分析接收到的Parcel,根据类型不同进行处理
- 根据数据中的Token(mSerail),反查mRequest,找到对应的请求信息
- 将是数据转换成结果数据
- 将结果放在RequestMessage中发回到请求的发起者
六、RIL Sender
发送步骤
- 生成RILRequest,此时将生成m_Serial(请求的Token)并将请求号,数据,及其Result Message 对象填入到RILRequest中
- 使用send将RILRequest打包到EVENT_SEND消息中发送到到RIL Sender Handler
- RilSender 接收到EVENT_SEND消息,将RILRequest通过套接口发送到RILD,同时将RILRequest保存在mRequest中以便应答消息的返回
?
|