Android源码目录hardware/ril/libril中总共包含5个C/CPP文件,它们分别是ril_commands.h、ril_unsol_commands.h、ril_event.h、ril_event.cpp和ril.cpp。这篇文章主要分析ril.cpp文件。
我们可以将该文件划分为定义部分和实现部分,先来看定义部分:
#define LOG_TAG "RILC"
#include <hardware_legacy/power.h>
#include <telephony/ril.h>
#include <telephony/ril_cdma_sms.h>
#include <cutils/sockets.h>
#include <cutils/jstring.h>
#include <cutils/record_stream.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <pthread.h>
#include <binder/Parcel.h>
#include <cutils/jstring.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <assert.h>
#include <ctype.h>
#include <alloca.h>
#include <sys/un.h>
#include <assert.h>
#include <netinet/in.h>
#include <cutils/properties.h>
#include <ril_event.h>
namespace android {
#define PHONE_PROCESS "radio"
#define SOCKET_NAME_RIL "rild"
#define SOCKET_NAME_RIL_DEBUG "rild-debug"
#define ANDROID_WAKE_LOCK_NAME "radio-interface"
#define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
// match with constant in RIL.java
#define MAX_COMMAND_BYTES (8 * 1024)
// Basically: memset buffers that the client library
// shouldn't be using anymore in an attempt to find
// memory usage issues sooner.
#define MEMSET_FREED 1
// 常见的获取数组元素个数的方法
#define NUM_ELEMS(a) (sizeof (a) / sizeof (a)[0])
// 返回两数中较小者
#define MIN(a,b) ((a)<(b) ? (a) : (b))
/* 回复类型:经过请求的回复和未经请求的回复*/
#define RESPONSE_SOLICITED 0
#define RESPONSE_UNSOLICITED 1
/* Negative values for private RIL errno's */
#define RIL_ERRNO_INVALID_RESPONSE -1
// request, response, and unsolicited msg print macro
// 即打印缓冲区printBuf的大小
#define PRINTBUF_SIZE 8096
// Enable RILC log
#define RILC_LOG 0
#if RILC_LOG
// 三个宏的调用顺序是startRequest - printRequest - closeRequest
// 这样打印出来的请求命令将包含在()中
#define startRequest sprintf(printBuf, "(")
#define closeRequest sprintf(printBuf, "%s)", printBuf)
#define printRequest(token, req) \
LOGD("[%04d]> %s %s", token, requestToString(req), printBuf)
// 三个宏的调用顺序是startResponse - printResponse - closeResponse
// 这样打印出来的回复信息将包含在{}中
#define startResponse sprintf(printBuf, "%s {", printBuf)
#define closeResponse sprintf(printBuf, "%s}", printBuf)
#define printResponse LOGD("%s", printBuf)
#define clearPrintBuf printBuf[0] = 0
#define removeLastChar printBuf[strlen(printBuf)-1] = 0
#define appendPrintBuf(x...) sprintf(printBuf, x)
#else
#define startRequest
#define closeRequest
#define printRequest(token, req)
#define startResponse
#define closeResponse
#define printResponse
#define clearPrintBuf
#define removeLastChar
#define appendPrintBuf(x...)
#endif
// 唤醒类型:不唤醒,部分唤醒
enum WakeType {DONT_WAKE, WAKE_PARTIAL};
// "经过请求的回复"结构体定义:请求号,命令分发处理函数,返回结果响应函数
// 该结构体的取值见ril_commands.h文件
typedef struct {
int requestNumber;
void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
int(*responseFunction) (Parcel &p, void *response, size_t responselen);
} CommandInfo;
//"未经请求的回复"结构体定义:请求号,事件响应函数,唤醒类型
// 该结构体的取值见ril_unsol_commands.h文件
typedef struct {
int requestNumber;
int (*responseFunction) (Parcel &p, void *response, size_t responselen);
WakeType wakeType;
} UnsolResponseInfo;
// 请求信息结构体,封装CommandInfo,串成链表
typedef struct RequestInfo {
int32_t token; //this is not RIL_Token
CommandInfo *pCI;
struct RequestInfo *p_next;
char cancelled;
char local; // responses to local commands do not go back to command process
} RequestInfo;
// 用户回调信息结构体
typedef struct UserCallbackInfo {
RIL_TimedCallback p_callback; // 回调函数
void *userParam; // 回调函数的参数
struct ril_event event; // ril event
struct UserCallbackInfo *p_next; // 指向下一个回调信息结构(链表形式)
} UserCallbackInfo;
/*******************************************************************/
// 初始化回调结构
RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
static int s_registerCalled = 0;
static pthread_t s_tid_dispatch; // 分发处理线程ID
static pthread_t s_tid_reader; // 读者线程ID
static int s_started = 0;
// 文件描述符初始化
static int s_fdListen = -1;
static int s_fdCommand = -1;
static int s_fdDebug = -1;
static int s_fdWakeupRead;
static int s_fdWakeupWrite;
// 5个相关的事件
static struct ril_event s_commands_event;
static struct ril_event s_wakeupfd_event;
static struct ril_event s_listen_event;
static struct ril_event s_wake_timeout_event;
static struct ril_event s_debug_event;
static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0};
// 初始化互斥量和条件变量
static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
static RequestInfo *s_pendingRequests = NULL;
static RequestInfo *s_toDispatchHead = NULL;
static RequestInfo *s_toDispatchTail = NULL;
static UserCallbackInfo *s_last_wake_timeout_info = NULL;
static void *s_lastNITZTimeData = NULL;
static size_t s_lastNITZTimeDataSize;
#if RILC_LOG
static char printBuf[PRINTBUF_SIZE]; // 缓存打印信息的数组
#endif
/*******************************************************************/
// dispatch*系列函数是基带处理器对应用处理器请求的处理函数
static void dispatchVoid (Parcel& p, RequestInfo *pRI);
static void dispatchString (Parcel& p, RequestInfo *pRI);
static void dispatchStrings (Parcel& p, RequestInfo *pRI);
static void dispatchInts (Parcel& p, RequestInfo *pRI);
static void dispatchDial (Parcel& p, RequestInfo *pRI);
static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
static void dispatchRaw(Parcel& p, RequestInfo *pRI);
static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI);
static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI);
static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI);
static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI);
static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI);
// response*系列函数是应用处理器对基带处理器消息的响应函数
// 包括请求回复响应函数和事件响应函数
static int responseInts(Parcel &p, void *response, size_t responselen);
static int responseStrings(Parcel &p, void *response, size_t responselen);
static int responseString(Parcel &p, void *response, size_t responselen);
static int responseVoid(Parcel &p, void *response, size_t responselen);
static int responseCallList(Parcel &p, void *response, size_t responselen);
static int responseSMS(Parcel &p, void *response, size_t responselen);
static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
static int responseCallForwards(Parcel &p, void *response, size_t responselen);
static int responseDataCallList(Parcel &p, void *response, size_t responselen);
static int responseRaw(Parcel &p, void *response, size_t responselen);
static int responseSsn(Parcel &p, void *response, size_t responselen);
static int responseSimStatus(Parcel &p, void *response, size_t responselen);
static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen);
static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen);
static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
static int responseCellList(Parcel &p, void *response, size_t responselen);
static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen);
static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen);
static int responseCallRing(Parcel &p, void *response, size_t responselen);
static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen);
static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen);
// 将数据结构信息转换成字符串输出
extern "C" const char * requestToString(int request);
extern "C" const char * failCauseToString(RIL_Errno);
extern "C" const char * callStateToString(RIL_CallState);
extern "C" const char * radioStateToString(RIL_RadioState);
#ifdef RIL_SHLIB
extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
size_t datalen);
#endif
static UserCallbackInfo * internalRequestTimedCallback
(RIL_TimedCallback callback, void *param,
const struct timeval *relativeTime);
/** Index == requestNumber */
// 很不错的一个用法,由于数组元素太多,为了代码的整洁清晰,
// 将数组元素的定义放在一个单独的头文件中,并用#include进来即可
static CommandInfo s_commands[] = {
#include "ril_commands.h"
};
static UnsolResponseInfo s_unsolResponses[] = {
#include "ril_unsol_commands.h"
};
To Be Continued