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 標頭。