Android源码目录hardware/ril/libril中总共包含5个C/CPP文件,它们分别是ril_commands.h、ril_unsol_commands.h、ril_event.h、ril_event.cpp和ril.cpp。这篇文章主要分析commands相关的两个头文件,这两个文件主要定义了所有telephony可以接收的命令或者响应的事件类型,以及相应的处理函数。

    进行源码分析前,我们必须先知道目前主流智能手机的硬件架构中有两个处理器,一个称为Application Processor(AP),主要用于运行操作系统,执行应用程序;一个称为Baseband Processor(BP),专门负责手机中和射频无线通信相关的功能。AP和BP芯片间通信基于串口,通信协议是广泛使用的AT指令。

    接着来了解下RIL中的两种Response类型:

    一是Solicited Response(经过请求的回复),应用的场景是AP主动向BP发送一个AT指令,请求BP进行相应处理并在处理结束时回复一个AT指令通知AP执行的结果。源码中对应的文件是ril_commands.h。

    一是Unsolicited Response(未经请求的回复),应用场景是BP主动向AP发送AT指令,用于通知AP当前系统发生的与Telephony相关的事件,例如网络信号变化,有电话呼入等。源码中对应的文件是ril_unsol_commands.h。

首先当然先看下ril_commands.h文件:

// 每一列分别对应:
// BP接收的请求 - BP对请求的处理函数 - AP对返回结果的处理函数
{0, NULL, NULL}, //none

// #define RIL_REQUEST_GET_SIM_STATUS 1(in ril.h)
// 获取SIM接口和SIM卡的状态,传入参数"data"是NULL
// 响应函数"response"是const RIL_CardStatus *
// 有效的返回码:无,该函数必须保证成功调用
{RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus},

// #define RIL_REQUEST_ENTER_SIM_PIN 2
// 请求pin码的输入,"data"是const char**
// 其中((const char**)data)[0]是pin码
// "response"是int*,其中((int*)response)[0]是剩余可输入次数
// 有效的返回码:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT
{RIL_REQUEST_ENTER_SIM_PIN, dispatchStrings, responseInts},

// #define RIL_REQUEST_ENTER_SIM_PUK 3
// 请求PUK码和新的PIN码的输入,"data"是const char**
// 其中((const char**)data)[0]是PUK码,((const char**)data)[1]是新的PIN码
// "response"是int*,其中((int*)response)[0]是剩余可输入次数
// 有效的返回码:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT
{RIL_REQUEST_ENTER_SIM_PUK, dispatchStrings, responseInts},

// #define RIL_REQUEST_ENTER_SIM_PIN2 4
// 请求PIN2码的输入,"data"是const char**
// 其中((const char**)data)[0]是pin2码
// "response"是int*,其中((int*)response)[0]是剩余可输入次数
// 有效的返回码:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT
{RIL_REQUEST_ENTER_SIM_PIN2, dispatchStrings, responseInts},

// #define RIL_REQUEST_ENTER_SIM_PUK2 5
// 请求PUK2码和新的PIN2码的输入,"data"是const char**
// 其中((const char**)data)[0]是PUK2码,((const char**)data)[1]是新的PIN2码
// "response"是int*,其中((int*)response)[0]是剩余可输入次数
// 有效的返回码:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT
{RIL_REQUEST_ENTER_SIM_PUK2, dispatchStrings, responseInts},

// #define RIL_REQUEST_CHANGE_SIM_PIN 6
// 请求更改PIN码,"data"是const char**
// 其中,((const char**)data)[0]是旧PIN码,((const char**)data)[1]是新PIN码
// "response"是int*,其中((int*)response)[0]是剩余可输入次数
// 有效的返回码:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT
{RIL_REQUEST_CHANGE_SIM_PIN, dispatchStrings, responseInts},

