/** assumes s_commandmutex is held */staticvoidhandleFinalResponse(constchar*line){
sp_response->finalResponse =strdup(line);pthread_cond_signal(&s_commandcond);}
// Initialize internal data structsvoidril_event_init(){MUTEX_INIT();FD_ZERO(&readFds);init_list(&timer_list);init_list(&pending_list);memset(watch_table,0,sizeof(watch_table));}
voidril_event_loop(){
n =select(nfds,&rfds,NULL,NULL, ptv);//主要循环调用三个方法for(;;){// Check for timeoutsprocessTimeouts();// Check for read-readyprocessReadReadies(&rfds, n);// Fire awayfirePending();}}
处理timer_list列表
staticvoidprocessTimeouts(){//如果timer_list中的事件超时,则从timer_list列表中移除,并添加到pending_list中while((tev !=&timer_list)&&(timercmp(&now,&tev->timeout,>))){// Timer expireddlog("~~~~ firing timer ~~~~");
next = tev->next;removeFromList(tev);addToList(tev,&pending_list);
tev = next;}}
mainLoop(void*param __unused){//初始化AT通道的关闭方法和超时方法at_set_on_reader_closed(onATReaderClosed);at_set_on_timeout(onATTimeout);for(;;){//控制关闭
s_closed =0;//注意传入的参数
ret =at_open(fd, onUnsolicited);RIL_requestTimedCallback(initializeCallback,NULL,&TIMEVAL_0);waitForClose();RLOGI("Re-opening after close");}}
staticvoid onUnsolicited (constchar*s,constchar*sms_pdu){...if(strStartsWith(s,"%CTZV:")){/* TI specific -- NITZ time */char*response;
line = p =strdup(s);at_tok_start(&p);
err =at_tok_nextstr(&p,&response);if(err !=0){RLOGE("invalid NITZ line %s\n", s);}else{
RIL_onUnsolicitedResponse (
RIL_UNSOL_NITZ_TIME_RECEIVED,
response,strlen(response));}free(line);}...省略多个elseif}
staticvoidprocessLine(constchar*line){pthread_mutex_lock(&s_commandmutex);if(sp_response ==NULL){/* no command pending */handleUnsolicited(line);//判断是否已经把所有有效数据传输完毕}elseif(isFinalResponseSuccess(line)){
sp_response->success =1;//回复消息给上层handleFinalResponse(line);}elseif(isFinalResponseError(line)){
sp_response->success =0;handleFinalResponse(line);}elseif(s_smsPDU !=NULL&&0==strcmp(line,"> ")){// See eg. TS 27.005 4.3// Commands like AT+CMGS have a "> " promptwriteCtrlZ(s_smsPDU);
s_smsPDU =NULL;}elseswitch(s_type){case NO_RESULT:handleUnsolicited(line);break;case NUMERIC:if(sp_response->p_intermediates ==NULL&&isdigit(line[0])){addIntermediate(line);}else{/* either we already have an intermediate response or
the line doesn't begin with a digit */handleUnsolicited(line);}break;case SINGLELINE:if(sp_response->p_intermediates ==NULL&& strStartsWith (line, s_responsePrefix)){//将数据放到反馈数据中addIntermediate(line);}else{/* we already have an intermediate response */handleUnsolicited(line);}break;case MULTILINE:if(strStartsWith (line, s_responsePrefix)){addIntermediate(line);}else{handleUnsolicited(line);}break;default:/* this should never be reached */RLOGE("Unsupported AT command type %d\n", s_type);handleUnsolicited(line);break;}pthread_mutex_unlock(&s_commandmutex);}
/** assumes s_commandmutex is held */staticvoidhandleFinalResponse(constchar*line){//把回应消息返回给eventLoop
sp_response->finalResponse =strdup(line);//发信号给s_commandcond线程,使其脱离阻塞状态 pthread_cond_signal(&s_commandcond);}
extern"C"void
RIL_register (const RIL_RadioFunctions *callbacks){...memcpy(&s_callbacks, callbacks,sizeof(RIL_RadioFunctions));
s_registerCalled =1;RLOGI("s_registerCalled flag set, %d", s_started);// Little self-checkfor(int i =0; i <(int)NUM_ELEMS(s_commands); i++){assert(i == s_commands[i].requestNumber);}for(int i =0; i <(int)NUM_ELEMS(s_unsolResponses); i++){assert(i + RIL_UNSOL_RESPONSE_BASE
== s_unsolResponses[i].requestNumber);}//通过注册服务获取
radio::registerService(&s_callbacks, s_commands);RLOGI("RILHIDL called registerService");}
staticvoidrequestDial(void*data, size_t datalen __unused, RIL_Token t){
RIL_Dial *p_dial;char*cmd;constchar*clir;int ret;
p_dial =(RIL_Dial *)data;switch(p_dial->clir){case1: clir ="I";break;/*invocation*/case2: clir ="i";break;/*suppression*/default:case0: clir ="";break;/*subscription default*/}asprintf(&cmd,"ATD%s%s;", p_dial->address, clir);//发送AT命令
ret =at_send_command(cmd,NULL);free(cmd);/* success or failure is ignored by the upper layer here.
it will call GET_CURRENT_CALLS and determine success that way *///结束时调用RIL_onRequestComplete(t, RIL_E_SUCCESS,NULL,0);}
staticvoidprocessLine(constchar*line){pthread_mutex_lock(&s_commandmutex);if(sp_response ==NULL){/* no command pending */handleUnsolicited(line);}elseif(isFinalResponseSuccess(line)){
sp_response->success =1;//将消息发回给eventLoophandleFinalResponse(line);}elseif(isFinalResponseError(line)){
sp_response->success =0;handleFinalResponse(line);}elseif(s_smsPDU !=NULL&&0==strcmp(line,"> ")){// See eg. TS 27.005 4.3// Commands like AT+CMGS have a "> " promptwriteCtrlZ(s_smsPDU);
s_smsPDU =NULL;}elseswitch(s_type){case NO_RESULT:handleUnsolicited(line);break;case NUMERIC:if(sp_response->p_intermediates ==NULL&&isdigit(line[0])){addIntermediate(line);}else{/* either we already have an intermediate response or
the line doesn't begin with a digit */handleUnsolicited(line);}break;case SINGLELINE:if(sp_response->p_intermediates ==NULL&& strStartsWith (line, s_responsePrefix)){addIntermediate(line);}else{/* we already have an intermediate response */handleUnsolicited(line);}break;case MULTILINE:if(strStartsWith (line, s_responsePrefix)){addIntermediate(line);}else{handleUnsolicited(line);}break;default:/* this should never be reached */RLOGE("Unsupported AT command type %d\n", s_type);handleUnsolicited(line);break;}pthread_mutex_unlock(&s_commandmutex);}
2.继续跟进handleFinalResponse
/** assumes s_commandmutex is held */staticvoidhandleFinalResponse(constchar*line){//把回应消息返回给RIL
sp_response->finalResponse =strdup(line);//唤醒阻塞线程pthread_cond_signal(&s_commandcond);}
3.回到at_send_command_full_nolock
if(pp_outResponse ==NULL){at_response_free(sp_response);}else{/* line reader stores intermediate responses in reverse order */reverseIntermediates(sp_response);//返回的数据*pp_outResponse = sp_response;}
staticvoidrequestDial(void*data, size_t datalen __unused, RIL_Token t){
RIL_Dial *p_dial;char*cmd;constchar*clir;int ret;
p_dial =(RIL_Dial *)data;switch(p_dial->clir){case1: clir ="I";break;/*invocation*/case2: clir ="i";break;/*suppression*/default:case0: clir ="";break;/*subscription default*/}asprintf(&cmd,"ATD%s%s;", p_dial->address, clir);
ret =at_send_command(cmd,NULL);free(cmd);/* success or failure is ignored by the upper layer here.
it will call GET_CURRENT_CALLS and determine success that way */RIL_onRequestComplete(t, RIL_E_SUCCESS,NULL,0);}
5.这就回到ril.c的onRequestComplete中
extern"C"voidRIL_onRequestComplete(RIL_Token t, RIL_Errno e,void*response, size_t responselen){
RequestInfo *pRI;int ret;
RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
pRI =(RequestInfo *)t;if(!checkAndDequeueRequestInfoIfAck(pRI,false)){
RLOGE ("RIL_onRequestComplete: invalid RIL_Token");return;}
socket_id = pRI->socket_id;#if VDBGRLOGD("RequestComplete, %s",rilSocketIdToString(socket_id));#endifif(pRI->local >0){// Locally issued command...void only!// response does not go back up the command socketRLOGD("C[locl]< %s",requestToString(pRI->pCI->requestNumber));free(pRI);return;}appendPrintBuf("[%04d]< %s",
pRI->token,requestToString(pRI->pCI->requestNumber));if(pRI->cancelled ==0){int responseType;if(s_callbacks.version >=13&& pRI->wasAckSent ==1){// If ack was already sent, then this call is an asynchronous response. So we need to// send id indicating that we expect an ack from RIL.java as we acquire wakelock here.
responseType = RESPONSE_SOLICITED_ACK_EXP;grabPartialWakeLock();}else{
responseType = RESPONSE_SOLICITED;}// there is a response payload, no matter success or not.#if VDBG
RLOGE ("Calling responseFunction() for token %d", pRI->token);#endif
pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock((int) socket_id);int rwlockRet =pthread_rwlock_rdlock(radioServiceRwlockPtr);assert(rwlockRet ==0);//调用返回的响应方法
ret = pRI->pCI->responseFunction((int) socket_id,
responseType, pRI->token, e, response, responselen);
rwlockRet =pthread_rwlock_unlock(radioServiceRwlockPtr);assert(rwlockRet ==0);}free(pRI);}
staticvoid*mainLoop(void*param __unused){...
ret =at_open(fd, onUnsolicited);...}
2.可以看到其实调用的是reference-ril.c中的onUnsolicited方法
/**
* Called by atchannel when an unsolicited line appears
* This is called on atchannel's reader thread. AT commands may
* not be issued here
*/staticvoid onUnsolicited (constchar*s,constchar*sms_pdu){...if(strStartsWith(s,"%CTZV:")){/* TI specific -- NITZ time */char*response;
line = p =strdup(s);at_tok_start(&p);
err =at_tok_nextstr(&p,&response);if(err !=0){RLOGE("invalid NITZ line %s\n", s);}else{
RIL_onUnsolicitedResponse (
RIL_UNSOL_NITZ_TIME_RECEIVED,
response,strlen(response));}free(line);}// ...省略多个else if}
可以看到其最后调用RIL_onUnsolicitedResponse进行处理
#define RIL_onRequestComplete(t, e, response, responselen) s_rilenv->OnRequestComplete(t,e, response, responselen)#define RIL_onUnsolicitedResponse(a,b,c) s_rilenv->OnUnsolicitedResponse(a,b,c)