Linux NFC 子系統¶
近場通訊 (NFC) 子系統旨在標準化 NFC 裝置驅動程式的開發,並建立統一的使用者空間介面。
本文件涵蓋了架構概述、裝置驅動程式介面描述和使用者空間介面描述。
架構概述¶
- NFC 子系統負責:
NFC 介面卡管理;
輪詢目標;
底層資料交換;
該子系統分為幾個部分。“核心”負責提供裝置驅動程式介面。 另一方面,它還負責提供控制操作和底層資料交換的介面。
控制操作可透過通用 netlink 提供給使用者空間。
底層資料交換介面由新的套接字族 PF_NFC 提供。 NFC_SOCKPROTO_RAW 執行與 NFC 目標的原始通訊。
+--------------------------------------+
| USER SPACE |
+--------------------------------------+
^ ^
| low-level | control
| data exchange | operations
| |
| v
| +-----------+
| AF_NFC | netlink |
| socket +-----------+
| raw ^
| |
v v
+---------+ +-----------+
| rawsock | <--------> | core |
+---------+ +-----------+
^
|
v
+-----------+
| driver |
+-----------+
裝置驅動程式介面¶
在 NFC 子系統上註冊時,裝置驅動程式必須通知核心支援的 NFC 協議集和 ops 回撥集。 必須實現的 ops 回撥如下:
start_poll - 設定裝置以輪詢目標
stop_poll - 停止正在進行的輪詢操作
activate_target - 選擇並初始化找到的目標之一
deactivate_target - 取消選擇並取消初始化所選目標
data_exchange - 傳送資料並接收響應(收發操作)
使用者空間介面¶
使用者空間介面分為控制操作和底層資料交換操作。
控制操作
通用 netlink 用於實現控制操作的介面。 這些操作由命令和事件組成,全部列在下面
NFC_CMD_GET_DEVICE - 獲取特定裝置資訊或轉儲裝置列表
NFC_CMD_START_POLL - 設定特定裝置以輪詢目標
NFC_CMD_STOP_POLL - 停止特定裝置中的輪詢操作
NFC_CMD_GET_TARGET - 轉儲特定裝置找到的目標列表
NFC_EVENT_DEVICE_ADDED - 報告 NFC 裝置的新增
NFC_EVENT_DEVICE_REMOVED - 報告 NFC 裝置的移除
NFC_EVENT_TARGETS_FOUND - 當找到 1 個或多個目標時,報告 START_POLL 結果
使用者必須呼叫 START_POLL 來輪詢 NFC 目標,並透過 NFC_ATTR_PROTOCOLS 屬性傳遞所需的 NFC 協議。 裝置保持輪詢狀態,直到找到任何目標。 但是,使用者可以透過呼叫 STOP_POLL 命令來停止輪詢操作。 在這種情況下,將檢查 STOP_POLL 的請求者是否與 START_POLL 的請求者相同。
如果輪詢操作找到一個或多個目標,則會發送 TARGETS_FOUND 事件(包括裝置 ID)。 使用者必須呼叫 GET_TARGET 以獲取此類裝置找到的所有目標的列表。 每個回覆訊息都有目標屬性,其中包含相關資訊,例如支援的 NFC 協議。
透過一個 netlink 套接字請求的所有輪詢操作在該套接字關閉時停止。
底層資料交換
使用者空間必須使用 PF_NFC 套接字來執行與目標的任何資料通訊。 所有 NFC 套接字都使用 AF_NFC
struct sockaddr_nfc {
sa_family_t sa_family;
__u32 dev_idx;
__u32 target_idx;
__u32 nfc_protocol;
};
要與一個目標建立連線,使用者必須建立一個 NFC_SOCKPROTO_RAW 套接字,並使用正確填充的 sockaddr_nfc 結構呼叫“connect”系統呼叫。 所有資訊都來自 NFC_EVENT_TARGETS_FOUND netlink 事件。 由於一個目標可以支援多個 NFC 協議,因此使用者必須告知它想要使用哪個協議。
在內部,“connect”將導致對驅動程式進行 activate_target 呼叫。 關閉套接字時,目標將被停用。
透過套接字交換的資料格式取決於 NFC 協議。 例如,在與 MIFARE 標籤通訊時,交換的資料是 MIFARE 命令及其響應。
收到的第一個資料包是對傳送的第一個資料包的響應,依此類推。 為了允許有效的“空”響應,收到的每個資料都有 1 位元組的 NULL 標頭。