getSIMStatus()-->at_send_command_singleline()->at_send_command_full()->at_send_command_full_nolock(); 因此,我们再次回到getSIMStatus中查看: 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;
} }
在getSIMStatus中,当我们从at_send_command_singleline中返回后,用Modem给的数据p_response->p_intermediates得到了当前SIM的状态。
我们在往上层看,当初是在getCardStatus中调用getSIMStatus的: static int getCardStatus(RIL_CardStatus_v6 **pp_card_status) { //SIM卡所有可能的状态
static RIL_AppStatus app_status_array[] = {
{ RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN, NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN }, { RIL_APPTYPE_SIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN, NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN }, };
//查询SIM状态,将AT命令发送到Modem,然后得到Modem的数据 int sim_status = getSIMStatus(); //得到返回值
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; return RIL_E_SUCCESS; }
在这个函数中,我们通过getSIMStatus得到的int型数据,由app_status_array数组转换为各个更容易理解的状态,然后放入pp_card_status返回值中,返回给父一级。 @reference-ril.c
static void onRequest (int request, void *data, size_t datalen, RIL_Token t) {
switch (request) {
case RIL_REQUEST_GET_SIM_STATUS: { RIL_CardStatus_v6 *p_card_status; char *p_buffer; int buffer_size;
//与Modem交互,发送命令并得到回应 int result = getCardStatus(&p_card_status); p_buffer = (char *)p_card_status; buffer_size = sizeof(*p_card_status); //把回应传回给Eventloop
RIL_onRequestComplete(t, result, p_buffer, buffer_size); freeCardStatus(p_card_status); break; } } }
这个函数就是当Eventloop中有请求时,我们把请求发送到注册的reference库的回调函数中,而reference的回调函数就是onRequest。在这里,当我们从getCardStatus返回后,就把数据转换为buffer,然后通过RIL_onRequestComplete重新返回给Eventloop,当我们去观察这个函数参数时,除了表示成功或失败的result和表示数据的buffer外,还有一个t,而这个t就是我们前面一再提到的令牌。当我们从RILJ发送数据时,就会把一个表示当前这个请求的的令牌传递下去,而当Modem返回数据后,我们再通过这个令牌找到当初发送的请求,然后把数据传递给他。接下来我们看这个函数的具体实现:
#define RIL_onRequestComplete(t, e, response, responselen) s_rilenv->OnRequestComplete(t,e, response, responselen)
我们看到,RIL_onRequestComplete就是s_rilenv的OnRequestComplete函数,而s_rilenv的来历我们在前面已经介绍过,他的各个处理函数都在ril.cpp中。
因此,到这里,我们的流程就又走到了ril.cpp中的RIL_onRequestComplete里面。而从流程上来讲,我们就将从Modem得到的回应,又由reference库交接给了Event端。 接下来要做的就是在Event侧把数据重新返回给RILJ。
3.4、Eventloop把数据返回给RILJ
我们直接来看此时的接收函数: @ril.cpp
void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) { RequestInfo *pRI; pRI = (RequestInfo *)t;
Parcel p;
p.writeInt32 (RESPONSE_SOLICITED); p.writeInt32 (pRI->token); errorOffset = p.dataPosition(); p.writeInt32 (e);
if (response != NULL) {
//先调用当前请求的回调函数
ret = pRI->pCI->responseFunction(p, response, responselen);
if (ret != 0) {
p.setDataPosition(errorOffset); p.writeInt32 (ret); } }
//发送数据给RILJ
sendResponse(p); }
我们看到,在RILC发送数据给RILJ之前,会先调用当前命令的回应处理函数,也就是responseFunction,对将要传输的数据进行差异化处理,然后再通过sendResponse发送给RILJ。
那么responseFunction函数的具体形式是什么呢?
我们回顾一下,我们当初在接到RILJ的命令后,由Eventloop把命令交给reference之前,在
processCommandBuffer中构建了用于在RILC层传输的RequestInfo数据类型,而构建这个数据的原理就是在ril_commands.h中查找当前命令所对应的两个回调函数,一个用于向reference传输时使用,另一个用于reference给Eventloop回应时使用。responseFunction指的就是第二个回调函数。 {RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus},
也就是说,发送到reference时我们需要调用dispatchVoid,而从reference接受Modem的回应时,我们就要从responseSimStatus进入了: @ril.cpp
static int responseSimStatus(Parcel &p, void *response, size_t responselen) { RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response); p.writeInt32(p_cur->card_state); p.writeInt32(p_cur->universal_pin_state);
p.writeInt32(p_cur->gsm_umts_subscription_app_index); p.writeInt32(p_cur->cdma_subscription_app_index); p.writeInt32(p_cur->ims_subscription_app_index);
sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications); } 接下来:
static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) { p.writeInt32(num_apps); startResponse;
for (int i = 0; i < num_apps; i++) { p.writeInt32(appStatus[i].app_type); p.writeInt32(appStatus[i].app_state); p.writeInt32(appStatus[i].perso_substate);
writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));