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},