从onRequest可以看出,reference中对所有的命令请求进行判别,然后选择不同的处理方式。对于尝试得到SIM状态这个请求来说,不仅需要通过getCardStatus得到SIM卡状态,而且还需要调用RIL_onRequestComplete将得到的状态通过Eventloop返回给RILJ。我们先看给Modem发送数据的过程 static int getCardStatus(RIL_CardStatus_v6 **pp_card_status) { //SIM卡所有可能的状态
static RIL_AppStatus app_status_array[] = { //SIM_ABSENT = 0 SIM不存在
{ RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN, NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN }, // SIM_NOT_READY = 1 SIM未就绪
{ RIL_APPTYPE_SIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN, NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN }, // SIM_READY = 2 SIM就绪
{ RIL_APPTYPE_SIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY, NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN }, ....
};
//查询SIM状态,将AT命令发送到Modem,然后得到Modem的数据 int sim_status = getSIMStatus();
RIL_CardStatus_v6 *p_card_status = malloc(sizeof(RIL_CardStatus_v6));
if (num_apps != 0) {
// Only support one app, gsm p_card_status->num_applications = 2;
p_card_status->gsm_umts_subscription_app_index = 0; p_card_status->cdma_subscription_app_index = 1;
// Get the correct app status
p_card_status->applications[0] = app_status_array[sim_status];
p_card_status->applications[1] = app_status_array[sim_status + RUIM_ABSENT]; }
*pp_card_status = p_card_status; //将状态返回给reference return RIL_E_SUCCESS; }
继续看发送过程
static SIM_Status getSIMStatus() {
//将命令转换为AT命令发送到Modem,而modem的回应放到p_response中 err = at_send_command_singleline(\
//取得返回值
cpinLine = p_response->p_intermediates->line; err = at_tok_start (&cpinLine);
err = at_tok_nextstr(&cpinLine, &cpinResult);
//根据返回值得到当前SIM卡状态 if (0 == strcmp (cpinResult, \ //PIN锁 ret = SIM_PIN; goto done;
} else if (0 == strcmp (cpinResult, \
//PUK锁 ret = SIM_PUK; goto done;
} else if (0 == strcmp (cpinResult, \ return SIM_NETWORK_PERSONALIZATION; } else if (0 != strcmp (cpinResult, \ { //SIM卡不存在 ret = SIM_ABSENT; goto done; } //返回结果 done:
at_response_free(p_response); return ret; }
继续看at_send_command_singleline的发送过程: @atchannel.c
int at_send_command_singleline (const char *command, const char *responsePrefix, ATResponse **pp_outResponse) {
err = at_send_command_full (command, SINGLELINE, responsePrefix, NULL, 0, pp_outResponse);
return err; }
static int at_send_command_full (const char *command, ATCommandType type, const char *responsePrefix, const char *smspdu,
long long timeoutMsec, ATResponse **pp_outResponse) {
//发送
err = at_send_command_full_nolock(command, type, responsePrefix, smspdu, timeoutMsec, pp_outResponse); return err; } 继续看
static int at_send_command_full_nolock (const char *command, ATCommandType type, const char *responsePrefix, const char *smspdu, long long timeoutMsec, ATResponse **pp_outResponse) {
//给Modem发消息AT err = writeline (command);
//创建新的sp_response作为回应 sp_response = at_response_new();
//上面发送完消息后需要阻塞等待Modem回应
while (sp_response->finalResponse == NULL && s_readerClosed == 0) { if (timeoutMsec != 0) {
//线程进入阻塞状态,等待另一线程满足s_commandcond 后解除
err = pthread_cond_timeout_np(&s_commandcond, &s_commandmutex, timeoutMsec); } }
if (pp_outResponse == NULL) { //释放sp_response
at_response_free(sp_response); } else {
reverseIntermediates(sp_response); //将回应发送给当初请求AT的线程 *pp_outResponse = sp_response; } return err; }
在上面的函数中,完成了两个重要动作:1、通过writeline发送数据到Modem;2、阻塞当前线程,等待Modem回应。我们先来看writeline的过程: static int writeline (const char *s) {
size_t len = strlen(s); ssize_t written;
//Log信息
RLOGD(\ while (cur < len) { do {
//s_fd就是Modem与RILC之间的串口 written = write (s_fd, s + cur, len - cur); } while (written < 0 && errno == EINTR);
cur += written; }