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"
- };