分享

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

 android之情殇 2013-07-24
Android RIL源码研究笔记 の ril (一)
2012-02-11 11:46:48     我来说两句      
收藏    我要投稿
Android源码目录hardware/ril/libril中总共包含5个C/CPP文件,它们分别是ril_commands.h、ril_unsol_commands.h、ril_event.h、ril_event.cpp和ril.cpp。这篇文章主要分析ril.cpp文件。
    我们可以将该文件划分为定义部分和实现部分,先来看定义部分:
[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)) 
 
/* WWW.2CTO.COM 回复类型:经过请求的回复和未经请求的回复*/ 
#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" 
}; 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约