摘要:終于,在去年的上,蘋果宣布開放其接口,這為以后的應用開發提供了更多的可能。目前,蘋果的對的格式支持有限,暫時僅支持格式。
前言
NFC這個詞相信大家現在都已經不陌生了,各大城市的地鐵、商場等等支持NFC支付一度成為頭條的熱點。其實很早之前就已經有二維碼和NFC的誕生了,但是由于二維碼成本低廉,技術門檻相對較低,因此,二維碼迅速搶占了移動支付的市場,但是,與此同時NFC的發展并未因此停止。
其實在安卓端的NFC發展已經非常迅猛了,只是我們的蘋果爸爸遲遲不肯帶我們一起玩NFC。終于,在去年的WWDC上,蘋果宣布“開放”其NFC接口,這為以后NFC的應用開發提供了更多的可能。
關于NFC
NFC(Near Field Communication)近場通信,當兩個設備相互靠近時能進行信息交流的一個技術。
使用了NFC技術的設備(比如手機)可以在彼此靠近的情況下進行數據交換,是由非接觸式射頻識別(RFID)及互連互通技術整合演變而來,通過在單一芯片上集成感應式讀卡器、感應式卡片和點對點通信的功能,利用移動終端實現移動支付、電子票務、門禁、移動身份識別、防偽等應用。目前,蘋果的CoreNFC對NFC的格式支持有限,暫時僅支持NDEF格式。
關于NDEF
NDEF(NFC Data Exchange Format)是一種能夠在NFC設備或者標簽之間進行信息交換的數據格式。NDEF格式由各種 NDEF Messages 和 NDEF Records 組成。NDEF格式使用了一種容易理解的格式來存儲和交換信息,如:URI、純文本等等。
NFC標簽,像Mifare Classic卡片可以配置為NDEF標簽,通過一個NFC設備寫入的數據可以被其他NDEF兼容的設備訪問。NDEF消息還可以用于兩個活躍的NFC設備之間“點對點”模式交換數據。
NDEF Messages
NDEF Messages是NDEF Records交換機制的基礎,每一個message包含一個或多個records。
NDEF Records
NDEF Records包含一個特定的payload,并且有以下結構來標識內容和記錄大小:
Record Header(記錄頭)
記錄頭包含了很多重要的信息,它占用3個位來標識遵循TNF協議的記錄的類型,講人話就是這3個位用來表示這條記錄的類型的。
TNF: Type Name Format 字段
一條NDEF記錄的類型名稱是一個3個位的數值,用來描述這條記錄的類型,并且可以用來設置對該記錄中其它的結構和內容的期望。簡單的說就是這3個位不僅可以表示該條記錄的類型,也可以在一定程度上決定了該條記錄接下來的數據結構。可能的記錄名稱如下表:
TNF Value
Record Type
0x00
Empty Record 表明這條記錄沒有類型、id或有效payload。這個記錄類型一般用于新格式化的NDEF卡上,因為NDEF標簽必須有至少一個NDEF紀錄。
0x01
Well-Known Record 表明記錄類型字段使用RTD類型名稱格式。這種類型名稱用一個Record Type Definition (RTD)來存儲任何指定的類型,例如:存儲RTD文本、RTD URIs等等。同時,這是一種比較常用的也比較有用的記錄類型。
0x02
MIME Media Record 表明payload是這條NDEF記錄分塊的中間或者最后一塊。
0x03
Absolute URI Record 表明這條記錄的類型字段一定包含一個URI字段。
0x04
External Record 表明這條記錄的類型字段包含一個RTD格式的外部字段。
0x05
Unknown Record 表明payload的類型未知。
0x06
Unchanged Record 未發生變化的記錄類型,釋同MIME Media Record。
IL:ID Length 字段
IL是ID長度的標志位,用來表示下面的ID Length字段是否省略。如果這個位設置為0,則該條記錄中省略ID Length。
SR:Short Record 位
短記錄標志位,如果下面的PAYLOAD LENGTH字段小于等于一個字節,則該位設置為1 。
CF:Chunk Flag
塊標識位,用于標識當前塊是第一個記錄塊還是中間的記錄塊。
ME:Message End
結束標志位,用于標識當前記錄是否是當前Message的最后一條記錄。
MB:Message Begin
起始標志位,用于標識當前記錄是否是當前Message的第一條記錄。
Type Length
表示類型字段的長度。對于上面TNF字段描述中的某些值,該字段一直為0 。
Payload Length
表示該條記錄的payload字段長度。如果上面的SR字段設置為1,則該字段占用1個字節的長度,但是如果SR設置為0,則該字段將有32個位,占用4個字節的長度。
ID Length
表示該條記錄的ID的長度。只有當上面的IL位置1時該字段才會被省略。
Record Type
表示記錄的類型,這個字段的值必須根據TNF位的設置確定。
Record ID
表示該條記錄的ID。當IL位為0時,該字段省略。
Payload
表示該條記錄的payload,該字段的長度務必與上面的Payload Length字段值一致。
關于 Well-Known Records 和 URI Records
首先要說的就是這兩個概念的區別,Well-Known Records(TNF Record Type 0x01) 是最常用也是最有用的NFC記錄類型,它是寫在上面說到的TNF字段的三個位里的,它描述的是當前這條NDEF記錄的整體類型,相當于一個總的架構決策。
而 URI Records(0x55/‘U’)是比較有用的數據類型,它是寫在上面 Recode Type 字段的一個字節(8個位)里的,它描述的是這條NDEF記錄攜帶的數據信息類型,簡單的說就是這條記錄攜帶了什么樣的信息。
這里,關于這個URI Records我要多說幾句,這個類型可以用來存儲例如電話號碼、網站地址以及各種協議的鏈接等等很多有用的信息,它的結構定義如下:
第一個字節表示該類型的識別碼,這個識別碼的主要是用于縮短URI的長度,它的有效值詳見下表:
后面的N個字節就是用來表示一個URI去掉前面識別碼之后剩余的部分,舉個例子:例如我們要將 https://www.mob.com 寫入,則在第一個字節里我們要寫入的是 0x02,表示 https://www.,接下來要連續寫入的就是 0x6D 0x6F 0x62 0x2E 0x63 0x6F 0x6D (詳細請參考:ASCII碼對照表http://ascii.911cha.com/)
以上所有內容就是關于NDEF數據格式的詳細說明了,那么這里也很不幸的告訴大家,我們平時直接從某寶、某東或者某某某上買來的NFC卡片(俗稱:白卡)都不會是NDEF格式的,所以。。。
將 Mifare Classic Cards 用作 NDEF 標簽
Mifare Classic 1K和4K的卡可以被初始化為NFC的NDEF格式標簽。關于Mifare的詳細介紹請各位老板參見:Mifare維基百科 Mifare Classic 可以配置為NFC論壇兼容的NDEF標簽,但必須以某種特定的方式組織它里面的數據才可以。具體要求可以參考如下資料:
AN1304 - NFC Type MIFARE Classic Tag Operation
https://www.nxp.com/docs/en/application-note/AN1304.pdf
上面的是使用手冊的權威來源,下面將快速的介紹一下將 Mifare Classic Cards 用作 NDEF 標簽所涉及的關鍵概念。
1. Mifare Application Directory (MAD)
Mifare應用程序的目錄,為了在Mifare Classic卡片的扇區內存與單個NDEF記錄之間建立關系而存在。MAD表明了哪個扇區包含著哪個NDEF記錄。關于Mifare應用程序目錄的權威信息來源如下:
AN10787 - MIFARE Application Directory (MAD)
https://www.nxp.com/docs/en/application-note/AN10787.pdf
為了兼容性考慮,官方根據卡片內存的大小定義了兩種不同類型的MAD,簡單說明一下區別,MAD1可以用在任何卡片上,而MAD2只能用在內存大于1K字節的卡片上。
2. 存儲 NDEF Messages
為了在Mifare Classic卡上存儲NDEF消息,消息需要被封裝在一個叫做 TLV 塊 的東西里面。關于 TLV 塊 的基本結構描述如下:
TLV 是三個不同維度的縮寫:T:Tag Field 標簽L:Length Field 長度V:Value Field 數值
一個 TLV 塊 由一個或多個字節組成,這取決于上面三個維度的存在情況,但至少有一個字節,因為 T 字段在每種情況下都是強制性的。
Tag Field
標簽字段是唯一必填的字段,使用單個字節來標識 TLV 塊 的類型,有效值如下:
Length Field
長度字段包含了數值字段的長度(字節),它可以使用一個或三個字節兩種不同的方式表示:一個字節格式就是簡單0x00~0xFF的一個字節數值;三個字節格式的組成如下:
Value Field
數值字段僅在長度字段存在且不等于0x00時才存在,這個字段就是 payload 的存儲位置。
Terminator TLV
終止符,是數據區域中的最后一個TLV 塊,固定的單個字節:0xFE,這個TLV 塊也是是強制性的。
3. 一個帶有NDEF記錄的Mifare Classic 卡片的內存示例
上圖示例中在扇區1包含了兩個NDEF記錄:
第一個記錄在扇區1塊4的前兩個字節:根據上面的描述,每個記錄都以TLV 塊開頭,并且TLV 塊的第一個字節(值0x00)指示這是一個空塊類型,第二個字節是長度字段,并且也是0x00,因此該記錄沒有payload,TLV 塊的值字段不存在。當Mifare Classic卡首次格式化以確保至少有一條記錄存在時,一般會插入此記錄。
第二個記錄從扇區1塊4的第3個字節開始,到塊5的第6個字節結束:
同樣,對于前兩個字節,根據TLV 塊的描述,第一個字節 0x03 表示這是一個NDEF Message類型,第二個字節 0x11 表示該塊的數據長度是17個字節。對于接下來17個字節的分析如下表:
Byte(s)
Value
Description
04:04
0xD1
NDEF記錄的記錄頭,詳細解釋參考上面的NDEF記錄描述部分。位分配如下:
TNF = 0x01 表示這是一個Well-Known類型的記錄
IL = 0 表示沒有ID字段
SR = 1 表示這是一個短記錄
CF = 0 表示這個塊不是第一塊
ME = 1 表示當前記錄為最后一條記錄
MB = 1 表示Message的開始
04:05
0x01
NDEF記錄類型的長度,1個字節,因為下面的記錄類型值是0x55
04:06
0x0D
表示payload的長度,13個字節
04:07
0x55
NDEF記錄的類型,0x55表示URI類型
04:08
0x01
表示payload開始,后面的將是payload中的內容
04:09..05:04
...
payload內容的16進制數據
最后一個字節,0xFE 是TLV 塊的終止符,表示這個塊的結束,這個沒什么好說的了~~
相關參考鏈接:
?NXP官方網站
https://www.nxp.com/
?NFC論壇
https://nfc-forum.org/
?Mifare Classic S50 技術詳解
http://www.cnblogs.com/SCPlatform/p/5116180.html
iOS CoreNFC
下面將通過一個簡單的示例來演示怎么使用蘋果爸爸推出的CoreNFC,該示例僅可以用來讀取存儲在卡片上的NDEF格式的信息。
為此,我使用了STM32F407單片機與Adafruit PN532 ShieldNFC讀寫模塊配對,將信息寫入NDEF格式的卡片上。本文中,我不會記錄如何將普通的Mifare Classic卡片格式化成NDEF格式的卡片以及如何將數據寫入到NDEF卡片中(iOS的CoreNFC暫時不支持寫入)。
我們的app要使用NFC必須要進行應用授權:首先要創建一個支持NFC的證書,并且開啟NFC Tag Reading,如下圖:
導入證書之后,我們需要進行Info.plist配置Privacy - NFC Scan Usage Description權限,如下圖:
要實現NFC功能,我們得先導入CoreNFC.framework,并導入其頭文件#import目前為止,iOS模擬器還不支持CoreNFC,只能使用真機調試。
與二維碼掃描等類似,NFC 也具備一個用于信息交互的Session,并且這個Session要在使用期間一直持有,所以初始化Session代碼如下:
@interface NFCTableViewController ()/** NFC Session */@property (nonatomic, strong) NFCNDEFReaderSession *nfcSession;/** founded NFC Messages */@property (nonatomic, strong) NSMutableArray *> *nfcMessages;@end@implementation NFCTableViewController#pragma mark - initializeNFC
- (void)initializeNFCSession { // 創建 Session
self.nfcSession = [[NFCNDEFReaderSession alloc] initWithDelegate:self queue:dispatch_get_main_queue() invalidateAfterFirstRead:NO]; // 設置 Session 的提示信息
self.nfcSession.alertMessage = @"You can scan NFC-tags by holding them behind the top of your iPhone.";
}@end
經過上面的初始化之后,有了Session就可以開啟監聽了,啟動監聽很簡單,示例代碼如下:
- (IBAction)startSearchBtnClick:(UIBarButtonItem *)sender { NSLog(@"%s", __func__); // 啟動Session
[self.nfcSession beginSession];
}
Session啟動時會自動調出系統的掃描面板,如下圖:
通過上面的方式把Session啟動之后,設備就會自動開始掃描NDEF格式的標簽信息,當掃描到標簽信息,或者發生任何異常時都會通過代理方法回調,所以我們需要監聽Session的回調信息,示例如下:
#pragma mark - NFCNDEFReaderSessionDelegate/*! * @method readerSession:didInvalidateWithError: * * @param session The session object that is invalidated. * @param error The error indicates the invalidation reason. * * @discussion Gets called when a session becomes invalid. At this point the client is expected to discard * the returned session object. *//** NFC 讀取的session發生錯誤或session過期時回調,此時客戶端應當丟棄返回的session,即此session不可重用。 @param session 發生錯誤的session @param error 錯誤信息 */- (void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error { if (error)
{ NSLog(@"NFC-Session invalidated: %@", error);
} if (self.nfcSession)
{ // 關閉當前session
[self.nfcSession invalidateSession];
self.nfcSession = nil;
} // 重新初始化一個新的session
[self initializeNFCSession];
}/*! * @method readerSession:didDetectNDEFs: * * @param session The session object used for tag detection. * @param messages Array of @link NFCNDEFMessage @link/ objects. The order of the discovery on the tag is maintained. * * @discussion Gets called when the reader detects NFC tag(s) with NDEF messages in the polling sequence. Polling * is automatically restarted once the detected tag is removed from the readers read range. *//** 當NFC Session在輪詢隊列中讀取到NDEF信息時回調,此時輪詢會自動重啟一次再次檢測NFC標簽是否離開了讀取范圍。(原理類似于機械按鍵的防抖動) @param session 讀取Session @param messages 讀取到的信息 */- (void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray *)messages { NSLog(@"New NFC Messages %zd detected:", messages.count); for (NFCNDEFMessage *message in messages) { NSLog(@"- %zd Records:", message.records.count); for (NFCNDEFPayload *record in message.records) { NSLog(@" - TNF(TypeNameFormat): %@", [self formattedTypeNameFormat:record.typeNameFormat]); NSLog(@" - Payload: %@", [[NSString alloc] initWithData:record.payload encoding:NSUTF8StringEncoding]); NSLog(@" - Type: %@", [[NSString alloc] initWithData:record.type encoding:NSUTF8StringEncoding]); NSLog(@" - Identifier: %@", [[NSString alloc] initWithData:record.identifier encoding:NSUTF8StringEncoding]);
}
}
[self.nfcMessages addObject:messages];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7075.html
摘要:基礎知識工會名稱項目第個工作組局域網標準無線局域網層,物理層技術規范開放互聯參考模型的七層架構應用,表示,會話,傳輸,網絡,數據鏈路,物理數據鏈路層邏輯鏈路控制子層媒介訪問控制子層只涉及層媒介不同的媒介無線有線沖突檢測邊發送邊監聽沖突避免 WiFi篇 一。Netd 是守護進程;Netd是Android系統中專門負責網絡管理和控制的后臺daemon程序;位于Framework層和Kern...
閱讀 713·2023-04-25 19:43
閱讀 3910·2021-11-30 14:52
閱讀 3785·2021-11-30 14:52
閱讀 3852·2021-11-29 11:00
閱讀 3783·2021-11-29 11:00
閱讀 3869·2021-11-29 11:00
閱讀 3558·2021-11-29 11:00
閱讀 6105·2021-11-29 11:00