GSM模塊_Android建立GPRS通信的流程

開篇廢話

    首選聲明我是一個嵌入式系統開發工程師,我整理這篇文章的目的,其實是希望通過借鑑手機連接GPRS的流程,來完善系統內部對於GSM模塊集成的穩定性。所有內容來自網絡,在文末的參考鏈接標註了出處,如有冒犯原作者的地方請指正。

 

名詞解釋

CMNET/CMWAP:CMWAP 和CMNET 只是移動人爲劃分的兩個GPRS接入方式。前者是爲手機WAP上網而設立的,後者則主要是爲PC、 筆記本電腦、PDA等利用GPRS上網服務。它們在實現方式上並沒有任何差別,但因爲定位不同,所以和CMNET相比,CMWAP便有了部分限制,資費上也存在差別。CMWAP的端口爲80和8080(HTTP代理),9201(WAP網關協議)。

 

APN:Access PointName,接入點名稱。是您在通過手機上網時必須配置的一個參數,它決定了您的手機通過哪種接入方式來訪問網絡。

 

PDP:Packet Data Protocol 分組數據協議。是GPRS連接的軟硬件環境,指定GPRS連接的接入點APN,連接類型IP或PPP,還有其他一些可選項。

 

PPP:Point-to-PointProtocol 業務流模板。終端和MODEM之間點對點的協議,包括終端於MODEM之間的鏈路層協商(LCP),服務器對終端的認證(PAP或CHAP,這一步非強制),以及終端與服務器的網絡層協商(基本都是IPCP)。PPP相當於鏈路層協議socket套接字,對TCP/IP協議的封裝、應用。GPRS上網首先要設置PDP,接着建立PPP連接,PPP連接建立之後,就可以進行TCP/IP傳輸了,要進行TCP/IP數據傳輸,很多時候都採用socket。

 

SOCKET:進程之間的通信方式,手機上的應用程序(客戶進程)要和服務器的某個服務進程通信,就用socket通過邦定的TCP或UDP端口基於IP進行數據傳輸。


RIL:Radio Interface Layer 無線接口層。RIL工作在PPP、TCP/IP協議之下,負責數據的可靠傳輸、AT命令的發送以及response的解析。除了對網絡的支持,RIL也支持SMS、Voice Call等功能。

 

Data Connect流程分析

    Android的數據連接是基於PPP方式的,主要步驟爲:首先通過AT命令激活PDP連接,然後利用pppd通過數據端口完成撥號連接。數據連接的核心控制類是DataConnectionTracker,存在於GSMPhone裏,數據連接不需要用戶的干預,在APN設置好之後,在適當的情況下就會自動激活,激活的入口點是:DataConnectionTracker.trySetupData→setupData→     PdpConnection.connetc→CommandsInterface.setupDefaultPDP,通過PdpConnection訪問GSMPhone中的RIL層的setupDefaultPDP實現,setupDefaultPDP的結果由EVENT_SETUP_PDP_DONE返回,如果成功,則開始調用pppd完成實際連接,這是通過DataLink.connect實現的; DataLink只是抽象基類,此處它的實現類是PppLink,實現DataLinkInterface接口,所以DataLink.connect實際上調用PppLink.connect,它通過SystemService.start(SERVICE_PPPD_GPRS)開始pppd服務,並通過checkPPP函數訪問Linux的sys文件系統來查詢pppd的連接狀態,如果成功,便可以將LINKUP的消息通知出去以完成連接流程。

 

RILD源碼分析

    RIL對消息的處理是將消息通過LocalSocket發送到以rild爲名稱的有名端口。這個有名Socket的創建在ril.cpp代碼中。s_fdListen = android_get_control_socket(SOCKET_NAME_RIL) 

RILD是守護進程,執行的過程爲:獲取參數→打開功能庫→建立事件循環→執行RIL_Init→RIL_register;事件循環式核心,通過Select多路複用機制,讀取來自上層的Socket接口的具體操作命令,同時一些命令Timeout喚醒機制,也通過Select實現; 

1.   Request流程 

命令下發流程:首先從JAVA層通過Socket將命令發送到RIL層的RILD守護進程,RILD中負責監聽的ril_event_loop消息循環中的Select發現RILD Socket有了請求連接信號,建立一個record_stream,打通與上層的數據通道並開始接收請求數據,數據通道的回調函數processCommandsCallback()會保證收到一個完整的Request後,將其送達processCommandBuffer()函數; 

解析過程:processCommandBuffer()從Socket中序列化的數據流裏還原信息,將其組織到RequestInfo中;RequestInfo數據結構如下(存在於ril.cpp中): 

typedef struct RequestInfo { 

    int32_t token;//this is not RIL_Token

    CommandInfo *pCI;

    struct RequestInfo *p_next;

    char cancelled; 

    char local; // responses to local commands do not go back to command process

}RequestInfo; 

    RIL層以Request號爲基礎採用表驅動方式分發請求,CommandInfo結構表示命令的信息,關聯了Request號和實際的請求函數,以及響應函數之間的關係; 分發流程:s_callback.onRequest()完成分發操作,s_callback獲取自libreference-ril的RIL_RadioFunction結構指針,Request請求在這裏轉入底層的libreference-ril處理,handler是reference-ril.cpp中的Request。 

    onRequest根據Request號進行簡單的switch分發,然後將命令和參數轉換成對應的AT命令,由writeline()完成驅動層的發送,writeline通過驅動程序節點的文件描述符進行寫操作實現控制。 


