Android中RIL层详细分析_第1页
Android中RIL层详细分析_第2页
Android中RIL层详细分析_第3页
Android中RIL层详细分析_第4页
Android中RIL层详细分析_第5页
已阅读5页,还剩142页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

dRILportingxstemfd??????Linux文件描述符pipe?????Linux管道selectHAL????????????????????硬件抽象层(HardwareAbstractionLayer,HAL)LdmasmsreferencerilrildwarerilrildlsAndroidmk?MODULE_LICENSE_APACHE2?NOTICE?radiooptions.c??rild.crilincludetelephonylsril_cdma_sms.h??ril.hhardwareril/libril$lsAndroid.mk?????????????NOTICE?????ril_event.h???????ril.cpp??????ril_event.cpp??ril_commands.h??ril_unsol_commands.hEAPACHEmslsAndroidmkreferencecdmasms.c?reference-cdma-sms.hrencerillsAndroidmkatchannelhattokhmischNOTICEatchannelcattokcrileventh??refereilcmisccMODULELICENSEAPACHEoprild包括一个radiooptions.c文件,它的作用是通过串口将一些Libril供的主要功能分布在两个主要方法内,一个是RIL_startEventLoop()方rRILregister要功能是启动名为rild的监听端口,等待java端通过ladioRILevent列机制io的阻塞问题,但是这种方法的不足之处是反复的执行读写调用将浪费cpu时钟。I/O多路转接技术在这里提供了另一种比较好的解决方案:structril_event{extrevtimeoutdparam化一个新ril_event的操作是通过ril_event_set()来完成的,并通过在进入ril_event_loop()之前,在eventLoop中已经创建和挂入了td道????s_wakeupfd_event:?无名管道,用于队列主动唤醒中为librefrence_ril.so)。接着调用RIL_startEventLoop()函数来启动消息队列onRILInit通过参数获取硬件接口的设备文件或模拟硬件接口的cks_fdCommand绑定,RecordStream实际上是一个用于存放数据的结构体,这个结erion析后通过sendResponse()→sendResponseRaw()→blockingWrite()→writeLine()k●?????对普通上报的解析ATResponse结构,它的成员包括成功与否(success)以及一个中间结果 ermediateshandleFinalResponseat_send_command_full_nolock获得到了完整的响应信息(在sp_response中),便开始进行响应信息的处理,最后由eowsMobileRIL的实现对比起到一个中介的作用,为上层接口向下传递请求,并上传回响应。在RIL2.2两者在线程结构与回调机制上的对比3.1.命名onsoeserviceril-daemon/system/bin/rild-l/system/lib/libreference-ril.so---d/dev/ttyS0/system/bin/rild-l/system/lib/libreference-ril.so---d/dev/ttyS0个串口设备的具体设备文件,除了参数-d外,还有-s代表加载类型为socket的rRIL模块结构t模块结构eM的IphoneStateListener接口,实现回调(回调方式参见android的aidl机制)。令以字母"AT"开头。JAVAFramework aandroidtelephony ?android.telephony以及hardware/ril/include?? referenceril typedefstruct{tversion??RIL_RequestFunconRequest;??RIL_RadioStateRequestonStateRequest;??RIL_Supportssupports;??RIL_CancelonCancel;??RIL_GetVersiongetVersion;}RIL_RadioFunctions;estFuncintrequestvoiddataLTokentateRILRadioStateRequestportsintrequestCodeLCancelRILTokentarRILGetVersionvoid/system/bin/rildrolibreferencerilso库c中,这个库将打开一个/dev/ttySXXX的终端(终端的名字是从上层传入的),然o callbacksconstRILRadioFunctionscallbackserconstRILRadioFunctionscallbacksestCompleteRILTokentRILErrnoevoidresponsesizetresponselennsolicitedResponseintunsolResponsevoiddata??????????size_tdatalen);TimedCallbackRILTimedCallbackcallbackvoidparam??????conststructtimeval*relativeTime);ronsv{//f析DNOWr}ttnewArgvMAXLIBARGSharargsPROPERTYVALUEMAXertygetLIBARGSPROPERTYargsargvargsrilArgvelyonbionicoopvoidEDpNULLiaochurpthreadcreatestiddispatchattreventLoopNsstartupCondsstartupMutexoderrno}---------------------------------------------------------{}eventsetswakeupfdeventsfdWakeupReadtrueprocessWakeupptrileventcbfuncvoidparam{lp}kkeupCallbackreadsfdWakeupReadbuffsizfbuffbackmptyourwakeupsocketoutntevddev}{ev_wakeupfd_event结构体添加到这个数组来ds}voidtriggerEvLoopfdWakeupWritestiddispatchntodothisopthreaditesfdWakeupWritenoEINTR}eventloop}<一>--RIL层代码分析nctionsRILInitfuncsrilInitmainlooprildrildcmainread上层发下来的命令,并响应rgccharargv{lLibPathNULLconstRILRadioFunctionsrilInitconststructRILEnvintchar*);oFunctionsfuncsthPROPERTYVALUEMAXarhasLibArgs??........bndiflopenrilLibPathRTLDNOWeNULLfprintfstderrdlopenfailedsndlerror());exit;ventLooprilInitconstRILRadioFunctionsconststructRILEnvintchar**))dlsym(dlHandle,"RIL_Init");LLfprintfstderrRILInitnotdefinedorexportedins\n",rilLibPath);exit;srilArgvargvi-1;rgcicharnewArgvMAXLIBARGSiccharargsPROPERTYVALUEMAXArgvpropertygetLIBARGSPROPERTYargsmakeargvargsrilArgvtheresareasonableargvgvargvInitsrilEnvargcrilArgvenetsterfuncseepUINTMAXseemstoreturnimmediatelyonbionicepxffffffAndroidmkatchannelhattokhmischNOTICEatchannelcattokcrileventh?refereilcmisccMODULELICENSEAPACHE???funcs=rilInit(&s_rilEnv,argc,rilArgv);//实际是通过动态加载动态库的方式执行reference-ril/reference-ril.c??->RIL_RadioFunctions*RIL_Init()函数onststructRILEnvenvintargccharargv{dattrLOGDreferencenrilcRILRadioFunctionsshixian-*RIL_Init-----");whileoptgetoptargcargvpds))){tepsportatoi(optarg);ifsport0){??usage(argv[0]);???returnNULL;LOGIOpeningloopbackportd\n",s_port);??????????s_device_path=optarg;???????????????LOGI("Openingttydevice%s\n",s_device_path);ssdevicepath??=optarg;sdevice_socket=1;LOGIOpeningsockets\n",s_device_path);ltusageargv[0]);turnNULLfsportsdevicepathNULLargvL//上面获取了设备节点和socketttrinitattrdattrsetdetachstateattrPTHREADCREATEDETACHEDLOGD-reference-ril.c--ril_init--ru-kou-??ret=pthread_create(&s_tid_mainloop,&attr,mainLoop,NULL);-")取串口数据oop#############################################################################################################kete(当然,能与硬件通信也已经可以发请求了),通过数配置,以及网络状态的检查等过来,并向硬件主动上报或响应(OK)。ATEQVvoidmainLoop(void*param){LOGDshixianmainLoop---");OGIinmainLoopnstaticstructtimevalTIMEVALDELAYINIT/延时函数ATDUMPenteringmainLoop()",-1);nreaderclosedonATReaderClosedimeoutonATTimeoutfd;efdsportfd=socket_loopback_client(s_port,SOCK_STREAM);lseifsdevicesocketif(!strcmp(s_device_path,"/dev/socket/qemud")){??/*Qemu-specificcontrolsocket*/???//1:LOGD"--1----socket_local_client---after--qian-yi-ge-");?AMESPACERESER????????????????????????????SOCK_STREAM);??if(fd>=0){?????????char?answer[2];???????if(write(fd,"gsm",3)!=3||???????????read(fd,answer,2)!=2||???????????memcmp(answer,"OK",2)!=0)??????{?????????close(fd);???????????????????fd=-1;??????}?}lse1:??LOGD("---2---socket_local_client---after--hou-yi-ge-");CEFelseifsdevicepathNULL{iffd>=0){???/*disableechoonserialports*/??structtermios?ios;?tcgetattr(fd,&ios);??????ios.c_lflag=0;?/*disableECHO,ICANON,etc...*/tcsetattrfd,TCSANOW,&ios);LOGI("---open()sucess\n");lseLOGI--open()failed\n");iffd??perror("openingATinterface.retrying...");sleep10);neverreturns*/LOGDjinru---at_open---");LOGEATerrordonatopennretrn??TIMEVAL_DELAYINIT.tv_sec=15;ngtoenterinitializeCallbacknlldelayRILinitializationfordsecondsTIMEVALDELAYINITtvsecOGDjinruRILrequestTimedCallbackinitializeCallbackNULLMEVALtializeCallbackachancetodispatchedsincetpresentlyhaveacancellationmechanismrCloseReopeningafterclose}/**leronstreamfduccessonerror{attrLOGDshixianatopen-----");hdfixNULLLLwercontrolioctl#ifdefHAVE_ANDROID_OSifdefOMAPCSMI_POWER_CONTROLctlfdOMAPCSMITTYENABLEACKtsrsyncbufldflagsfcntlfdFGETFLfcntlfdFSETFLoldflagsO_NONBLOCK);ioctlfdOMAPCSMITTYREAD_UNACKED,&ack_count);retreadfd,sync_buf,sizeof(sync_buf));etwhileretret<0&&errno==EINTR));ioctlfdOMAPCSMITTY_ACK,&ack_count);whileackcountreadcount0);cntlfdFSETFLoldflagsountowerIoctlowerIoctl#else//OMAP_CSMI_POWER_CONTROLtlendif//OMAP_CSMI_POWER_CONTROLendif/*HAVE_ANDROID_OS*/ttrinitattrdattrsetdetachstateattrPTHREADCREATEDETACHEDfdfdopendevttyUSB",O_RDWR);perroropeningURCinterfaceretrying...");epiosiosttrfdiossclflagttrfdTCSANOWiosretpthreadcreatestidreaderurcattrurcreaderLoopattr);rpthreadcreatereturn;eLOGDatopenrukouretpthreadcreatestidreader&attr,readerLoop,&attr);------");derLoopattrrpthreadcreatereturn;ndif}readerLoop()作用:阻塞地去读取,modem发过来的AT命令,并回应(OK)和上报上层,后再去阻塞的形式读取等Loopvoidarg{LOGDshixianreaderLoop;lineeNULLSUnsolicitedlinelinetcharlineLOGDshixianreaderLoopisSMSUnsolicitedline");Thescopeofstringreturnedbyreadline'isvalidonlyllnextcalltoreadlinehencemakingacopyofline???????????//beforecallingreadlineagain.linestrduplineinereadlineflineNULLkfsunsolHandlerNULLsunsolHandlerlineline2);eelinecessLineline#ifdefHAVE_ANDROID_OSckPowerIoctlacknowledgethatbyteshavebeenreadandprocessed/ioctlsfdOMAPCSMITTY_ACK,&s_readCount);eadCountendif/*HAVE_ANDROID_OS*/osed}/**?*ReadsalinefromtheATchannel,returnsNULLontimeout.usivereadaccesstotheFDonlyuntilthenextcalltoreadlineistsbecauseasofwritingandroidlibcdoesnot?*havebufferedstdio.eadline{LLLOGDshixianreadline--");ittleoddIusesATBufferCurtofferconsumedcompletelyIfitpointstoacharacterthancontinuesuntilaTBufferCurybufferufferCursATBufferTBufferCurATBufferelsesATBufferCur/eresdatainthebufferfromthelastreadeadingnewlineswhilesATBufferCurr'||*s_ATBufferCur=='\n')BufferCurndNextEOLsATBufferCurlNULLapartialline.moveitupandpreparetoreadmore*/etlentrlensATBufferCurmemmovesATBuffersATBufferCurlen);adsATBufferlenATBufferCursATBufferOtherwisepeolNULLthereisacompleteline/thatwillbereturnedthewhileloopbelow????*/ULLifMAXATRESPONSEpreadsATBuffer){LOGEERRORInputlineexceededbuffern;ditchbufferandstartoveragainATBufferCursATBuffersATBufferCur;dsATBuffercountreadsfdpread,???????????MAX_AT_RESPONSE-(p_read-s_ATBuffer));whilecounterrno=EINTR);ntATDUMP<<",p_read,count);eadCountcountpreadcount0';erleadingnewlineswhilesATBufferCur='\r'||*s_ATBufferCur=='\n')sATBufferCurpeolfindNextEOLsATBufferCur;eadcountfcountreaderrorencounteredorEOFreached/fcountLOGDatchannel:EOFreached");LOGDatchannelreaderror%s",strerror(errno));NULLllineinthebufferPlaceaovertherandreturnrsATBufferCurpeolthiswillalwaysbepread?*/??????????????????????????????????????/*andtherewillbea\0at*p_read*/snretreturnret息}<二>---RIL层代码分析ILstartEventLoopeventLooprileventlooprildrildcmainread上层发下来的命令,并响应rgccharargv{lLibPathNULLconstRILRadioFunctionsrilInitconststructRILEnvintchar*);oFunctionsfuncsthPROPERTYVALUEMAXarhasLibArgs??........bndiflopenrilLibPathRTLDNOWeNULLfprintfstderrdlopenfailedsndlerror());exit;ventLooprilInitconstRILRadioFunctionsconststructRILEnvintchar)dlsym(dlHandle,"RIL_Init");LLfprintfstderrRILInitnotdefinedorexportedins\n",rilLibPath);exit;srilArgvargvi-1;rgcicharnewArgvMAXLIBARGSiccharargsPROPERTYVALUEMAXArgvpropertygetLIBARGSPROPERTYargsmakeargvargsrilArgvtheresareasonableargvgvargvInitsrilEnvargcrilArgveneterfuncseepUINTMAXseemstoreturnimmediatelyonbionicepxffffffAndroidmk????????????NOTICE?????ril_event.h???????ril.cpp???????ril_event.cpp??ril_commands.h??ril_unsol_commands.hEAPACHErefrencerilsoregisterRILstartEventLoop就是启用eventLoop线程,开始执行voidRIL_startEventLoop(void)?{attrLOGDrilcppRILstartEventLoop;tLoopthreadandwaitforittogetstartedexlocksstartupMutexttrinitattrdattrsetdetachstateattrPTHREADCREATEDETACHEDLOGDrilcppkaikoupthreadcreatestiddispatch,&attr,eventLoop,NULL);------");LOGDrilcpptiaochu-rpthread_create(&s_tid_dispatch,&attr,eventLoop,NULL);----");artedpthreadcondwaitsstartupCondsstartupMutex;mutexunlocksstartupMutexailedtocreatedispatchthreaderrnoderrno}peventpvoidril_event_init();?voidril_event_set(structril_event*ev,intfd,boolpersist,ril_event_cbfunc,void*param);voidrilevent_add(structril_event*ev);voidril_timer_add(structril_event*ev,structtimeval*tv);voidril_event_del(structril_event*ev);voidrileventloop();ilevententnextprevtimeoutcectfdfd层请求的event对象建立,在第三个任务中)。voidoopvoidparamLOGDrilcppeventLoopzhi-xing--");LOGDRILCrileventinit-kai-shi-");entinitLOGDRILCrileventinittiaochu");exlocksstartupMutexcondbroadcastsstartupCondmutexunlocksstartupMutexOGEErrorinpipeerrnoderrnoLsfdWakeupReadfiledes侦听?s_fdWakeupWrite=filedes[1];//用于通知消息循环定义消息已发送LOGDrilcppevnetlooprilevent_set(&s_wakeupfd_event,s_fdWakeupRead,true,processWakeupCallback,NULL);--");sfdWakeupReadFSETFLONONBLOCKsetLOGDrilcppeventlooprilEventAddWakeup&s_wakeupfd_event);---");DtiaochurileventsetaddnerrorLOGDrilcpp-cong--eventloop---tiao_ru--ril_event_loop()----");LOGDrilcppcongeventlooptiaochu--ril_event_loop()----");rrorineventloopbaseerrnoderrno}ril_event_init()主要工作是清零和处理三种函数(定时,监听,挂起);//Initializeinternaldatastructsvoidril_event_init(){ITLOGDRilevnetcpprileventinitshixian-han-shu-");dstimerlistpendinglistmsetwatchtablesizeofwatchtable}rileventset过管道,对读到的数据进行初始化?---------注册进程唤醒事件回调ileventevintfdboolpersistrileventcbfuncvoidparam{LOGDRILevnentcppshixianvoidrileventsetstructrileventevintfdboolpersistrileventcbfuncvoid*paradlogrileventsetx,(unsignedint)ev);evsizeofstructrileventvindexrsistETFLONONBLOCK}/**akeupfdisdonejusttopopusoutofselectferhereandthenrileventwillresetthetimersonthehortflagsvoidparamLOGDrileventset--processWakeupCallback-read(s_fdWakeupRead,&buff,sizeof(buff));---");WakeupCallbackakeupsocketoutretreadsfdWakeupReadbuffsizeofbuffwhileretreterrnoEINTR));}oopWakeupstructrileventevdevp}//Addeventtowatchlisttructrileventev{LOGDRILevnentcppshixian-voidril_event_add(structril_event*ev)----");dlogrileventadd;intiiMAXFDEVLLndexidlog~~addedat%d~~~~",i);peventevifev>fd>=nfds)nfds=ev->fd+1;dlog~nfds=%d~~~~",nfds);breakENTSi{tchtableiNUEdlogrileventadd}到数据后,再通过写端,写到对应的数组去(readFs)LOGDretwritesfdWakeupWrite,1);---");ifpthreadequalpthreadselfstiddispatcheventlooptowakeupNoreasontodothiseintheeventloopthreadretwritesfdWakeupWrite",1);whilereterrnoEINTR}voidril_event_loop(){tvlptvLOGDrileventcppshixian--ril_event_loop-limain----");for询alcopyofreadfdsetLOGD-101.1--kaishi--ril_event_loop-memcpy(&rfds,&readFds,sizeof(fd_set));---");去ifcalcNextTimeouttv取超时参数,若失败则返回-1。endingtimersblockindefinitelydlog~~notimers;blockingindefinitely~~~~");ULLdlogblockingfords+%dus~~~~",(int)tv.tv_sec,(int)tv.tv_usec);tvdiesrfdsLOGD--ril_event.cpp---ril_event_loop---tiao-ru--select------");electreadylcetIo机制去唤醒管道来的数据LOGD--101.3--ril_event.cpp---ril_event_loop--tiao-chu--select---");GIselectgodiesrfdsdlogdeventsfired~~~",n);iferrnoEINTRcontinueLOGErileventselecterror%d)",errno);nocessTimeoutsmeoutseoutsrileventinitpendinglistkforreadreadyprocessReadReadiesrfdsn;firePendingril_event_loop()--OVER1--");firePending;//处理挂起消息?firePendingril_event_loop()--OVER2--");}sTimeouts{GDDSJTprocessTimeoutsrocessTimeoutsgprocessTimeoutsw???structril_event*tev=timer_list.next;entnextetNownoweeifnowevtimeoutforanyeventsdlogLookingfortimersdsdus~~",(int)now.tv_sec,(int)now.tv_usec);whiletevtimerlisttimercmpnowtev->timeout,>))){//查找所有当前时间点以前的消息???pireddlogfiringtimer");nextremoveFromListtev从定时消息队列中移除,就是已经做完的内容???????addToList(tev,&pending_list);//添加至挂起列表(pending_list)中??EdlogprocessTimeouts;}taticvoidaddToListstructrileventevstructrileventlist{LOGDTJLBaddToList);tprevextevev}dReadiesfdsetrfdsintn{LOGDJTprocssReadReadies);processReadReadiesdlogprocessReadReadiesd~",n);rintiiMAXFDEVENTSnictrileventrevwatchtableiifrevNULLFDISSETrevfdrfds)){???????????addToList(rev,&pending_list);//添加至挂起列表(pending_list)中removeWatchrevi;???????????n--;EdlogprocessReadReadiesd",n);}Pending{ePendingPendingdlogfirePending);???structril_event*ev=pending_list.next;evpendinglistructrileventnextevnextFromListevevfuncevfdev>param);dlogfirePending;}RIL层代码分析---RIL_register()rildrildcmainread上层发下来的命令,并响应rgccharargv{lLibPathNULLconstRILRadioFunctionsrilInitconststructRILEnvintchar*);oFunctionsfuncsthPROPERTYVALUEMAXarhasLibArgs??........bndiflopenrilLibPathRTLDNOWeNULLfprintfstderrdlopenfailedsndlerror());exit;ventLooprilInitconstRILRadioFunctionsconststructRILEnvintchar**))dlsym(dlHandle,"RIL_Init");LLfprintfstderrRILInitnotdefinedorexportedins\n",rilLibPath);exit;srilArgvargvi-1;rgcicharnewArgvMAXLIBARGSiccharargsPROPERTYVALUEMAXArgvpropertygetLIBARGSPROPERTYargsmakeargvargsrilArgvtheresareasonableargvgvargvInitsrilEnvargcrilArgveneterfuncseepUINTMAXseemstoreturnimmediatelyonbionicepxffffffAndroidmk????????????NOTICE?????ril_event.h???????ril.cpp???????ril_event.cpp??ril_commands.h??ril_unsol_commands.hpedefstructintversionsettoRIL_VERSION*/unconRequesteRequestonStateRequestportsncelngetVersionLRadioFunctions供调试时使用)。然后将这两个socket接口使用任务一中实现的机制进行注册(仅列出s_fdListen)entsetslisteneventsfdListenfalselistenCallbackNULLdWakeupslisteneventsocketIO的检查句柄集合中,一旦有上层来的(调试)请求,event机制hril/libril/ril.cpp->RIL_register函数voidLOGDRILCRILregisterfuncRILCPPRILregister-");ULLcallbacksversionRILVERSION|callbacks->version==1)RILregisterRILRadioFunctionsnullorinvalidversion"expecteddRIL_VERSION);erCalledLOGE("RIL_registerhasbeencalledmorethanonce."Subsequentcallignored");LOGD("RIL_registerhasbeencalledmorethanonce."Subsequentcallignored");//1:换个马甲CalledckforintiiintNUMELEMSscommandsi){ssertiscommandsirequestNumberforintiiintNUMELEMSsunsolResponsesi){sertiRILUNSOLRESPONSEBASE??==s_unsolResponses[i].requestNumber);dimplcallsRILstartEventLoopfirst???//oldstandaloneimplwantsithere.rtEventLoop?//startlistensocket?开始侦听套接字if?0LOGEUnabletobindsocketerrnoderrnoexit;elsenLOGEFailedtogetsocketSOCKETNAMERIL");exit;LOGEFailedtolistenoncontrolsocketdssfdListenstrerrorerrno;exit;ndif的监听话柄enpersistentsowecanacceptonlyoneconnectionatatimeselect列去fugLOGEFailedtogetsocketSOCKETNAMERILDEBUGerrno:%d",errno);exit;LOGEFailedtolistenonrildebugsocketdssfdDebugstrerrorerrno);exit;ugtruedebugCallbackNULLndif}//Initializeaneventntfdboolpersistrileventcbfuncvoidparam{LOGDRILevnentcppshixianvoidrileventsetstructrileventevintfdboolpersistrileventcbfuncvoid*paradlogrileventsetx,(unsignedint)ev);evsizeofstructrileventvindexrsistETFLONONBLOCK}ntfdshortflagsvoidparamocketeamprsunpeeraddrocklensizeofpeeraddredsredssizeofcredswdNULLCommandfdListenLOGDshixianrilregiterrilevent_set(&s_debug_event,s_fdDebug,true,debugCallback,NULL);");drsocklenandLOGEErroronaccepterrnoderrnotlisteningfornewconnectionsagainEventAddWakeupslistenevententialoftheothersideandonlyacceptsocketfrometrrgetsockoptsfdCommandSOLSOCKETSOPEERCREDcredsszCredsszCredsetpwuidcredsuidNULLifstrcmppwdpwnamePHONEPROCESS)==0){isphonesocket1;LOGE("RILDcan'tacceptsocketfromprocess%s",pwd->pw_name);LOGEErrorongetpwuiderrno%d",errno);LOGDErrorongetsockopterrnoderrno;socketERILDmustacceptsocketfromsPHONEPROCESSdCommandsfdCommand;dsSocketClosedeningfornewconnectionsagain?????rilEventAddWakeup(&s_listen_event);ntlsfdCommandFSETFLONONBLOCKEErrorsettingONONBLOCKerrnoderrnorilnewconnections_fdCommand绑定到record_stream_new。目的就是保证数据的完整性newsfdCommandMAXCOMMANDBYTESCallbackprs}backintfdshortflagsvoidparameamprsndsfdCommandLOGDSHIXIANrilregieterstaticvoidprocessCommandsCallbackintfdshortflagsvoidparam);opuntilEAGAINEINTRendofstreamorothererrorifretprecordNULL){endofstream/fretelseifret*&&p_record!=NULL*/eamifreterrnoEAGAINerrnoEINTR){atalerrororendofstreamtLOGEerroronreadingcommandsocketerrnodnerrno);LOGWEOSClosingcommandsocket");sfdCommandsfdCommand1;ent???????record_stream_free(p_rs);//释放了上面监听到的数据,再开始新的路程tartlisteningfornewconnectionsagain}nttokenpRItizetbuflenIDshixianprocessCommandBuffertDatauinttbufferbuflenatendpreadIntrequeststatuspreadInttoken队列的序列号OERRORvalidrequestblockifrequestrequestinttNUMELEMS(s_commands)){OGEunsupportedrequestcodedtokendrequesttokensshouldperhapsreturnaresponseRequestInfocallocsizeofRequestInfokenCIscommandsrequesthreadmutexlockspendingRequestsMutexpendingRequestsuestspRIhreadmutexunlockspendingRequestsMutex/*???sLastDispatchedToken=token;*/pRIpCIdispatchFunctionppRI/电话来了,就执行这个函数}<四>--RIL层代码分析--整个电话来访过程gesappsPhonesrccomandroidphoneDialtactsActivityjava2ntentIntentACTIONCALLPRIVILEGEDUrifromPartstelnumbernull);setFlagsIntentFLAGACTIVITYNEWTASKtActivityintentllBroadcasterassstartActivityintenttIntentnewIntentIntentACTIONNEWOUTGOINGCALLifnumbernullbroadcastIntentputExtraIntentEXTRAPHONENUMBERnumber);oadcastIntentputExtraEXTRAALREADYCALLEDcallNowbroadcastIntentputExtraEXTRAORIGINALURIintentgetDatatoString());ifLOGVLogv(TAG,"Broadcastingintent"+broadcastIntent+".");rderedBroadcastbroadcastIntentPERMISSIONnullnull????????????Activity.RESULT_OK,number,null);eivetnewIntentIntentACTIONCALLuriewIntentputExtraIntentEXTRAPHONENUMBERnumberentsetClasscontextInCallScreenclassewIntentaddFlagsIntentFLAGACTIVITYNEWTASKonCreateonNewIntent(非第一次)ntentntenthoneUtilsplaceCallmPhonenumberintentgetDatalnumberdialnewDialStringdialdialStringCommandsInterfaceCLIR_DEFAULT);cmdialpendingMO.address,clirMode,obtainCompleteMessage());//obtainCompleteMessage(EVENTOPERATIONCOMPLETEsendrr;?msg=mSender.obtainMessage(EVENT_SEND,rr);acquireWakeLock();?msg.sendToTarget();RILSender.handleMessage()???caseEVENT_SEND:????????????????????...???s.getOutputStream().write(dataLength);??????????????????上面步骤:为APP就是java层传下的信息(就是执行的动作:按键打电话),已经做完,下面讲RIL层如何来接受上层来的信息第一、《创建轮询机制》ntLoop、建立事件循环线程ret=pthread_create(&s_tid_dispatch,&attr,eventLoop,NULL);RIL_startEventLoop(void){???..........ret=pthread_create(&s_tid_dispatch,&attr,?eventLoop,?NULL);//创建线程,为入口函数,去实现它的}eventLooprillibrilrilcpp实现eventLoop(void*param){voidril_event_init(){ITLOGDRilevnetcpprileventinitshixian-han-shu-");dstimerlistpendinglistmsetwatchtablesizeofwatchtable}sfdWakeupWritefiledes/*用于通知消息循环定义消息已发送*/第二、注册进程唤醒事件回调ril_event_set(&s_wakeupfd_event,s_fdWakeupRead,true,processWakeupCallback,NULL);注册进回调*/staticvoidprocessWakeupCallbackintfdshortflagsvoidparam{LOGDrileventset--processWakeupCallback-read(s_fdWakeupRead,&buff,sizeof(buff));---");keupCallbackakeupsocketout???do{ret=read(s_fdWakeupRead,&buff,sizeof(buf???????whileretreterrnoEINTR));}taticvoidrilEventAddWakeupstructrileventev????????{???????????????ril_event_add(ev);?????????????????triggerEvLoop();????????}//Addeventtowatchlistuctrileventev{LOGDRILevnentcppshixian-voidril_event_add(structril_event*ev)----");dlogrileventadd;intiiMAXFDEVLL??watch_table[i]=ev;//?????????把上面ril_event_add函数添加的事件_wakeupfd_eventndexidlog~~addedat%d~~~~",i);peventevFDSETevfdreadFds);ifev>fd>=nfds)nfds=ev->fd+1;dlog~nfds=%d~~~~",nfds);breakENTSi{tchtableiNUEdlogrileventadd}staticvoidtriggerEvLoop(){LOGDretwritesfdWakeupWrite,1);---");ifpthreadequalpthreadselfstiddispatcheventlooptowakeupNoreasontodothiseintheeventloopthread???ret=write(s_fdWakeupWrite,"",1);????????whilereterrnoEINTR}三、建立事件循环rileventloop*/}DS*/void?ril_event_loop(){?????????...}?????????//CheckfortimeoutsessTimeoutsrileventinitpendinglist??//Checkforread-ready?????????processReadReadies(&rfds,n);//处理侦听消息,处理ril_event_init->watch_listireawayfirePending?//处理挂起消息############################################################################################何运转.es_wakeupfd_event:无名管道,用于队列主动唤醒(前面提到的队列刷新,就用它来实现,请参考使用它的相关地方)###########################################################################################################?RIL_requestTimedCallback(initializeCallback,NULL,&TIMEVAL_0);中的initializeCallback发送AT>ATE0Q0V1命令#############################################################################################################第二、读取并判断modem发的信息(URC,还是referencerilreferenceril.c->RIL_init()const?RIL_RadioFunctions*RIL_Init(conststructRIL_Env*env,intargc,char**argv){pdsopessdevicepath??=optarg;sdevicesocket=1;LOGIOpeningsocket%s\n",s_device_path);L????第四、单独启动一个线程读取串口数据retpthreadcreatestidmainloopattr,NULL);//创建一个线程}voidmainLoop(void*param){KSTREAMetqemudetNAMESPACERESgsmswererOKfd1;clientsdevicepathANDROIDSOCKETNAMESPACEFILESYSTREAMULLthORDWR???????}???????ret=?at_open(fd,onUnsolicited);dATUnsolHandlerh{fdopendevttyUSBO_RDWR);eadcreatestidreaderurcattrurcreaderLoopattrtpthreadcreatestidreaderattrreaderLoopattrif}第五、通过readloop()函数判断为AT:等待回应还是URC请求/*下面read的阻塞式的读取modoem(是initializeCallback()函数发送的AT命令,)发来信息,还判断是URC还是readerLoopstaticvoid?*(void*arg){???????constchar*line;readline???????line=();eNULLUnsolicitedlinelinetcharlinelinestrduplinedlineflineNULLkfsunsolHandlerNULLsunsolHandlerlineline2);eeline?processLine(line);/*对上面读取信息进行解??????????判断*/#ifdefHAVE_ANDROID_OSifsackPowerIoctlioctlsfdOMAPCSMITTY_ACK,&s_readCount);eadCountendif/*HAVE_ANDROID_OS*/}ee{mutexlockscommandmutexnseNULLmmandpendingUnsolicitedlineFinalResponseSuccesslineesponsesuccessnalResponselineinalResponseErrorlineesponsesuccesselseifssmsPDUNULLstrcmpline")){SeeegTS.3ndslikeATCMGShaveaprompttrlZssmsPDUULLstypeSULThandleUnsolicited????????????(line);//2.用来处理send_at_command()发过的回应Cifspresponsepintermediates=NULLisdigit(line[0])addIntermediateline);/*eitherwealreadyhaveanintermediateresponseor?thelinedoesn'tbeginwithadigit*/handleUnsolicitedlineELINEifspresponsepintermediates=NULL&&strStartsWith(line,s_responsePrefix)addIntermediateline);/*wealreadyhaveanintermediateresponse*/handleUnsolicitedlineNEifstrStartsWithlinesresponsePrefixaddIntermediateline);handleUnsolicitedlineefaultthisshouldneverbereachedLOGEUnsupportedATcommandtypedn,s_type);dleUnsolicitedlinemutexunlockscommandmutex}constcharreadline{snretreturnret息}initializeCallback?RIL_requestTimedCallback(,NULL,&TIMEVAL_0);//打印QVvoidinitializeCallbackvoidparamonseadioStateRADIOSTATESIMNOTREADY}}###########################################################################################################效#############################################################################################################第三、处理两个socket6.5libril/ril.cpp-tILregisterfuncsRILregisterconstRILRadioFunctionscallbacks经初始化完?if(s_registerCalled>0){??????LOGE("RIL_registerhasbeencalledmorethanonce.""Subsequentcallignored");?????LOGD("RIL_registerhasbeencalledmorethanonce.""Subsequentcallignored");eturn//1:换个马甲alledforintiiintNUMELEMSscommandsi){ssertiscommandsirequestNumber???for(inti=0;i<(int)NUM_ELEMS(s_unsolResponses);i++){???????assert(i+RIL_UNSOL_RESPONSE_BASE???????????????==s_unsolResponses[i].requestNumber);??if(s_started==0){??????RIL_startEventLoop();rtlistensocket#if0socketlocalserverSOCKETNAMERILANDROIDSOCKETNAMESPACEABSTRACTSOCKSTRListenret#else2:获取init.rc定义的rildsocket????s_fdListen=android_get_control_socket(SOCKEAMERILdif端的监听话柄enlistenCallbackNULL;if3.获取debugsocket????s_fdDebug=android_get_control_socket(SOCKug//将此处端口加入到select队列去????ril_event_set(&s_debug_event,s_fdDebug,true,debugCallback,NULL);???rilEventAddWakeup(&s_debug_event);#endif}ventsetslisteneventsfdListenfalselistenCallbackNULLlistenCallbackstaticvoid?

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论