// #define RIL_REQUEST_CHANGE_SIM_PIN2 7
// 请求更改PIN2码,"data"是const char**
// 其中,((const char**)data)[0]是旧PIN2码,((const char**)data)[1]是新PIN2码
// "response"是int*,其中((int*)response)[0]是剩余可输入次数
// 有效的返回码:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT
{RIL_REQUEST_CHANGE_SIM_PIN2, dispatchStrings, responseInts},

// #define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8
// 请求输入网络个人码以便去激活,"data"是const char**
// 其中,((const char**)data))[0]是网络个人码
// "Response"是int*,((int*)response)[0]是剩余可输入次数
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT
{RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, dispatchStrings, responseInts},

// #define RIL_REQUEST_GET_CURRENT_CALLS 9
// 请求获取当前呼叫列表,"data"是NULL
// "response"类型必须是const RIL_Call **
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL_REQUEST_GET_CURRENT_CALLS, dispatchVoid, responseCallList},

// #define RIL_REQUEST_DIAL 10
// 初始化一个语音呼叫,"data"是const RIL_Dial*类型
// "response"是NULL
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL_REQUEST_DIAL, dispatchDial, responseVoid},

// #define RIL_REQUEST_GET_IMSI 11
// 获取SIM卡中的国际移动用户识别码IMSI,只在RADIO_STATE_SIM_READY时可用
// "data"是NULL,"response"是包含IMSI的const char*类型
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL_REQUEST_GET_IMSI, dispatchVoid, responseString},

// #define RIL_REQUEST_HANGUP 12
// 挂断某一激活的通话,类似AT指令:AT+CHLD=1x;在HANDUP请求返回时,RIL将在
// 下一次RIL_REQUEST_GET_CURRENT_CALLS请求时,显示这个连接不可用
// "data"是int*,其中((int*)data)[0]包含连接的索引,即上面CHLD中的x值
// "response"是NULL
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL_REQUEST_HANGUP, dispatchInts, responseVoid},

// #define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13
// 挂断所有等待的或者保持的通话,类似AT指令:AT+CHLD=0;在HANDUP请求返回时,
// RIL将在下一次RIL_REQUEST_GET_CURRENT_CALLS请求时,显示这个连接不可用
// "data"和"response"都是NULL
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, dispatchVoid, responseVoid},

// #define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14
// 释放所有激活的通话并激活保持的或者等待的通话,类似AT指令:AT+CHLD=1
// 在HANDUP请求返回时
// RIL将在下一次RIL_REQUEST_GET_CURRENT_CALLS请求时,显示这个连接不可用
// "data"和"response"都是NULL
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, dispatchVoid, responseVoid},

// #define RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE 15
// 通话连接状态的转换,将所有激活的通话转为保持或等待状态,或者将保持或等待的
// 通话转为激活状态,类似AT指令:AT+CHLD=2
// 状态的转换有以下几种,假设通话1处于等待态,通话处于是激活态
// 转换前 转换后
// 通话1 通话2 通话1 通话2
// ACTIVE HOLDING HOLDING ACTIVE
// ACTIVE WAITING HOLDING ACTIVE
// HOLDING WAITING HOLDING ACTIVE
// ACTIVE IDLE HOLDING IDLE
// IDLE IDLE IDLE IDLE
// "data"和"response"都是NULL
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, dispatchVoid, responseVoid},

// #define RIL_REQUEST_CONFERENCE 16
// 请求加入电话会议,类似AT指令:AT+CHLD=3
// "data"和"response"都是NULL
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL__CONFERENCE, dispatchVoid, responseVoid},

// #define RIL_REQUEST_UDUB 17
// 发送用户确定用户忙UDUB(user determined user busy)信号
// "data"和"response"都是NULL
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL_REQUEST_UDUB, dispatchVoid, responseVoid},

// #define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18
// 请求最近一次通话中断的错误码,"data"是NULL,"response"是int*
// ((int*)response)[0]是RIL_LastCallFailCause类型。
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE
{RIL_REQUEST_LAST_CALL_FAIL_CAUSE, dispatchVoid, responseInts},

