日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Android RIL使用詳解

瀏覽:22日期:2022-09-23 11:06:23

前言

Android作為一個通用的移動平臺,其首要的功能就是通話、短信以及上網等通信功能。那么,從系統的角度來看,Android究竟是怎么實現與網絡的交互的了? 這篇文章里,就來看一看Android中負責通信功能的Telephony中間層,通常也被稱之為RIL(Radio Interface Layer)的具體實現原理與架構。

Android手機要實現與網絡端的通信,需要跨越兩個層:

RIL Java(RILJ):負責將上層APP的通信請求發送給HAL層;RIL C++(RILD): 系統守護進程,負責將RILJ的請求命令發送給CP(Communication Processor)

什么是RIL

簡單的說,RIL(Radio Interface Layer),就是將應用程序的通信請求發送給CP的中間層,其包括兩個部分,一個是Java層RILJ,一個是C++層(不妨看作是CP對應的HAL層)RILD。

RILJ屬于系統Phone進程的一部分,隨Phone進程啟動而加載;而RILD守護進程是通過Android的Init進程進行加載的。

RIL結構

下圖是一個Android RIL的一個結構圖。整個通信過程有四個層:

最上層的是應用程序,如通話,短信以及SIM卡管理,它們主要負責將用戶的指令發送到RIL Framework(以后統稱RILJ); RILJ為上層提供了通用的API,如TelephonyManager(包括通話,網絡狀態; SubscriptionManager(卡狀態)以及SmsManager等,同時RILJ還負責維持與RILD的通信,并將上層的請求發送給RILD; RILD是系統的守護進程,對于支持通話功能的移動平臺是必不可少的。RILD的功能主要功能是將RILJ發送過來的請求繼續傳遞給CP,同時會及時將CP的狀態變化發送給RILJ; Linux驅動層:kernel驅動層接受到數據后,將指令傳給CP,最后由CP發送給網絡端,等網絡返回結果后,CP將傳回給RILD;

Android RIL使用詳解

RILJ與RILD(RILD與CP的通信)都是通過一個個消息進行數據傳遞。消息主要分兩種:一種是RILJ主動發送的請求(solicited),常見的有RIL_REQUEST_GET_SIM_STATUS(獲取SIM卡狀態),RIL_REQUEST_DIAL(撥打電話),RIL_REQUEST_SEND_SMS(發送短信),RIL_REQUEST_GET_CURRENT_CALLS(獲取當前通話狀態),RIL_REQUEST_VOICE_REGISTRATION_STATE(獲取網絡狀態); 另一種則是從CP主動上報給RIL的消息(unsolicited),如網絡狀態發生變化時,CP會上報RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,有新短信時,會上報RIL_UNSOL_RESPONSE_NEW_SMS,有來電時會上報RIL_UNSOL_CALL_RING。

RIL相關的請求命令與數據結構都定義在/android/hardware/ril/include/telephony/ril.h

在整個過程中,有幾個關鍵問題:

上層是如何得知RILJ狀態變化的; RILJ與RILD是怎么進行通信的? RILJD與CP又是如何進行通信的?

圍繞這三個問題點,我們來看一下具體的細節。

上層如何得知RILJ狀態變化

為方便上層實時監聽網絡狀態、通話狀態以及CP的狀態變化,RIL提供了一個專門的監聽接口IPhoneStateListener.aidl,上層需要監聽上述狀態變化時,只需要實現上述接口,并在Android系統服務TelephonyRegistry中對上述接口實現進行注冊:

public void listen(String pkgForDebug, IPhoneStateListener callback, int events, boolean notifyNow);

另外,也可以在TelephonyManager中對RIL狀態進行監聽:

public void listen(PhoneStateListener listener, int events)

源代碼:/android/frameworks/base/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl

oneway interface IPhoneStateListener { void onServiceStateChanged(in ServiceState serviceState); void onSignalStrengthChanged(int asu); void onMessageWaitingIndicatorChanged(boolean mwi); void onCallForwardingIndicatorChanged(boolean cfi); // we use bundle here instead of CellLocation so it can get the right subclass void onCellLocationChanged(in Bundle location); void onCallStateChanged(int state, String incomingNumber); void onDataConnectionStateChanged(int state, int networkType); void onDataActivity(int direction); void onSignalStrengthsChanged(in SignalStrength signalStrength); void onOtaspChanged(in int otaspMode); void onCellInfoChanged(in List<CellInfo> cellInfo); void onPreciseCallStateChanged(in PreciseCallState callState); void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState); void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo); void onVoLteServiceStateChanged(in VoLteServiceState lteState); void onOemHookRawEvent(in byte[] rawData); void onCarrierNetworkChange(in boolean active); void onFdnUpdated(); void onVoiceRadioBearerHoStateChanged(int state); }

RILJ與RILD如何通信

RILJ在創建過程中,會啟動兩個線程:RILSender和RILReceiver,RILSender負責將指令發送給RILD,而RILReceiver則負責從讀取從RILD發送過來的數據。RILJ與RILD的通信通道就是在RILReceiver中建立起來的。

我們來看一看RILReciver的代碼:

class RILReceiver implements Runnable { byte[] buffer; RILReceiver() { ... @Override public void run() { int retryCount = 0; String rilSocket = 'rild'; // 嘗試與RILD建立連接 try {for (;;) { LocalSocket s = null; LocalSocketAddress l; if (mInstanceId == null || mInstanceId == 0 ) { rilSocket = SOCKET_NAME_RIL[0]; } else { rilSocket = SOCKET_NAME_RIL[mInstanceId]; } try { s = new LocalSocket(); l = new LocalSocketAddress(rilSocket, LocalSocketAddress.Namespace.RESERVED); s.connect(l); } catch (IOException ex){ ... // don’t print an error message after the the first time // or after the 8th time if (retryCount == 8) { Rlog.e (RILJ_LOG_TAG, 'Couldn’t find ’' + rilSocket + '’ socket after ' + retryCount + ' times, continuing to retry silently'); } else if (retryCount >= 0 && retryCount < 8) { Rlog.i (RILJ_LOG_TAG, 'Couldn’t find ’' + rilSocket + '’ socket; retrying after timeout'); } ... retryCount++; continue; } retryCount = 0; mSocket = s; // 從socket讀取數據 int length = 0; try { InputStream is = mSocket.getInputStream(); for (;;) { Parcel p; length = readRilMessage(is, buffer); if (length < 0) { // End-of-stream reached break; } p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0); processResponse(p); p.recycle(); } } catch (java.io.IOException ex) { Rlog.i(RILJ_LOG_TAG, '’' + rilSocket + '’ socket closed', ex); } catch (Throwable tr) { Rlog.e(RILJ_LOG_TAG, 'Uncaught exception read length=' + length + 'Exception:' + tr.toString()); } //無法讀取數據,將CP狀態設置為不可用 setRadioState (RadioState.RADIO_UNAVAILABLE); ... mSocket = null; RILRequest.resetSerial(); // Clear request list on close clearRequestList(RADIO_NOT_AVAILABLE, false); }} catch (Throwable tr) { Rlog.e(RILJ_LOG_TAG,'Uncaught exception', tr); } } }

RILReceiver啟動時,會建立一個UNIX Domain socket(LocalSocket,kernel層對應/dev/socket/rild),與RILD進行通信,然后一直從socket中讀取數據,并將數據傳給上層。連接成功后,RILD會發送一個消息給RILJ,表示連接成功了,這樣RILJ就可以將請求數據發送給RILD,進行通信了。

RILD與CP如何進行通信

RILD與CP(可以看做是兩個運行在不同CPU上的進程通信)交換數據方式一般有兩種情況。如果AP與CP集中在一個芯片上,如高通的平臺就是將AP與CP集中在一塊芯片上,這時通常采用共享內存的方式實現跨進程通信;而如果不是在同一塊芯片,而是AP與CP分別采用不同廠商的平臺,則一般采用字符設備(character devices) 進行通信。總的說來,共享內存的方式在速度上要優于字符設備。

接下來,主要介紹下RILJ部分的代碼結構。

RILJ代碼結構

RIL Framework (RILJ)的代碼按照功能來劃分的話,主要有以下幾個組成部分:

管理網絡狀態(信號強度,網絡注冊狀態等):ServiceStateTracker等; 通話管理(撥號,接聽,呼叫等待等):CallManager,GsmCallTracker等 SMS短信接收發送:InboundSMSHandler,SmsDispater等 SIM卡管理:UiccController,SubscriptionsController等 數據鏈接管理:DcTracker,DctController等 Telephony 大管家:PhoneBase,GsmPhone,PhoneProxy等

Android RIL使用詳解

以上代碼主要位于兩個目錄:

/android/frameworks/opt/telephony/(負責與RILD交互) /android/frameworks/base/telephony/(對上層提供接口)

下面,以撥打電話的流程作為示例看一看RIL是如何發揮作用的。

示例:CALL流程

下圖是一個MO(Mobile Originated) 通話流程簡圖:

Android RIL使用詳解

APP向TelecomManager發送撥號請求(關于TelecomManager可以參考另一篇文章Android Telecom系統服務); TelecomManager將通話請求發送給GsmPhone; GsmPhone繼續將指令傳遞給GsmCallTracker; GsmCallTracker調用RILJ,RILJ將通話請求發送給RILD; RILD接收到通話指令時,發送給CP; CP發送給網絡,MT(Mobile Terminal)收到通話后,告知網絡,由網絡將該信息傳遞給MO已將通話信息發送給MT了(就是手機發出嘟嘟聲音的時候):通話狀態由DIALING ?> ALERTING; RILD收到通話狀態變化的消息后,發送一個UNSOL_RESPONSE_CALL_STATE_CHANGED的消息給RILJ; RILJ通知GsmCallTracker通話狀態變化了; GsmCallTracker主動查詢CALL狀態:pollCallWhenSafe(),確保得到的信息是對的,沒有發生變化; RILJ給RILD發送getCurrentCalls()的請求; RILD獲取到CALL狀態后,上報給RILJ,再由RILJ返回結果給GsmCallTracker GsmCallTracker得到確定的CALL狀態后,通知GsmPhone:notifyPreciseCallStateChanged(); GsmPhone將CALL狀態變化的消息告知Telecom系統服務; 最后,Telecom系統服務發送CALL狀態變化的廣播給上層APP

到這一步后,通話并沒有開始,如果MT接聽了電話,則MO會收到CALL狀態變化的信息,然后,才真正開始建立通話鏈接。

到此這篇關于Android RIL使用詳解的文章就介紹到這了,更多相關Android RIL內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Android
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲视频二区| 国产精品97| 亚洲人成网站在线在线观看| 国产美女一区| 中文日韩欧美| 国产亚洲毛片| 蜜桃一区二区三区在线| 蜜臀av一区二区三区| 蜜桃一区二区三区在线观看| 日韩一区二区三区免费视频| 亚洲tv在线| 欧美日韩在线精品一区二区三区激情综合 | 欧美日韩日本国产亚洲在线 | 日韩一级网站| 亚洲精品精选| 久久激情五月激情| 麻豆精品视频在线观看免费| 国产精品久久久久久久免费观看| 久久精品资源| 日韩精品影视| 狠狠干成人综合网| 亚洲精品在线a| 国产精品一区二区av日韩在线| 麻豆国产一区| 91精品一区国产高清在线gif | 欧美性www| 成人精品动漫一区二区三区| 久久精品播放| 国产视频一区欧美| 日本不卡的三区四区五区| 欧美精品不卡| 久久久水蜜桃av免费网站| 黄色国产精品| 91精品国产自产在线丝袜啪| 国产suv精品一区二区四区视频 | 国产精品宾馆| 日韩不卡在线| 亚洲精品黄色| 久久亚洲精品中文字幕| 国产在线观看www| 91久久在线| 久久精品99国产精品日本| 日韩综合一区| 欧美日韩国产综合网| 国产精品最新| 99免费精品| 日本午夜精品| 999精品一区| 欧美日韩伊人| 亚洲性图久久| 日韩国产欧美三级| 日韩欧美在线中字| 蜜桃视频在线观看一区| 国产一区二区视频在线看| 欧美日韩国产一区精品一区| 欧美久久亚洲| 激情综合亚洲| 久久av网站| 模特精品在线| 国产一区二区三区亚洲综合| 美女国产精品| 成人日韩av| 喷白浆一区二区| 国产福利电影在线播放| 天堂精品久久久久| 欧美日韩尤物久久| 美腿丝袜亚洲三区| 亚洲一区二区三区四区五区午夜| 久久97视频| 亚洲开心激情| 夜鲁夜鲁夜鲁视频在线播放| 日韩av在线免费观看不卡| 韩日一区二区三区| 精品中文字幕一区二区三区四区| 一区二区三区四区日韩| 欧美三区四区| 久久99影视| 亚洲精品护士| 久久久久久久久久久9不雅视频| 国产伦乱精品| 蜜桃91丨九色丨蝌蚪91桃色| 婷婷综合六月| 国产精品白丝久久av网站| 男人操女人的视频在线观看欧美| 久久久水蜜桃av免费网站| 国产欧美啪啪| 亚洲美女91| 国产视频一区欧美| 精精国产xxxx视频在线野外| 国产精品片aa在线观看| 亚洲区国产区| 六月婷婷一区| 欧美 日韩 国产精品免费观看| 国产66精品| 久久99久久人婷婷精品综合| 亚洲欧洲免费| 亚洲少妇诱惑| 极品裸体白嫩激情啪啪国产精品| 四虎成人av| 嫩呦国产一区二区三区av| 一二三区精品| 国产模特精品视频久久久久| 免费不卡中文字幕在线| 欧美xxxx中国| 精品入口麻豆88视频| 国产精品白丝av嫩草影院| 911亚洲精品| 亚洲乱码一区| 免费人成网站在线观看欧美高清| 国产综合精品| 欧美a级片一区| 精品一区三区| 国产精品99一区二区| 欧产日产国产精品视频| 成人国产精品一区二区免费麻豆| 欧美一区在线观看视频| 日韩不卡一区二区| 欧美一级二级视频| 日韩国产欧美三级| 日韩高清一区二区| 石原莉奈在线亚洲二区| 国产精品外国| 中文字幕一区二区三区四区久久| 玖玖精品视频| 四虎成人精品一区二区免费网站| 亚洲资源网站| 日本成人在线不卡视频| 日本不卡的三区四区五区| 午夜精品福利影院| 日韩美女国产精品| 亚洲精品九九| 日本强好片久久久久久aaa| 国产日本久久| 免费在线亚洲| 中文字幕高清在线播放| 久久久蜜桃一区二区人| 午夜国产精品视频免费体验区| 9国产精品视频| 一本一道久久a久久| 日韩国产欧美在线视频| 国产精品nxnn| 日本久久精品| 欧美综合另类| 最新亚洲激情| 亚洲免费毛片| 日本成人在线网站| 久久影院资源站| 午夜精品成人av| 伊人久久亚洲热| 亚洲精品极品| 欧美精品1区| 神马日本精品| 蜜臀av亚洲一区中文字幕| 国产精品一区二区三区www| 国产伊人久久| 午夜久久99| 午夜电影一区| 国产中文字幕一区二区三区| 99久久激情| 亚洲a级精品| 国产福利一区二区精品秒拍| www在线观看黄色| 91精品91| 欧美亚洲免费| 欧美二三四区| 中文字幕日本一区二区| 麻豆精品一区二区综合av| 欧美日韩免费观看视频| 久久夜色精品| 精品久久影院| 亚洲少妇自拍| 国产精品久久久一区二区| 蜜桃av.网站在线观看| 久久先锋影音| 久久99精品久久久久久园产越南 | 欧美日韩精品免费观看视欧美高清免费大片 | 激情不卡一区二区三区视频在线| 欧美成人综合| 国产日产高清欧美一区二区三区 | 蜜桃av一区| 精品国产乱码| 欧美日韩国产高清| 国产精品2023| 午夜日韩福利| 里番精品3d一二三区| 亚洲精品中文字幕乱码| 国产人成精品一区二区三| 久久精品青草| 欧美日韩视频免费看| 激情久久中文字幕| 国产精品久久久久久久久久久久久久久| 久久精品青草| 国产精品多人| 免费在线观看一区二区三区| 麻豆中文一区二区| 亚洲免费婷婷| а√天堂中文在线资源8| 亚洲v天堂v手机在线| 99国产精品免费视频观看| 国产乱人伦精品一区|