在前面介紹的R/W模式中,NFC Device只能單向和NFC Tag交互,即只能NFC Device單方對NFC Tag發起操作,而NFC所基于的無線射頻技術實際上可以支持NFC Device之間互相傳遞數據。為了滿足NFC Device之間雙向交互的需求,NFC Forum定義了P2P(Peer-to-Peer)運行模式。
圖8-9展示了IEEE 802參考模型、OSI參考模型及NFC P2P的協議棧參考模型。由此圖可知,NFC P2P協議棧最高層為LLC(Logical Link Control,邏輯鏈路控制層)。這一層使用的協議稱為LLCP(LLC Protocol)。
在OSI參考模型中,LLC比較偏底層,其更多考慮的是物理地址尋址、鏈路管理,以及數據傳輸方面的事情(參考3.3.1節關于OSI/RM的介紹)。所以,NFC也在LLC層之上添加了一些對使用者更為方便和友好的協議。圖8-10所示為NFC P2P協議棧的全貌。
:-: 
圖8-9 NFC P2P協議棧
:-: 
圖8-10 NFC P2P協議棧參考模型全貌
* SNEP(Simple NDEF Exchange Protocol)緊接LLC層。該協議使得兩個NFC Device之間能直接交換NDEF消息。
* 通過Protocol Bindings,NFC可支持其他高層次并且用途更加廣泛的協議。根據參考資料[3]所示的內容,NFC可支持IP和OBEX(Object Exchange,對象交換)協議,但經過調查發現NFC Forum官網目前只有LLCP-OBEX-Binding協議的草案,而LLCP和IP協議如何綁定還在研究當中。
* Other Protocols中目前比較常用的是CHP(Connection Handover Protocol)。
目前,Android 4.2中的NFC P2P模塊支持SNEP和CHP。本章將重點分析SNEP,而CHP則請讀者學完本章后再自行研究。下面先介紹LLCP,然后再介紹SNEP。
**1、LLCP介紹**
NFC LLCP比較簡單,對應的規范全長也只有40來頁。關于LLCP,從以下兩個方面來介紹。
* LLCP的數據封包格式。對學習通信協議來說,掌握數據包格式非常重要。
* NFC LLCP對上層提供無鏈接(Connectionless)和面向鏈接(Connection-oriented)的兩種數據傳輸服務。其中,無鏈接的數據傳輸服務和UDP類似,上層的收發雙方無須事先建立邏輯鏈接關系即可收發數據。面向鏈接的數據傳輸服務和TCP類似,收發雙方發送數據前,需要在LLC層先建立邏輯鏈接關系(即類似TCP協議中的connect和accept)。同時,LLC層還會處理數據包丟失、重傳以及接收確認等方面的事情。目前SNEP和CHP均使用了LLC提供的面向鏈接的數據傳輸服務,故我們將重點介紹它。
**①、LLCP數據包格式**
NFC LLC層數據封包格式如圖8-11所示。
:-: 
圖8-11 NFC LLCP數據包格式
由圖8-11可知,LLCP數據包前3字節為LLCP Header。LLCP Header之后就是Payload,其長
度由PTYPE來決定。
* DSAP和SSAP分別代表Destination和Source Service Access Point(目標和源服務接入點)。DSAP和SSAP的作用類似于TCP/UDP中的端口號。注意,使用NFC LLCP時,DSAP和SSAP可唯一確定通信雙方。讀者可能有疑問,使用TCP/UDP時,除了指明端口號外,還需要指明對端設備的IP地址,但NFC LLCP數據包中卻沒有這樣的信息。另外,和圖3-24所示的LLC數據封裝格式比起來,NFC LLCP數據包也沒有MAC地址這樣的字段。也就是說,LLCP只需要通信雙方所使用的端口號即可,而無需MAC或IP地址這樣的信息,這是因為NFC近距離作用的特點使得通信雙方從進入有效距離內開始就已彼此確定,故無需再通過MAC地址指明誰是接收設備,誰是發送設備。而當上層通過LLC發送數據或者LLC向上層傳遞接收到的數據時則需要通過類似端口這樣的SSAP和DSAP來進一步確定發送模塊和接收模塊到底是誰。
* PTYPE字段指明LLCP包的類型。NFC LLCP定義了多種不同類型的包,下文將結合面向鏈接的數據傳輸服務來學習相關的LLCP包。
* Sequence字段指明LLCP包的序號,它可分為Send端和Receiver端。由于有一些類型的LLCP包無需Sequence字段,所以Sequence字段長度有可能為0。例如,無鏈接的數據包就不需要Sequence字段,而面向鏈接的數據包需要該字段來處理數據接收確認或丟失重傳等方面的事情。
由上述介紹可知,DSAP和SSAP類似TCP/UDP的端口號,決定了收發模塊到底是誰。表8-6所示為NFC中SAP取值情況。
:-: 
表8-6 LLCP SAP取值說明
以SNEP的使用為例:
* 位于NFC Device A的服務端模塊在SSAP為0x04的端口上進行監聽。
* 位于NFC Device B的客戶端模塊選擇一個合適的SSAP,設置DSAP為0x04。然后該客戶端模塊發送數據包,LLC負責將數據包打包傳遞給NFC Device B(假設這兩個設備都在彼此的有效距離內)。
* NFC Device A的LLC層接收到數據包后發現DSAP為0x04,而其上剛好有一個服務模塊工作在0x04端口,故LLC層將把數據包傳遞給這個在0x04端口上監聽的服務模塊。
下面將通過分析面向鏈接數據傳輸服務的工作流程來進一步研究LLCP。
**②、面向鏈接數據傳輸服務**
假設Device A和Device B打開了NFC功能。當二者進入有效距離后,它們的LLC模塊將進入Link Activation(鏈路激活)階段,在此階段中,A和B的交互過程如圖8-12所示。
:-: 
圖8-12 Link Activation工作流程
* 進入Link Activation時,Device A和Device B將分別扮演Initiator和Target角色,參考資料[13]可用于確定誰來扮演Initiator或Target。
* Initiator發送PAX數據包給Target。PAX全稱為Parameter Exchange,它用于在兩個設備間交換彼此的LLC層配置信息(如協議版本等,詳情見下文)。
* Target收到Initiator的PAX包后需要相應處理,例如判斷協議版本是否匹配等。Target處理完后,它需要發送自己的LLC層配置信息給Initiator。
* Initiator檢查Target的LLC層配置參數,如果一切正常,雙方Logical Link成功建立,隨后可進入正常工作階段。
根據上述內容,雙方需要通過PAX交換LLC層的配置信息。PAX屬于LLCP數據包的一種,其格式如圖8-13所示。
:-: 
圖8-13 PAX數據包
LLC層的配置信息保存在圖8-13中的參數列表中,正常情況下PAX攜帶的參數信息及作用如表8-7所示。(注意,并非所有參數都會包含在圖8-13的參數列表中。)
:-: 
表8-7 PAX參數說明
以上知識有一些細節需要讀者注意。
* 當Device A和Device B進入有效距離后,Link Activation將被觸發,而Device A和B分開后,Link Deactivation將被觸發。從使用角度來看,Link Activation/Deactivation可能會頻繁被觸發。
* WKS用于告知本機設備哪些Well-Known服務端口上有模塊在監聽。這表明在LinkActivation被觸發前,使用者就必須在感興趣的WKS端口上進行監聽。這和筆者之前所認為的設備先進入Link Activation,然后再監聽WKS端口不同。以后分析Android平臺中SNEP的代碼時讀者將看到相關的處理。
Link被激活后,Device A和Device B將先建立面向鏈接的關系,然后再開展數據交互,這一流程如圖8-14所示。
:-: 
圖8-14 面向鏈接工作流程
假設Device A扮演Client角色,Device B扮演Server角色。Client先通過CONNECT包向Server發起鏈接請求。CONNECT包對應的格式如圖8-15所示。
:-: 
圖8-15 CONNECT包格式
CONNECT包需要攜帶一些參數信息,常見的參數如表8-8所示。
:-: 
表8-8 CONNECT參數說明
當服務器端成功處理CONNECT包后,它將回復CC(Connection Complete)包給客戶端。如此,Client和Server就建立了鏈接關系。CC包內容非常簡單,請讀者自行研究參考資料[12]。此后,Client和Server就可通過Information(規范中簡稱為I)包和RR(Receive Ready)包來傳輸數據,其中:
* I包用于承載具體的數據。
* RR包用來確認接收方確實收到了數據。
I和RR包比較簡單,這部分內容也請讀者自行研究參考資料[12]。
總體而言,LLCP比較簡單,不過直接使用LLCP還是稍顯復雜。所以,在LLCP基礎上,NFCForum定義了SNEP協議用于在兩個NFC Device之間傳輸NDEF消息。下面來學習SNEP。
**2、SNEP介紹[14]**
SNEP(Simple NDEF Exchange Protocol)支持在兩個NFC Device之間交換NDEF消息。SNEP是一種基于面向鏈接的數據傳輸協議,作為Well-Known Service的一種,其服務端口號為0x04,服務名為"urn:nfc:sn:snep"。
SNEP屬于Request/Response方式,其工作過程如圖8-16所示。
:-: 
圖8-16 SNEP工作方式
SNEP的工作流程非常簡單,主要包括兩個步驟。
1. SNEP客戶端發送SENP Request消息給服務端進行處理。
2. SNEP服務端回復SNEP Response消息給客戶端以告知處理結果。
SNEP Request消息和Response消息的格式如圖8-17所示。
:-: 
圖8-17 SNEP Request/Response消息格式
圖8-17中,SNEP Request/Response消息開頭都是1字節的Version字段,Version字段之后分別是Request字段和Response字段。Request字段表示請求類型,Response字段表示處理結果。
表8-9所示為SNEP當前支持的Request類型。
:-: 
以SNEP Put請求消息為例,其對應的格式如圖8-18所示。
:-: 
圖8-18 SNEP Put消息格式
SNEP協議本身非常簡單,此處不詳細介紹,本章下文將結合代碼來介紹Android中SNEP的實現。
至此,我們對NFC LLCP進行了相關介紹。這部分難度不大,讀者需要重點掌握的部分包括LLCP協議本身,尤其是其數據封包格式、各種參數信息、常見SAP等。在LLCP基礎上,讀者可學習SNEP這種比較常用的協議。另外,讀者還可在本節基礎上自行學習ConnectionHandover,它是另外一種基于LLCP面向鏈接數據傳輸服務的協議。
>[info] 提示 以后在分析Android NFC模塊代碼時也會碰到Connection Handover,請讀者自己來分析。
下面來看NFC運行模式中最后一種,即NFC CE(Card Emulation)模式。
- 前言
- 第1章 準備工作
- 1.1 Android系統架構
- 1.2 工具使用
- 1.2.1 Source Insight的使用
- 1.2.2 Eclipse的使用
- 1.2.3 BusyBox的使用
- 1.3 本書資源下載說明
- 第2章 深入理解Netd
- 2.1 概述
- 2.2 Netd工作流程
- 2.2.1 main函數分析
- 2.2.2 NetlinkManager分析
- 2.2.3 CommandListener分析
- 2.2.4 DnsProxyListener分析
- 2.2.5 MDnsSdListener分析
- 2.3 CommandListener中的命令
- 2.3.1 iptables、tc和ip命令
- 2.3.2 CommandListener構造函數和測試工具ndc
- 2.3.3 InterfaceCmd命令
- 2.3.4 IpFwd和FirewallCmd命令
- 2.3.5 ListTtysCmd和PppdCmd命令
- 2.3.6 BandwidthControlCmd和IdletimerControlCmd命令
- 2.3.7 NatCmd命令
- 2.3.8 TetherCmd和SoftapCmd命令
- 2.3.9 ResolverCmd命令
- 2.4 NetworkManagementService介紹
- 2.4.1 create函數詳解
- 2.4.2 systemReady函數詳解
- 2.5 本章總結和參考資料說明
- 2.5.1 本章總結
- 2.5.2 參考資料說明
- 第3章 Wi-Fi基礎知識
- 3.1 概述
- 3.2 無線電頻譜和802.11協議的發展歷程
- 3.2.1 無線電頻譜知識
- 3.2.2 IEEE 802.11發展歷程
- 3.3 802.11無線網絡技術
- 3.3.1 OSI基本參考模型及相關基本概念
- 3.3.2 802.11知識點導讀
- 3.3.3 802.11組件
- 3.3.4 802.11 Service介紹
- 3.3.5 802.11 MAC服務和幀
- 3.3.6 802.11 MAC管理實體
- 3.3.7 無線網絡安全技術知識點
- 3.4 Linux Wi-Fi編程API介紹
- 3.4.1 Linux Wireless Extensions介紹
- 3.4.2 nl80211介紹
- 3.5 本章總結和參考資料說明
- 3.5.1 本章總結
- 3.5.2 參考資料說明
- 第4章 深入理解wpa_supplicant
- 4.1 概述
- 4.2 初識wpa_supplicant
- 4.2.1 wpa_supplicant架構
- 4.2.2 wpa_supplicant編譯配置
- 4.2.3 wpa_supplicant命令和控制API
- 4.2.4 git的使用
- 4.3 wpa_supplicant初始化流程
- 4.3.1 main函數分析
- 4.3.2 wpa_supplicant_init函數分析
- 4.3.3 wpa_supplicant_add_iface函數分析
- 4.3.4 wpa_supplicant_init_iface函數分析
- 4.4 EAP和EAPOL模塊
- 4.4.1 EAP模塊分析
- 4.4.2 EAPOL模塊分析
- 4.5 wpa_supplicant連接無線網絡分析
- 4.5.1 ADD_NETWORK命令處理
- 4.5.2 SET_NETWORK命令處理
- 4.5.3 ENABLE_NETWORK命令處理
- 4.6 本章總結和參考資料說明
- 4.6.1 本章總結
- 4.6.2 參考資料說明
- 第5章 深入理解WifiService
- 5.1 概述
- 5.2 WifiService的創建及初始化
- 5.2.1 HSM和AsyncChannel介紹
- 5.2.2 WifiService構造函數分析
- 5.2.3 WifiStateMachine介紹
- 5.3 加入無線網絡分析
- 5.3.1 Settings操作Wi-Fi分析
- 5.3.2 WifiService操作Wi-Fi分析
- 5.4 WifiWatchdogStateMachine介紹
- 5.5 Captive Portal Check介紹
- 5.6 本章總結和參考資料說明
- 5.6.1 本章總結
- 5.6.2 參考資料說明
- 第6章 深入理解Wi-Fi Simple Configuration
- 6.1 概述
- 6.2 WSC基礎知識
- 6.2.1 WSC應用場景
- 6.2.2 WSC核心組件及接口
- 6.3 Registration Protocol詳解
- 6.3.1 WSC IE和Attribute介紹
- 6.3.2 802.11管理幀WSC IE設置
- 6.3.3 EAP-WSC介紹
- 6.4 WSC代碼分析
- 6.4.1 Settings中的WSC處理
- 6.4.2 WifiStateMachine的處理
- 6.4.3 wpa_supplicant中的WSC處理
- 6.4.4 EAP-WSC處理流程分析
- 6.5 本章總結和參考資料說明
- 6.5.1 本章總結
- 6.5.2 參考資料說明
- 第7章 深入理解Wi-Fi P2P
- 7.1 概述
- 7.2 P2P基礎知識
- 7.2.1 P2P架構
- 7.2.2 P2P Discovery技術
- 7.2.3 P2P工作流程
- 7.3 WifiP2pSettings和WifiP2pService介紹
- 7.3.1 WifiP2pSettings工作流程
- 7.3.2 WifiP2pService工作流程
- 7.4 wpa_supplicant中的P2P
- 7.4.1 P2P模塊初始化
- 7.4.2 P2P Device Discovery流程分析
- 7.4.3 Provision Discovery流程分析
- 7.4.4 GO Negotiation流程分析
- 7.5 本章總結和參考資料說明
- 7.5.1 本章總結
- 7.5.2 參考資料說明
- 第8章 深入理解NFC
- 8.1 概述
- 8.2 NFC基礎知識
- 8.2.1 NFC概述
- 8.2.2 NFC R/W運行模式
- 8.2.3 NFC P2P運行模式
- 8.2.4 NFC CE運行模式
- 8.2.5 NCI原理
- 8.2.6 NFC相關規范
- 8.3 Android中的NFC
- 8.3.1 NFC應用示例
- 8.3.2 NFC系統模塊
- 8.4 NFC HAL層討論
- 8.5 本章總結和參考資料說明
- 8.5.1 本章總結
- 8.5.2 參考資料說明
- 第9章 深入理解GPS
- 9.1 概述
- 9.2 GPS基礎知識
- 9.2.1 衛星導航基本原理
- 9.2.2 GPS系統組成及原理
- 9.2.3 OMA-SUPL協議
- 9.3 Android中的位置管理
- 9.3.1 LocationManager架構
- 9.3.2 LocationManager應用示例
- 9.3.3 LocationManager系統模塊
- 9.4 本章總結和參考資料說明
- 9.4.1 本章總結
- 9.4.2 參考資料說明
- 附錄