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

    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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值