Android GSM驅動模組(rild)詳細分析(三)response流程

來源:互聯網
上載者:User
前文對request的分析, 終止在了at_send_command_full_nolock裡的writeline操作,因為這裡完成命令寫出到硬體裝置的操作,接下來就是等待硬體響應,也就是response的過程了。我們的分析也是從這裡開始。

response資訊的擷取,是在第一篇初始化分析中,提到的readerLoop中。由readline函數以‘行’為單位接收上來。
AT的response有兩種,一是主動上報的,比如網路狀態,簡訊,來電等都不需要經過請求,有一unsolicited詞語專門描述。另一種才是真正意義上的response,也就是命令的響應。

這裡我們可以看到,所有的行,首先經過sms的自動上報篩選,因為簡訊的AT處理通常比較麻煩,無論收發都單獨列出。這裡是因為要即時處理這條簡訊訊息(兩行,標誌+pdu),而不能拆開處理。處理函數為onUnsolicited(由s_unsolHandler指向),我們等下介紹。

除開sms的特例,所有的line都要經過processLine,我們來看看這個流程:
processLine
|----no cmd--->handleUnsolicited //主動上報
|----isFinalResponseSuccess--->handleFinalResponse //成功,標準響應
|----isFinalResponseError--->handleFinalResponse //失敗,標準響應
|----get '>'--->send sms pdu //收到>符號,發送sms資料再繼續等待響應
|----switch s_type--->具體響應  //命令有具體的響應資訊需要對應分析

我們這裡主要關注handleUnsolicited自動上報(會調用到前面smsUnsolicite也調用的onUnsolicite),以及 switch s_type具體響應資訊,另外具體響應需要handleFinalResponse這樣的標準響應來最終完成。

1. onUnsolicite(主動上報響應)
static void onUnsolicited (const char *s, const char *sms_pdu);
簡訊的AT設計真是麻煩的主,以致這個函數的第二個參數完全就是為它準備的。
response 的主要的解析過程,由at_tok.c中的函數完成,其實就是字串按塊解析,具體的解析方式由每條命令或上報資訊自行決定。這裡不再詳述,onUnsolicited只解析出頭部(一般是+XXXX的形式),然後按類型決定下一步操作,操作為 RIL_onUnsolicitedResponse和RIL_requestTimedCallback兩種。

a)RIL_onUnsolicitedResponse:
將 unsolicited的資訊直接返回給上層。通過Parcel傳遞,將 RESPONSE_UNSOLICITED,unsolResponse(request號)寫入Parcel先,然後通過 s_unsolResponses數組,尋找到對應的responseFunction完成進一步的的解析,存入Parcel中。最終通過 sendResponse將其傳遞迴原進程。流程:

sendResponse-->sendResponseRaw-->blockingWrite-->write to s_fdCommand(前面建立起來的和上層架構的socket串連)

這些步驟之後有一些喚醒系統等其他動作。不再詳述。
b)RIL_requestTimedCallback:
通過event機制(參考文章二)實現的timer機制,回調對應的內部處理函數。通過internalRequestTimedCallback將回調添加到event迴圈,最終完成callback上掛的函數的回調。比如pollSIMState,onPDPContextListChanged等回調, 不用返回上層, 內部處理就可以。

2. switch s_type(命令的具體響應)及handleFinalResponse(標準響應)
命令的類型(s_type)在send command的時候設定(參考文章二),有NO_RESULT,NUMERIC,SINGLELINE,MULTILINE幾種,供不同的AT使用。比如AT+CSQ是singleline, 返回at+csq=xx,xx,再加一行OK,比如一些設定命令,就是no_result, 只有一行OK或ERROR。

這幾個類型的解析都很相仿,通過一定的判斷(比較AT頭標記等),如果是對應的響應,就通過 addIntermediate掛到一個臨時結果sp_response->p_intermediates隊列裡。如果不是對應響應,那它其實應該是穿插其中的自動上報,用onUnsolicite來處理。

具體響應,只起一個擷取響應資訊到臨時結果,等待具體分析的作用。無論有無具體響應,最終都得以標準響應handleFinalResponse來完成,也就是接受到OK,ERROR等標準response來結束,這是大多數AT命令的規範。

handleFinalResponse 會設定s_commandcond這一object,也就是at_send_command_full_nolock等待的對象。到這裡,響應的完整資訊已經完全獲得,send command可以進一步處理返回的資訊了(臨時結果,以及標準返回的成功或失敗,都在sp_response中)。

pp_outResponse參數將sp_response返回給調用at_send_command_full_nolock的函數。
繼續我們在文章二的分析的話,這個函數其實是requestDial,不過requestDial忽略了響應,所以我們另外看個例子,如requestSignalStrength,命令其實就是前面提到的at+csq:

可以看到確實是通過at_send_command_singleline來進行的操作,response在p_response中。
p_response如果返回失敗(也就是標準響應的ERROR等造成),則通過RIL_onRequestComplete發送返回資料給上層,結束命令。
如果成功,則進一步分析p_response->p_intermediates, 同樣是通過at_tok.c裡的函數進行分析。並同樣將結果通過RIL_onRequestComplete返回。

RIL_onRequestComplete:
RIL_onRequestComplete和RIL_onUnsolicitedResponse很相仿,功能也一致。
通過Parcel來傳遞迴上層,同樣是先寫入RESPONSE_SOLICITED(區別於 RESPONSE_UNSOLICITED),pRI->token(上層傳下的request號),錯誤碼(send command的錯誤,不是AT響應)。如果有AT響應,通過訪問pRI->pCI->responseFunction來完成具體 response的解析,並寫入Parcel。

然後通過同樣的途徑:
sendResponse-->sendResponseRaw-->blockingWrite-->write to s_fdCommand
完成最終的響應傳遞。

到這裡,我們分析了自動上報與命令響應,其實response部分,也就告一段落了。
三篇分析RIL的文章也到此結束。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.