您的位置:首页 > 移动开发 > Android开发

Android RIL源码研究笔记 の ril (一)

2011-12-09 00:18 441 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: