Android RIL源碼研究筆記 の ril_command (一)

Android源碼目錄hardware/ril/libril中總共包含5個C/CPP文件,它們分別是ril_commands.h、ril_unsol_commands.h、ril_event.h、ril_event.cpp和ril.cpp。這篇文章主要分析commands相關的兩個頭文件,這兩個文件主要定義瞭所有telephony可以接收的命令或者響應的事件類型,以及相應的處理函數。
    進行源碼分析前,我們必須先知道目前主流智能手機的硬件架構中有兩個處理器,一個稱為Application Processor(AP),主要用於運行操作系統,執行應用程序;一個稱為Baseband Processor(BP),專門負責手機中和射頻無線通信相關的功能。AP和BP芯片間通信基於串口,通信協議是廣泛使用的AT指令。
    接著來瞭解下RIL中的兩種Response類型:
    一是Solicited Response(經過請求的回復),應用的場景是AP主動向BP發送一個AT指令,請求BP進行相應處理並在處理結束時回復一個AT指令通知AP執行的結果。源碼中對應的文件是ril_commands.h。
    一是Unsolicited Response(未經請求的回復),應用場景是BP主動向AP發送AT指令,用於通知AP當前系統發生的與Telephony相關的事件,例如網絡信號變化,有電話呼入等。源碼中對應的文件是ril_unsol_commands.h。
首先當然先看下ril_commands.h文件:
[cpp]
// 每一列分別對應: 
// BP接收的請求 – BP對請求的處理函數 – AP對返回結果的處理函數 
{0, NULL, NULL},                   //none 
 
// #define RIL_REQUEST_GET_SIM_STATUS 1(in ril.h) 
// 獲取SIM接口和SIM卡的狀態,傳入參數"data"是NULL 
// 響應函數"response"是const RIL_CardStatus * 
// 有效的返回碼:無,該函數必須保證成功調用 
{RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus}, 
 
// #define RIL_REQUEST_ENTER_SIM_PIN 2 
// 請求pin碼的輸入,"data"是const char** 
// 其中((const char**)data)[0]是pin碼 
// "response"是int*,其中((int*)response)[0]是剩餘可輸入次數 
// 有效的返回碼:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT 
{RIL_REQUEST_ENTER_SIM_PIN, dispatchStrings, responseInts}, 
 
// #define RIL_REQUEST_ENTER_SIM_PUK 3 
// 請求PUK碼和新的PIN碼的輸入,"data"是const char** 
// 其中((const char**)data)[0]是PUK碼,((const char**)data)[1]是新的PIN碼 
// "response"是int*,其中((int*)response)[0]是剩餘可輸入次數 
// 有效的返回碼:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT 
{RIL_REQUEST_ENTER_SIM_PUK, dispatchStrings, responseInts}, 
 
// #define RIL_REQUEST_ENTER_SIM_PIN2 4 
// 請求PIN2碼的輸入,"data"是const char** 
// 其中((const char**)data)[0]是pin2碼 
//  "response"是int*,其中((int*)response)[0]是剩餘可輸入次數 
// 有效的返回碼:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT 
{RIL_REQUEST_ENTER_SIM_PIN2, dispatchStrings, responseInts}, 
 
// #define RIL_REQUEST_ENTER_SIM_PUK2 5 
// 請求PUK2碼和新的PIN2碼的輸入,"data"是const char** 
// 其中((const char**)data)[0]是PUK2碼,((const char**)data)[1]是新的PIN2碼 
// "response"是int*,其中((int*)response)[0]是剩餘可輸入次數 
// 有效的返回碼:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT 
{RIL_REQUEST_ENTER_SIM_PUK2, dispatchStrings, responseInts}, 
 
// #define RIL_REQUEST_CHANGE_SIM_PIN 6 
// 請求更改PIN碼,"data"是const char** 
// 其中,((const char**)data)[0]是舊PIN碼,((const char**)data)[1]是新PIN碼 
// "response"是int*,其中((int*)response)[0]是剩餘可輸入次數 
// 有效的返回碼:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT 
{RIL_REQUEST_CHANGE_SIM_PIN, dispatchStrings, responseInts}, 
 
// #define RIL_REQUEST_CHANGE_SIM_PIN2 7 
// 請求更改PIN2碼,"data"是const char** 
// 其中,((const char**)data)[0]是舊PIN2碼,((const char**)data)[1]是新PIN2碼 
// "response"是int*,其中((int*)response)[0]是剩餘可輸入次數 
// 有效的返回碼:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT 
{RIL_REQUEST_CHANGE_SIM_PIN2, dispatchStrings, responseInts}, 
 
// #define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8 
// 請求輸入網絡個人碼以便去激活,"data"是const char** 
// 其中,((const char**)data))[0]是網絡個人碼 
// "Response"是int*,((int*)response)[0]是剩餘可輸入次數 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE/PASSWORD_INCORRECT 
{RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, dispatchStrings, responseInts}, 
 
// #define RIL_REQUEST_GET_CURRENT_CALLS 9 
// 請求獲取當前呼叫列表,"data"是NULL 
// "response"類型必須是const RIL_Call ** 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL_REQUEST_GET_CURRENT_CALLS, dispatchVoid, responseCallList}, 
 
// #define RIL_REQUEST_DIAL 10 
// 初始化一個語音呼叫,"data"是const RIL_Dial*類型 
// "response"是NULL 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL_REQUEST_DIAL, dispatchDial, responseVoid}, 
 
// #define RIL_REQUEST_GET_IMSI 11 
// 獲取SIM卡中的國際移動用戶識別碼IMSI,隻在RADIO_STATE_SIM_READY時可用 
// "data"是NULL,"response"是包含IMSI的const char*類型 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL_REQUEST_GET_IMSI, dispatchVoid, responseString}, 
 
// #define RIL_REQUEST_HANGUP 12 
// 掛斷某一激活的通話,類似AT指令:AT+CHLD=1x;在HANDUP請求返回時,RIL將在 
// 下一次RIL_REQUEST_GET_CURRENT_CALLS請求時,顯示這個連接不可用 
// "data"是int*,其中((int*)data)[0]包含連接的索引,即上面CHLD中的x值 
// "response"是NULL 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL_REQUEST_HANGUP, dispatchInts, responseVoid}, 
 
// #define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13 
// 掛斷所有等待的或者保持的通話,類似AT指令:AT+CHLD=0;在HANDUP請求返回時, 
// RIL將在下一次RIL_REQUEST_GET_CURRENT_CALLS請求時,顯示這個連接不可用 
// "data"和"response"都是NULL 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, dispatchVoid, responseVoid}, 
 
// #define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14 
// 釋放所有激活的通話並激活保持的或者等待的通話,類似AT指令:AT+CHLD=1 
// 在HANDUP請求返回時 
// RIL將在下一次RIL_REQUEST_GET_CURRENT_CALLS請求時,顯示這個連接不可用 
// "data"和"response"都是NULL 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, dispatchVoid, responseVoid}, 
 
// #define RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE 15 
// 通話連接狀態的轉換,將所有激活的通話轉為保持或等待狀態,或者將保持或等待的 
// 通話轉為激活狀態,類似AT指令:AT+CHLD=2 
// 狀態的轉換有以下幾種,假設通話1處於等待態,通話處於是激活態 
//      轉換前                       轉換後 
// 通話1    通話2              通話1      通話2 
// ACTIVE    HOLDING            HOLDING    ACTIVE 
// ACTIVE    WAITING            HOLDING    ACTIVE 
// HOLDING   WAITING            HOLDING    ACTIVE 
// ACTIVE    IDLE               HOLDING    IDLE 
// IDLE      IDLE               IDLE       IDLE 
// "data"和"response"都是NULL 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, dispatchVoid, responseVoid}, 
 
// #define RIL_REQUEST_CONFERENCE 16 
// 請求加入電話會議,類似AT指令:AT+CHLD=3 
// "data"和"response"都是NULL 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL__CONFERENCE, dispatchVoid, responseVoid}, 
 
// #define RIL_REQUEST_UDUB 17 
// 發送用戶確定用戶忙UDUB(user determined user busy)信號 
// "data"和"response"都是NULL 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL_REQUEST_UDUB, dispatchVoid, responseVoid}, 
 
// #define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18 
// 請求最近一次通話中斷的錯誤碼,"data"是NULL,"response"是int* 
// ((int*)response)[0]是RIL_LastCallFailCause類型。 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE/GENERIC_FAILURE 
{RIL_REQUEST_LAST_CALL_FAIL_CAUSE, dispatchVoid, responseInts}, 
 
// #define RIL_REQUEST_SIGNAL_STRENGTH 19 
// 請求當前的信號強度等相關信息,當天線打開時必須返回成功 
// "data"是NULL,"response"是const RIL_SignalStrength 
// 有效返回碼是:SUCCESS/RADIO_NOT_AVAILABLE 
{RIL_REQUEST_SIGNAL_STRENGTH, dispatchVoid, responseRilSignalStrength}, 
 
// #define RIL_REQUEST_REGISTRATION_STATE 20 
// 請求當前的註冊狀態,"data"是NULL,"response"是const char**類型 
// ((const char **)response)[0]表示註冊狀態,取值如下: 
//  0 – 未註冊,移動終端MT當前沒有搜索新的運營商去註冊 
//  1 – 已註冊,本地網絡 
//  2 – 未註冊,移動終端MT當前正在搜索新的運營商去註冊 
//  3 – 拒絕註冊 
//  4 – 未知 
//  5 – 已註冊,漫遊 
//  10 – 類似0,但指示緊急呼叫使能 
//  12 – 類似2,但指示緊急呼叫使能 
//  13 – 類似3,但指示緊急呼叫使能 
//  14 – 類似4,但指示緊急呼叫使能 
// ((const char **)response)[1],如果註冊在GSM/WCDMA網絡上,則表示LAC, 
// 否則是NULL,有效的LAC值是0x0000 — 0xffff 
// ((const char **)response)[2],如果註冊在GSM/WCDMA網絡上,表示CID, 
// 否則是NULL,有效的CID值是0x00000000 — 0xffffffff 
// GSM網絡中,CID指Cell ID,以16bits表示 
// UMTS網絡中(3G網絡),CID指UMTS Cell Identity,以28bits表示 
// ((const char **)response)[3],指示可用的無線技術: 
// 0 – Unknown, 1 – GPRS, 2 – EDGE, 3 – UMTS, 4 – IS95A, 5 – IS95B 
// 6 – 1xRTT, 7 – EvDo Rev.0, 8 – EvDo Rev.A, 9 – HSDPA, 10 – HSUPA 
// 11 – HSPA, 12 – EVDO Rev B 
// ((const char **)response)[4],CDMA網絡中表示基站ID,否則為NULL 
// 基站ID是十進制表示的 
// ((const char **)response)[5],CDMA網絡中表示基站緯度,否則為NULL 
// ((const char **)response)[6],CDMA網絡中表示基站經度,否則為NULL 
// ((const char **)response)[7],CDMA網絡中表示是否支持並發服務 
// 0 – 不支持,1 – 支持 
// ((const char **)response)[8],CDMA網絡中表示系統ID,否則為NULL 
// 取值范圍是0 – 32767 
// ((const char **)response)[9],CDMA網絡中表示網絡ID,否則為NULL 
// 取值范圍是0 – 65535 
// ((const char **)response)[10],CDMA和EVDO網絡中表示TSB-58漫遊指示符 
// 否則為NULL,有效值是0 – 255 
// ((const char **)response)[11],CDMA和EVDO網絡中表示當前系統是否在PRL中 
// 否則為NULL,0 – 不在,1 – 在 
// ((const char **)response)[12],CDMA和EVDO網絡中表示默認的TSB-58漫遊指示符 
// 否則為NULL,有效值是0 – 255 
// ((const char **)response)[13],如果註冊狀態是3(拒絕註冊),這個值表示拒絕的 
// 原因,取值如下:0 – 一般,1 – 認證失敗,2 – IMSI在HLR中是未知的,3 – 非法MS,// 4 – 非法ME,5 – PLMN不允許,6 – 本地網絡不允許,7 – 漫遊不允許, 
// 8 – 本地網絡沒有可用的蜂窩站點,9 – 網絡失效,10 – 持續定位更新拒絕// ((const char **)response)[13],當前蜂窩站點的主要擾碼,十進制表示 
// 如果未在UMTS網絡中註冊,或者註冊狀態未知,則為NULL 
// 註意:當註冊狀態未知時,在Android電話系統中將作為服務不可用來處理 
{RIL_REQUEST_REGISTRATION_STATE, dispatchVoid, responseStrings}, 

摘自 ASCE1885的專欄

發佈留言