nfcscript 0.0.11__tar.gz → 0.0.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nfcscript-0.0.11 → nfcscript-0.0.13}/PKG-INFO +10 -7
- {nfcscript-0.0.11 → nfcscript-0.0.13}/README.md +9 -6
- {nfcscript-0.0.11 → nfcscript-0.0.13}/pyproject.toml +2 -2
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/cli.py +0 -7
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/reader.py +21 -16
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/trace.py +0 -10
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfcscript.egg-info/PKG-INFO +10 -7
- {nfcscript-0.0.11 → nfcscript-0.0.13}/tests/test_trace.py +0 -8
- {nfcscript-0.0.11 → nfcscript-0.0.13}/setup.cfg +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/__init__.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/assertions.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/bits.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/checksum.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/delay.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/hex_util.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfc/nfc_cli.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfcscript.egg-info/SOURCES.txt +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfcscript.egg-info/dependency_links.txt +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfcscript.egg-info/entry_points.txt +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfcscript.egg-info/requires.txt +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/src/nfcscript.egg-info/top_level.txt +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/tests/test_assertions.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/tests/test_bits.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/tests/test_checksum.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/tests/test_cli.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/tests/test_cli_collect.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/tests/test_delay.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/tests/test_hex_util.py +0 -0
- {nfcscript-0.0.11 → nfcscript-0.0.13}/tests/test_reader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nfcscript
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.13
|
|
4
4
|
Summary: A plugin-based core engine for DSL-style NFC testing automation.
|
|
5
5
|
Author: crthu
|
|
6
6
|
Requires-Python: >=3.14
|
|
@@ -123,14 +123,14 @@ connect()
|
|
|
123
123
|
trace.set_layer("DRIVER", True)
|
|
124
124
|
trace.set_layer("PROTOCOL", True)
|
|
125
125
|
|
|
126
|
-
#
|
|
126
|
+
# 寻卡(自动切换协议解析器)
|
|
127
127
|
card_info = active()
|
|
128
128
|
ASSERT_IS_NOT_NONE(card_info, "未扫描到卡片")
|
|
129
|
-
print(f"UID: {
|
|
129
|
+
print(f"UID: {' '.join(f'{b:02X}' for b in card_info.uid)}")
|
|
130
130
|
|
|
131
131
|
# 创建卡片实例
|
|
132
132
|
from nfctester.registry import CardRegistry
|
|
133
|
-
card = CardRegistry.create("
|
|
133
|
+
card = CardRegistry.create("mifare_classic", reader=get_reader())
|
|
134
134
|
|
|
135
135
|
# 关闭连接
|
|
136
136
|
close()
|
|
@@ -142,8 +142,8 @@ close()
|
|
|
142
142
|
from nfc import *
|
|
143
143
|
|
|
144
144
|
with session() as reader:
|
|
145
|
-
card_info = reader.
|
|
146
|
-
print(card_info)
|
|
145
|
+
card_info = reader.active()
|
|
146
|
+
print(card_info.uid)
|
|
147
147
|
# 自动断开连接
|
|
148
148
|
```
|
|
149
149
|
|
|
@@ -167,7 +167,7 @@ with session() as reader:
|
|
|
167
167
|
|------|------|
|
|
168
168
|
| `connect(port, reader_type)` | 连接读卡器 |
|
|
169
169
|
| `get_reader()` | 获取当前读卡器实例 |
|
|
170
|
-
| `active(low_layer, ignore_error, reqa_cmd)` | 寻卡,返回 uid/atq/sak |
|
|
170
|
+
| `active(low_layer, ignore_error, reqa_cmd)` | 寻卡,返回 CardInfo (uid/atq/sak),自动切换协议解析器 |
|
|
171
171
|
| `transceive(data, tx_crc, rx_crc)` | 底层帧交互 |
|
|
172
172
|
| `transceive_bits(data, last_tx_bits, tx_crc, rx_crc)` | 位控制帧交互 |
|
|
173
173
|
| `reqa()` | ISO14443-A REQA |
|
|
@@ -185,6 +185,9 @@ with session() as reader:
|
|
|
185
185
|
|------|------|
|
|
186
186
|
| `trace.set_layer(layer, enable)` | 开启/关闭追踪层 |
|
|
187
187
|
| `trace.set_level(level)` | 设置日志级别 |
|
|
188
|
+
| `trace.set_parse(level)` | 设置解析级别 (0=关闭, 1=hex+摘要) |
|
|
189
|
+
| `trace.add_sink(fn)` | 注册结构化 trace 事件回调 |
|
|
190
|
+
| `trace.remove_sink(fn)` | 移除已注册的回调 |
|
|
188
191
|
| `trace.info(msg)` / `trace.error(msg)` / `trace.warning(msg)` / `trace.success(msg)` / `trace.debug(msg)` | 输出日志 |
|
|
189
192
|
|
|
190
193
|
### assertions.py
|
|
@@ -113,14 +113,14 @@ connect()
|
|
|
113
113
|
trace.set_layer("DRIVER", True)
|
|
114
114
|
trace.set_layer("PROTOCOL", True)
|
|
115
115
|
|
|
116
|
-
#
|
|
116
|
+
# 寻卡(自动切换协议解析器)
|
|
117
117
|
card_info = active()
|
|
118
118
|
ASSERT_IS_NOT_NONE(card_info, "未扫描到卡片")
|
|
119
|
-
print(f"UID: {
|
|
119
|
+
print(f"UID: {' '.join(f'{b:02X}' for b in card_info.uid)}")
|
|
120
120
|
|
|
121
121
|
# 创建卡片实例
|
|
122
122
|
from nfctester.registry import CardRegistry
|
|
123
|
-
card = CardRegistry.create("
|
|
123
|
+
card = CardRegistry.create("mifare_classic", reader=get_reader())
|
|
124
124
|
|
|
125
125
|
# 关闭连接
|
|
126
126
|
close()
|
|
@@ -132,8 +132,8 @@ close()
|
|
|
132
132
|
from nfc import *
|
|
133
133
|
|
|
134
134
|
with session() as reader:
|
|
135
|
-
card_info = reader.
|
|
136
|
-
print(card_info)
|
|
135
|
+
card_info = reader.active()
|
|
136
|
+
print(card_info.uid)
|
|
137
137
|
# 自动断开连接
|
|
138
138
|
```
|
|
139
139
|
|
|
@@ -157,7 +157,7 @@ with session() as reader:
|
|
|
157
157
|
|------|------|
|
|
158
158
|
| `connect(port, reader_type)` | 连接读卡器 |
|
|
159
159
|
| `get_reader()` | 获取当前读卡器实例 |
|
|
160
|
-
| `active(low_layer, ignore_error, reqa_cmd)` | 寻卡,返回 uid/atq/sak |
|
|
160
|
+
| `active(low_layer, ignore_error, reqa_cmd)` | 寻卡,返回 CardInfo (uid/atq/sak),自动切换协议解析器 |
|
|
161
161
|
| `transceive(data, tx_crc, rx_crc)` | 底层帧交互 |
|
|
162
162
|
| `transceive_bits(data, last_tx_bits, tx_crc, rx_crc)` | 位控制帧交互 |
|
|
163
163
|
| `reqa()` | ISO14443-A REQA |
|
|
@@ -175,6 +175,9 @@ with session() as reader:
|
|
|
175
175
|
|------|------|
|
|
176
176
|
| `trace.set_layer(layer, enable)` | 开启/关闭追踪层 |
|
|
177
177
|
| `trace.set_level(level)` | 设置日志级别 |
|
|
178
|
+
| `trace.set_parse(level)` | 设置解析级别 (0=关闭, 1=hex+摘要) |
|
|
179
|
+
| `trace.add_sink(fn)` | 注册结构化 trace 事件回调 |
|
|
180
|
+
| `trace.remove_sink(fn)` | 移除已注册的回调 |
|
|
178
181
|
| `trace.info(msg)` / `trace.error(msg)` / `trace.warning(msg)` / `trace.success(msg)` / `trace.debug(msg)` | 输出日志 |
|
|
179
182
|
|
|
180
183
|
### assertions.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nfcscript"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.13"
|
|
4
4
|
description = "A plugin-based core engine for DSL-style NFC testing automation."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.14"
|
|
@@ -34,7 +34,7 @@ dev = [
|
|
|
34
34
|
]
|
|
35
35
|
|
|
36
36
|
[tool.bumpversion]
|
|
37
|
-
current_version = "0.0.
|
|
37
|
+
current_version = "0.0.13"
|
|
38
38
|
commit = true
|
|
39
39
|
tag = true
|
|
40
40
|
allow_dirty = true
|
|
@@ -59,8 +59,6 @@ def main():
|
|
|
59
59
|
parser.add_argument("--trace-protocol", action="store_true", help="开启 PROTOCOL 层追踪")
|
|
60
60
|
parser.add_argument("--trace-parse", type=int, default=None, choices=[0, 1, 2],
|
|
61
61
|
help="解析级别: 0=关闭 1=简单 2=复杂 (默认: NFC_TRACE_PARSE 或 1)")
|
|
62
|
-
parser.add_argument("--trace-card-type", default=None,
|
|
63
|
-
help="卡片类型标识 (默认: NFC_TRACE_CARD_TYPE)")
|
|
64
62
|
parser.add_argument("--trace-level", default="INFO", help="日志级别 (默认: INFO)")
|
|
65
63
|
|
|
66
64
|
args, extra = parser.parse_known_args()
|
|
@@ -87,7 +85,6 @@ def main():
|
|
|
87
85
|
trace_driver = os.environ.get("NFC_TRACE_DRIVER", "").lower() in ("1", "true", "yes")
|
|
88
86
|
trace_protocol = os.environ.get("NFC_TRACE_PROTOCOL", "").lower() in ("1", "true", "yes")
|
|
89
87
|
trace_parse = os.environ.get("NFC_TRACE_PARSE", "1")
|
|
90
|
-
trace_card_type = os.environ.get("NFC_TRACE_CARD_TYPE")
|
|
91
88
|
trace_width = os.environ.get("NFC_TRACE_WIDTH")
|
|
92
89
|
|
|
93
90
|
if args.trace_level != "INFO":
|
|
@@ -98,15 +95,11 @@ def main():
|
|
|
98
95
|
trace_protocol = True
|
|
99
96
|
if args.trace_parse is not None:
|
|
100
97
|
trace_parse = str(args.trace_parse)
|
|
101
|
-
if args.trace_card_type is not None:
|
|
102
|
-
trace_card_type = args.trace_card_type
|
|
103
98
|
|
|
104
99
|
trace.set_level(trace_level)
|
|
105
100
|
trace.set_layer("DRIVER", trace_driver)
|
|
106
101
|
trace.set_layer("PROTOCOL", trace_protocol)
|
|
107
102
|
trace.set_parse(_parse_level(trace_parse))
|
|
108
|
-
if trace_card_type is not None:
|
|
109
|
-
trace.set_card_type(trace_card_type)
|
|
110
103
|
if trace_width is not None:
|
|
111
104
|
os.environ["CRFT_TRACE_WIDTH"] = trace_width
|
|
112
105
|
|
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
from contextlib import contextmanager
|
|
3
3
|
from nfctester.drivers.card_reader import CardInfo, TransceiveBits
|
|
4
4
|
from nfctester.registry import CardReaderRegistry
|
|
5
|
+
from nfctester.trace import trace as _trace
|
|
5
6
|
from .assertions import ASSERT_EQUAL, ASSERT_IS_NOT_NONE, ASSERT_LEN
|
|
6
7
|
from .checksum import GET_BCC
|
|
7
8
|
from .hex_util import FORMAT_HEX
|
|
@@ -102,7 +103,7 @@ def active(low_layer: bool = False, ignore_error: bool = False, reqa_cmd: int =
|
|
|
102
103
|
# 手动底层寻卡流程
|
|
103
104
|
# 1. REQA
|
|
104
105
|
res_reqa = reqa(cmd=reqa_cmd)
|
|
105
|
-
if not res_reqa:
|
|
106
|
+
if not res_reqa.data:
|
|
106
107
|
return None
|
|
107
108
|
atq = res_reqa.data
|
|
108
109
|
|
|
@@ -110,7 +111,7 @@ def active(low_layer: bool = False, ignore_error: bool = False, reqa_cmd: int =
|
|
|
110
111
|
full_uid = []
|
|
111
112
|
for cl in [1, 2, 3]:
|
|
112
113
|
res = anticoll(cl_level=cl, nvb=0x20)
|
|
113
|
-
if not res
|
|
114
|
+
if not res.data:
|
|
114
115
|
return None
|
|
115
116
|
|
|
116
117
|
data = res.data
|
|
@@ -146,7 +147,10 @@ def active(low_layer: bool = False, ignore_error: bool = False, reqa_cmd: int =
|
|
|
146
147
|
sak = sak_res[0] if sak_res else 0
|
|
147
148
|
break
|
|
148
149
|
|
|
149
|
-
|
|
150
|
+
info = CardInfo(uid=full_uid, atq=atq, sak=sak)
|
|
151
|
+
atqa = int.from_bytes(atq, "little")
|
|
152
|
+
_trace.set_parser(atqa, sak)
|
|
153
|
+
return info
|
|
150
154
|
|
|
151
155
|
|
|
152
156
|
def transceive(data: list[int], tx_crc: bool = True, rx_crc: bool = True) -> list[int]:
|
|
@@ -167,7 +171,7 @@ def transceive(data: list[int], tx_crc: bool = True, rx_crc: bool = True) -> lis
|
|
|
167
171
|
return res.data if res and res.data else []
|
|
168
172
|
|
|
169
173
|
|
|
170
|
-
def transceive_bits(data: list[int], last_tx_bits: int = 0, tx_crc: bool = True, rx_crc: bool = True) -> TransceiveBits
|
|
174
|
+
def transceive_bits(data: list[int], last_tx_bits: int = 0, tx_crc: bool = True, rx_crc: bool = True) -> TransceiveBits:
|
|
171
175
|
"""
|
|
172
176
|
使用底层帧交互方式发送数据,并支持对最后一个字节进行位控制。
|
|
173
177
|
|
|
@@ -178,14 +182,15 @@ def transceive_bits(data: list[int], last_tx_bits: int = 0, tx_crc: bool = True,
|
|
|
178
182
|
rx_crc: 接收时是否自动校验 CRC。False 则原样接收不校验。
|
|
179
183
|
|
|
180
184
|
Returns:
|
|
181
|
-
TransceiveBits
|
|
185
|
+
TransceiveBits: 包含 data 和 bits 属性,失败返回空的 TransceiveBits(data=[], bits=0)。
|
|
182
186
|
"""
|
|
183
187
|
_state.ensure_connected()
|
|
184
188
|
reader = _state.reader
|
|
185
|
-
|
|
189
|
+
res = reader.transceive(data, last_tx_bits=last_tx_bits, tx_crc=tx_crc, rx_crc=rx_crc)
|
|
190
|
+
return res if res else TransceiveBits(data=[], bits=0)
|
|
186
191
|
|
|
187
192
|
|
|
188
|
-
def reqa(cmd: int = 0x26) -> TransceiveBits
|
|
193
|
+
def reqa(cmd: int = 0x26) -> TransceiveBits:
|
|
189
194
|
"""
|
|
190
195
|
ISO14443-A REQA (7 bits)。
|
|
191
196
|
|
|
@@ -193,27 +198,27 @@ def reqa(cmd: int = 0x26) -> TransceiveBits | None:
|
|
|
193
198
|
cmd: REQA 命令字节,默认 0x26。
|
|
194
199
|
|
|
195
200
|
Returns:
|
|
196
|
-
TransceiveBits
|
|
201
|
+
TransceiveBits: 包含 data 和 bits 属性,失败返回空的 TransceiveBits(data=[], bits=0)。
|
|
197
202
|
"""
|
|
198
203
|
return transceive_bits([cmd], last_tx_bits=7, tx_crc=False, rx_crc=False)
|
|
199
204
|
|
|
200
205
|
|
|
201
|
-
def wupa() -> TransceiveBits
|
|
206
|
+
def wupa() -> TransceiveBits:
|
|
202
207
|
"""
|
|
203
208
|
ISO14443-A WUPA (7 bits)。
|
|
204
209
|
|
|
205
210
|
Returns:
|
|
206
|
-
TransceiveBits
|
|
211
|
+
TransceiveBits: 包含 data 和 bits 属性,失败返回空的 TransceiveBits(data=[], bits=0)。
|
|
207
212
|
"""
|
|
208
213
|
return transceive_bits([0x52], last_tx_bits=7, tx_crc=False, rx_crc=False)
|
|
209
214
|
|
|
210
215
|
|
|
211
|
-
def halt() -> list[int]
|
|
216
|
+
def halt() -> list[int]:
|
|
212
217
|
"""
|
|
213
218
|
ISO14443-A HALT (Standard Frame)。
|
|
214
219
|
|
|
215
220
|
Returns:
|
|
216
|
-
list[int]
|
|
221
|
+
list[int]: 返回响应数据。
|
|
217
222
|
"""
|
|
218
223
|
return transceive([0x50, 0x00], tx_crc=True, rx_crc=True)
|
|
219
224
|
|
|
@@ -237,7 +242,7 @@ def _get_sel_cmd(cl_level: int) -> int:
|
|
|
237
242
|
return sel_map[cl_level]
|
|
238
243
|
|
|
239
244
|
|
|
240
|
-
def anticoll(cl_level: int, nvb: int = 0x20, uid_prefix: list[int] = []) -> TransceiveBits
|
|
245
|
+
def anticoll(cl_level: int, nvb: int = 0x20, uid_prefix: list[int] = []) -> TransceiveBits:
|
|
241
246
|
"""
|
|
242
247
|
ISO14443-A ANTICOLL (Anti-collision)。
|
|
243
248
|
|
|
@@ -247,13 +252,13 @@ def anticoll(cl_level: int, nvb: int = 0x20, uid_prefix: list[int] = []) -> Tran
|
|
|
247
252
|
uid_prefix: 已知的部分 UID (0-4 字节)。
|
|
248
253
|
|
|
249
254
|
Returns:
|
|
250
|
-
TransceiveBits
|
|
255
|
+
TransceiveBits: 包含 data 和 bits 属性,失败返回空的 TransceiveBits(data=[], bits=0)。
|
|
251
256
|
"""
|
|
252
257
|
cmd = [_get_sel_cmd(cl_level), nvb] + uid_prefix
|
|
253
258
|
return transceive_bits(cmd, last_tx_bits=0, tx_crc=False, rx_crc=False)
|
|
254
259
|
|
|
255
260
|
|
|
256
|
-
def select(cl_level: int, uid: list[int]) -> list[int]
|
|
261
|
+
def select(cl_level: int, uid: list[int]) -> list[int]:
|
|
257
262
|
"""
|
|
258
263
|
ISO14443-A SELECT (Standard Frame)。
|
|
259
264
|
|
|
@@ -262,7 +267,7 @@ def select(cl_level: int, uid: list[int]) -> list[int] | None:
|
|
|
262
267
|
uid: 完整 5 字节 UID (包含 BCC)。
|
|
263
268
|
|
|
264
269
|
Returns:
|
|
265
|
-
list[int]
|
|
270
|
+
list[int]: 返回响应数据。
|
|
266
271
|
"""
|
|
267
272
|
cmd = [_get_sel_cmd(cl_level), 0x70] + uid
|
|
268
273
|
return transceive(cmd, tx_crc=True, rx_crc=True)
|
|
@@ -39,16 +39,6 @@ def set_parse(level: int = 1):
|
|
|
39
39
|
_trace.set_parse(level)
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def set_card_type(card_type: str):
|
|
43
|
-
"""
|
|
44
|
-
设置当前卡片类型,注入到所有协议解析器的 state 中。
|
|
45
|
-
|
|
46
|
-
Args:
|
|
47
|
-
card_type: 卡片类型标识,如 "mifare_classic_1k", "ntag213"
|
|
48
|
-
"""
|
|
49
|
-
_trace.set_card_type(card_type)
|
|
50
|
-
|
|
51
|
-
|
|
52
42
|
def info(msg: str):
|
|
53
43
|
"""输出 INFO 级别日志"""
|
|
54
44
|
_trace.info(msg)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nfcscript
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.13
|
|
4
4
|
Summary: A plugin-based core engine for DSL-style NFC testing automation.
|
|
5
5
|
Author: crthu
|
|
6
6
|
Requires-Python: >=3.14
|
|
@@ -123,14 +123,14 @@ connect()
|
|
|
123
123
|
trace.set_layer("DRIVER", True)
|
|
124
124
|
trace.set_layer("PROTOCOL", True)
|
|
125
125
|
|
|
126
|
-
#
|
|
126
|
+
# 寻卡(自动切换协议解析器)
|
|
127
127
|
card_info = active()
|
|
128
128
|
ASSERT_IS_NOT_NONE(card_info, "未扫描到卡片")
|
|
129
|
-
print(f"UID: {
|
|
129
|
+
print(f"UID: {' '.join(f'{b:02X}' for b in card_info.uid)}")
|
|
130
130
|
|
|
131
131
|
# 创建卡片实例
|
|
132
132
|
from nfctester.registry import CardRegistry
|
|
133
|
-
card = CardRegistry.create("
|
|
133
|
+
card = CardRegistry.create("mifare_classic", reader=get_reader())
|
|
134
134
|
|
|
135
135
|
# 关闭连接
|
|
136
136
|
close()
|
|
@@ -142,8 +142,8 @@ close()
|
|
|
142
142
|
from nfc import *
|
|
143
143
|
|
|
144
144
|
with session() as reader:
|
|
145
|
-
card_info = reader.
|
|
146
|
-
print(card_info)
|
|
145
|
+
card_info = reader.active()
|
|
146
|
+
print(card_info.uid)
|
|
147
147
|
# 自动断开连接
|
|
148
148
|
```
|
|
149
149
|
|
|
@@ -167,7 +167,7 @@ with session() as reader:
|
|
|
167
167
|
|------|------|
|
|
168
168
|
| `connect(port, reader_type)` | 连接读卡器 |
|
|
169
169
|
| `get_reader()` | 获取当前读卡器实例 |
|
|
170
|
-
| `active(low_layer, ignore_error, reqa_cmd)` | 寻卡,返回 uid/atq/sak |
|
|
170
|
+
| `active(low_layer, ignore_error, reqa_cmd)` | 寻卡,返回 CardInfo (uid/atq/sak),自动切换协议解析器 |
|
|
171
171
|
| `transceive(data, tx_crc, rx_crc)` | 底层帧交互 |
|
|
172
172
|
| `transceive_bits(data, last_tx_bits, tx_crc, rx_crc)` | 位控制帧交互 |
|
|
173
173
|
| `reqa()` | ISO14443-A REQA |
|
|
@@ -185,6 +185,9 @@ with session() as reader:
|
|
|
185
185
|
|------|------|
|
|
186
186
|
| `trace.set_layer(layer, enable)` | 开启/关闭追踪层 |
|
|
187
187
|
| `trace.set_level(level)` | 设置日志级别 |
|
|
188
|
+
| `trace.set_parse(level)` | 设置解析级别 (0=关闭, 1=hex+摘要) |
|
|
189
|
+
| `trace.add_sink(fn)` | 注册结构化 trace 事件回调 |
|
|
190
|
+
| `trace.remove_sink(fn)` | 移除已注册的回调 |
|
|
188
191
|
| `trace.info(msg)` / `trace.error(msg)` / `trace.warning(msg)` / `trace.success(msg)` / `trace.debug(msg)` | 输出日志 |
|
|
189
192
|
|
|
190
193
|
### assertions.py
|
|
@@ -37,14 +37,6 @@ class TestSetParse:
|
|
|
37
37
|
mock_trace.set_parse.assert_called_once_with(2)
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
class TestSetCardType:
|
|
41
|
-
|
|
42
|
-
@patch("nfc.trace._trace")
|
|
43
|
-
def test_set_card_type(self, mock_trace):
|
|
44
|
-
trace.set_card_type("mifare_classic_1k")
|
|
45
|
-
mock_trace.set_card_type.assert_called_once_with("mifare_classic_1k")
|
|
46
|
-
|
|
47
|
-
|
|
48
40
|
class TestLogFunctions:
|
|
49
41
|
|
|
50
42
|
@patch("nfc.trace._trace")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|