2.   Response流程 

    Response有兩類:unsolicited表示主動上報的消息,如來電,來短信等,而solicited是AT命令的響應,判斷是否是solicited的依據有兩點:一是當前用AT命令正在等待響應;二是讀取的響應符合該AT命令的響應格式。 對於Response流程來講,流程是從Modem設備發回響應數據開始的。 RIL通過readerLoop函數,利用readline逐行讀取響應數據,隨後通過processLine進行分析,主動上報的一般以+XXXX的形式出現,而AT命令的響應格式則有一行或多行之分,但最終一定以OK或者ERROR結尾,於是PrcessLine有以下幾種情況: 

1)、沒有AT命令等待響應或不符合AT響應格式,一般是主動上報行,由handleUnsolicited處理,handleUnsolicited→onUnsolicetd→RIL_onUnsolicitedResponse; 

2)、isFinalResponseSucess/isFinalResponseError是最終響應行,轉到handleFinalResponse處理,handleFInalResponse會發送線程同步信號,激活等到的發送線程; 

3)、符合當前AT命令響應格式的行,解析並獲取數據,這是響應處理的中間過程,然後繼續收到最終響應行,然後進入2流程 最後的發送動作由sendResponse→sendResponseRaw→blockingWrite通過Socket回傳給上層來完成,響應解析由上層完成。

 

專有APN

    專有APN在功能上可以和Internet的VPN做類比,實際上他就是基於GPRS的VPN網絡。
專有APN常見組網方式
1,運營商部署一條專線接入到企業的網絡中,局端和企業端路由器之間採用私有IP進行連接。
2,局端互連路由器與GGSN採用GRE隧道連接。
專有APN的幾個重要特點:
1,除非運營商分配一個Internet IP地址,否則計算機沒有任何辦法通過Internet訪問該APN中的主機。
2,只有手機卡號在APN中的白名單之列,該手機纔可以接入該APN。
3,企業客戶可以建立一套RADIUS和DHCP服務器,GGSN向RADIUS服務器提供用戶主叫號碼,採用主叫號碼和用戶賬號相結合的認證方式;用戶通過認證後由DHCP服務器分配企業內部的靜態IP地址。補充:該認證方式不一定適合於每個省的運營商,這取決於該省運營商的APN管理平臺。

PPP和PDP激活

    PPP協商過程中的IPCP配置中,終端通過MODEM請求激活PDP上下文獲得IP地址完成網絡連接,PDP中設置的APN就是終端所在的這個網絡的網關,終端訪問internet時就得通過這個網關; 而終端的客戶進程與服務器的服務進程進行socket通信時,就基於這個IP地址。

    據我所知道的:從網絡側來看,PPP連接最重要的一步是獲取IP地址,這個IP由GGSN分配,GGSN是GPRS網到internet的網關,GSM和WCDMA協議規定一個MODEM可以和多個GGSN建立PDP上下文,不知道你所說的服務器是否指GGSN。而socket連接的服務器和GGSN完全是兩碼事,socket連接的是internet網絡中的服務器,socket是用於進程間通信的,它將進程與TCP/UDP端口進行綁頂,一個client端的socket只能連接一個serversocket。也就決定了它只能連接一臺服務器。如果你要寫應用程序,你只需要關心socket的函數族就可以了,不需要去考慮GPRS如何如何,它對你是透明的。


當然,寫應用的時候必須注意兩件事:

1、GPRS是否可用。如果當前GPRS根本就無法連接,你開socket是毫無意義的;

2、擁塞控制。GPRS速度其實並不高,從理論上來說,如果你的平臺上的TCP/IP足夠完整,你根本不需要考慮GPRS的內容,只需要根據TCP/IP協議棧上的接口就完全可以控制應用程序的調度和流控了。通常的平臺上,TCP/IP協議棧都是“賽揚”版的,所以應用程序經常還需要去讀取GPRS狀態。如果你寫的是GPRS協議棧,關心到PDP就可以爲止了。如果手機的GPRS沒有長時間掉線,就不會變化。PDP就是處理這件事的。PDP的作用相當於維持一根看不見的網線,不管你走到哪兒都保證你IP地址不變。


PPP是發生在PDP和TCP/IP之間的。這裏引入PPP基於兩個歷史淵源:

1、TCP/IP當然可以覆蓋在PDP之上,但這幾乎就是重寫TCP/IP了。而更早的時候已經有以PPP爲底層的TCP/IP了。PPP的移植又比TCP/IP的移植要簡單得多。於是就有人先把PPP移植到PDP上,然後再在上面蓋一層TCP/IP。PPP其實就是一個DL(數據鏈路層)的變異體;

2、(實際上這個纔是真正的最主要的淵源),最開始的處理器能力都不夠,跑GPRS之後,根本不可能再跑TCP/IP協議棧和應用,GPRS充當modem,TCP/IP和應用程序在PC一端。

    GPRS的數據怎麼弄進PC呢?這就是PPP的用武之地了。PC和GPRS modem用串口進行物理鏈接,串口之上覆蓋PPP協議,PPP的一端是GPRS modem的PDP。另一端就是TCP/IP的數據鏈路層接口。

參考鏈接

PPP,PDP原理以及同socket的關係
http://wenku.baidu.com/view/c9e45e0dbb68a98271fefa25.html?re=view
Android APN開發流程分析
http://wenku.baidu.com/view/fc9eca060740be1e650e9aa1.html
Android 新建一個APN後的數據連接的調試過程
http://blog.csdn.net/napolun007/archive/2010/07/21/5753018.aspx
Android建立GPRS通信的流程
http://blog.csdn.net/yankebin/article/details/44035489
Android啓用GPRS成功後反饋流程(MTK)
http://blog.csdn.net/yankebin/article/details/44034587
Android AT命令與APN開發流程分析
http://www.programgo.com/article/78322543743/
發佈了54 篇原創文章 · 獲贊 83 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章