// #define RIL_REQUEST_SIGNAL_STRENGTH 19
// 请求当前的信号强度等相关信息,当天线打开时必须返回成功
// "data"是NULL,"response"是const RIL_SignalStrength
// 有效返回码是:SUCCESS/RADIO_NOT_AVAILABLE
{RIL_REQUEST_SIGNAL_STRENGTH, dispatchVoid, responseRilSignalStrength},

// #define RIL_REQUEST_REGISTRATION_STATE 20
// 请求当前的注册状态,"data"是NULL,"response"是const char**类型
// ((const char **)response)[0]表示注册状态,取值如下:
// 0 - 未注册,移动终端MT当前没有搜索新的运营商去注册
// 1 - 已注册,本地网络
// 2 - 未注册,移动终端MT当前正在搜索新的运营商去注册
// 3 - 拒绝注册
// 4 - 未知
// 5 - 已注册,漫游
// 10 - 类似0,但指示紧急呼叫使能
// 12 - 类似2,但指示紧急呼叫使能
// 13 - 类似3,但指示紧急呼叫使能
// 14 - 类似4,但指示紧急呼叫使能
// ((const char **)response)[1],如果注册在GSM/WCDMA网络上,则表示LAC,
// 否则是NULL,有效的LAC值是0x0000 -- 0xffff
// ((const char **)response)[2],如果注册在GSM/WCDMA网络上,表示CID,
// 否则是NULL,有效的CID值是0x00000000 -- 0xffffffff
// GSM网络中,CID指Cell ID,以16bits表示
// UMTS网络中(3G网络),CID指UMTS Cell Identity,以28bits表示
// ((const char **)response)[3],指示可用的无线技术:
// 0 - Unknown, 1 - GPRS, 2 - EDGE, 3 - UMTS, 4 - IS95A, 5 - IS95B
// 6 - 1xRTT, 7 - EvDo Rev.0, 8 - EvDo Rev.A, 9 - HSDPA, 10 - HSUPA
// 11 - HSPA, 12 - EVDO Rev B
// ((const char **)response)[4],CDMA网络中表示基站ID,否则为NULL
// 基站ID是十进制表示的
// ((const char **)response)[5],CDMA网络中表示基站纬度,否则为NULL
// ((const char **)response)[6],CDMA网络中表示基站经度,否则为NULL
// ((const char **)response)[7],CDMA网络中表示是否支持并发服务
// 0 - 不支持,1 - 支持
// ((const char **)response)[8],CDMA网络中表示系统ID,否则为NULL
// 取值范围是0 - 32767
// ((const char **)response)[9],CDMA网络中表示网络ID,否则为NULL
// 取值范围是0 - 65535
// ((const char **)response)[10],CDMA和EVDO网络中表示TSB-58漫游指示符
// 否则为NULL,有效值是0 - 255
// ((const char **)response)[11],CDMA和EVDO网络中表示当前系统是否在PRL中
// 否则为NULL,0 - 不在,1 - 在
// ((const char **)response)[12],CDMA和EVDO网络中表示默认的TSB-58漫游指示符
// 否则为NULL,有效值是0 - 255
// ((const char **)response)[13],如果注册状态是3(拒绝注册),这个值表示拒绝的
// 原因,取值如下:0 - 一般,1 - 认证失败,2 - IMSI在HLR中是未知的,3 - 非法MS,// 4 - 非法ME,5 - PLMN不允许,6 - 本地网络不允许,7 - 漫游不允许,
// 8 - 本地网络没有可用的蜂窝站点,9 - 网络失效,10 - 持续定位更新拒绝// ((const char **)response)[13],当前蜂窝站点的主要扰码,十进制表示
// 如果未在UMTS网络中注册,或者注册状态未知,则为NULL
// 注意:当注册状态未知时,在Android电话系统中将作为服务不可用来处理
{RIL_REQUEST_REGISTRATION_STATE, dispatchVoid, responseStrings},

To Be Continued