nfcscript 0.0.17__tar.gz → 0.0.19__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.17 → nfcscript-0.0.19}/PKG-INFO +1 -1
- {nfcscript-0.0.17 → nfcscript-0.0.19}/pyproject.toml +2 -2
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/reader.py +31 -3
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfcscript.egg-info/PKG-INFO +1 -1
- {nfcscript-0.0.17 → nfcscript-0.0.19}/tests/test_reader.py +35 -3
- {nfcscript-0.0.17 → nfcscript-0.0.19}/README.md +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/setup.cfg +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/__init__.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/assertions.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/bits.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/checksum.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/cli.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/delay.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/hex_util.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/nfc_cli.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfc/trace.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfcscript.egg-info/SOURCES.txt +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfcscript.egg-info/dependency_links.txt +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfcscript.egg-info/entry_points.txt +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfcscript.egg-info/requires.txt +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/src/nfcscript.egg-info/top_level.txt +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/tests/test_assertions.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/tests/test_bits.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/tests/test_checksum.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/tests/test_cli.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/tests/test_cli_collect.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/tests/test_delay.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/tests/test_hex_util.py +0 -0
- {nfcscript-0.0.17 → nfcscript-0.0.19}/tests/test_trace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nfcscript"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.19"
|
|
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"
|
|
@@ -31,7 +31,7 @@ dev = [
|
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
[tool.bumpversion]
|
|
34
|
-
current_version = "0.0.
|
|
34
|
+
current_version = "0.0.19"
|
|
35
35
|
commit = true
|
|
36
36
|
tag = true
|
|
37
37
|
allow_dirty = true
|
|
@@ -83,6 +83,26 @@ class _ReaderFacade:
|
|
|
83
83
|
"""获取 Mifare 硬件加密状态。"""
|
|
84
84
|
return getattr(get_reader(), "mf_crypto", False)
|
|
85
85
|
|
|
86
|
+
@property
|
|
87
|
+
def name(self) -> str:
|
|
88
|
+
"""读卡器驱动名称 (如 'pn532', 'clrc663')。"""
|
|
89
|
+
return getattr(get_reader(), "name", "")
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def fifo_size(self) -> int:
|
|
93
|
+
"""读卡器内部物理硬件 FIFO 深度 (字节)。"""
|
|
94
|
+
return getattr(get_reader(), "fifo_size", 64)
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def lazy_crc(self) -> bool:
|
|
98
|
+
"""是否启用惰性 CRC 状态缓存。"""
|
|
99
|
+
return getattr(get_reader(), "lazy_crc", True)
|
|
100
|
+
|
|
101
|
+
@lazy_crc.setter
|
|
102
|
+
def lazy_crc(self, value: bool) -> None:
|
|
103
|
+
"""设置是否启用惰性 CRC 状态缓存。"""
|
|
104
|
+
get_reader().lazy_crc = value
|
|
105
|
+
|
|
86
106
|
@property
|
|
87
107
|
def target(self) -> Any:
|
|
88
108
|
"""获取当前连接的底层 CardReader 实例。"""
|
|
@@ -254,7 +274,12 @@ def active(low_layer: bool = False, ignore_error: bool = False, reqa_cmd: int =
|
|
|
254
274
|
return info
|
|
255
275
|
|
|
256
276
|
|
|
257
|
-
def transceive(
|
|
277
|
+
def transceive(
|
|
278
|
+
data: list[int] | bytes,
|
|
279
|
+
tx_crc: bool = True,
|
|
280
|
+
rx_crc: bool = True,
|
|
281
|
+
timeout: float = 0.5,
|
|
282
|
+
) -> list[int]:
|
|
258
283
|
"""
|
|
259
284
|
使用底层帧交互方式发送数据。
|
|
260
285
|
|
|
@@ -262,13 +287,14 @@ def transceive(data: list[int] | bytes, tx_crc: bool = True, rx_crc: bool = True
|
|
|
262
287
|
data: 要发送的字节列表或 bytes。
|
|
263
288
|
tx_crc: 发送时是否自动添加 CRC。False 则原样发送。
|
|
264
289
|
rx_crc: 接收时是否自动校验 CRC。False 则原样接收不校验。
|
|
290
|
+
timeout: 接收超时时间 (秒),默认 0.5s。
|
|
265
291
|
|
|
266
292
|
Returns:
|
|
267
293
|
list[int]: 接收到的数据字节列表。
|
|
268
294
|
"""
|
|
269
295
|
rdr = get_reader()
|
|
270
296
|
raw_list = list(data) if isinstance(data, (bytes, bytearray)) else data
|
|
271
|
-
res = rdr.transceive(raw_list, tx_crc=tx_crc, rx_crc=rx_crc)
|
|
297
|
+
res = rdr.transceive(raw_list, tx_crc=tx_crc, rx_crc=rx_crc, timeout=timeout)
|
|
272
298
|
return res.data if res and res.data else []
|
|
273
299
|
|
|
274
300
|
|
|
@@ -277,6 +303,7 @@ def transceive_bits(
|
|
|
277
303
|
last_tx_bits: int = 0,
|
|
278
304
|
tx_crc: bool = True,
|
|
279
305
|
rx_crc: bool = True,
|
|
306
|
+
timeout: float = 0.5,
|
|
280
307
|
) -> TransceiveBits:
|
|
281
308
|
"""
|
|
282
309
|
使用底层帧交互方式发送数据,并支持对最后一个字节进行位控制。
|
|
@@ -286,13 +313,14 @@ def transceive_bits(
|
|
|
286
313
|
last_tx_bits: 最后一个字节实际发送的有效位数 (1-7),0 表示发送完整字节。
|
|
287
314
|
tx_crc: 发送时是否自动添加 CRC。False 则原样发送。
|
|
288
315
|
rx_crc: 接收时是否自动校验 CRC。False 则原样接收不校验。
|
|
316
|
+
timeout: 接收超时时间 (秒),默认 0.5s。
|
|
289
317
|
|
|
290
318
|
Returns:
|
|
291
319
|
TransceiveBits: 包含 data 和 bits 属性,失败返回空的 TransceiveBits(data=[], bits=0)。
|
|
292
320
|
"""
|
|
293
321
|
rdr = get_reader()
|
|
294
322
|
raw_list = list(data) if isinstance(data, (bytes, bytearray)) else data
|
|
295
|
-
res = rdr.transceive(raw_list, last_tx_bits=last_tx_bits, tx_crc=tx_crc, rx_crc=rx_crc)
|
|
323
|
+
res = rdr.transceive(raw_list, last_tx_bits=last_tx_bits, tx_crc=tx_crc, rx_crc=rx_crc, timeout=timeout)
|
|
296
324
|
return res if res else TransceiveBits(data=[], bits=0)
|
|
297
325
|
|
|
298
326
|
|
|
@@ -25,6 +25,9 @@ def _mock_reader():
|
|
|
25
25
|
mock.active.return_value = CardInfo(uid=[0x01, 0x02, 0x03, 0x04], atq=[0x44, 0x00], sak=0x00)
|
|
26
26
|
mock.rf_field = False
|
|
27
27
|
mock.mf_crypto = False
|
|
28
|
+
mock.name = "pn532"
|
|
29
|
+
mock.fifo_size = 64
|
|
30
|
+
mock.lazy_crc = True
|
|
28
31
|
return mock
|
|
29
32
|
|
|
30
33
|
|
|
@@ -84,6 +87,28 @@ class TestGetReader:
|
|
|
84
87
|
nfc.get_reader()
|
|
85
88
|
|
|
86
89
|
|
|
90
|
+
class TestReaderFacadeCapabilities:
|
|
91
|
+
def test_reader_properties(self):
|
|
92
|
+
mock = _mock_reader()
|
|
93
|
+
mock.name = "clrc663"
|
|
94
|
+
mock.fifo_size = 512
|
|
95
|
+
mock.lazy_crc = True
|
|
96
|
+
reader._target = mock
|
|
97
|
+
reader._connected = True
|
|
98
|
+
|
|
99
|
+
assert reader.name == "clrc663"
|
|
100
|
+
assert reader.fifo_size == 512
|
|
101
|
+
assert reader.lazy_crc is True
|
|
102
|
+
|
|
103
|
+
def test_reader_lazy_crc_setter(self):
|
|
104
|
+
mock = _mock_reader()
|
|
105
|
+
reader._target = mock
|
|
106
|
+
reader._connected = True
|
|
107
|
+
|
|
108
|
+
reader.lazy_crc = False
|
|
109
|
+
assert mock.lazy_crc is False
|
|
110
|
+
|
|
111
|
+
|
|
87
112
|
class TestTransceive:
|
|
88
113
|
|
|
89
114
|
def test_transceive_returns_data(self):
|
|
@@ -92,14 +117,21 @@ class TestTransceive:
|
|
|
92
117
|
reader._connected = True
|
|
93
118
|
result = nfc.transceive([0x30, 0x00])
|
|
94
119
|
assert result == [0xAA, 0xBB]
|
|
95
|
-
mock.transceive.assert_called_once_with([0x30, 0x00], tx_crc=True, rx_crc=True)
|
|
120
|
+
mock.transceive.assert_called_once_with([0x30, 0x00], tx_crc=True, rx_crc=True, timeout=0.5)
|
|
96
121
|
|
|
97
122
|
def test_transceive_no_crc(self):
|
|
98
123
|
mock = _mock_reader()
|
|
99
124
|
reader._target = mock
|
|
100
125
|
reader._connected = True
|
|
101
126
|
nfc.transceive([0x30], tx_crc=False, rx_crc=False)
|
|
102
|
-
mock.transceive.assert_called_once_with([0x30], tx_crc=False, rx_crc=False)
|
|
127
|
+
mock.transceive.assert_called_once_with([0x30], tx_crc=False, rx_crc=False, timeout=0.5)
|
|
128
|
+
|
|
129
|
+
def test_transceive_with_timeout(self):
|
|
130
|
+
mock = _mock_reader()
|
|
131
|
+
reader._target = mock
|
|
132
|
+
reader._connected = True
|
|
133
|
+
nfc.transceive([0x30], timeout=1.2)
|
|
134
|
+
mock.transceive.assert_called_once_with([0x30], tx_crc=True, rx_crc=True, timeout=1.2)
|
|
103
135
|
|
|
104
136
|
def test_transceive_empty_result(self):
|
|
105
137
|
mock = _mock_reader()
|
|
@@ -131,7 +163,7 @@ class TestTransceiveBits:
|
|
|
131
163
|
reader._target = mock
|
|
132
164
|
reader._connected = True
|
|
133
165
|
nfc.transceive_bits([0x26], last_tx_bits=7, tx_crc=False, rx_crc=False)
|
|
134
|
-
mock.transceive.assert_called_once_with([0x26], last_tx_bits=7, tx_crc=False, rx_crc=False)
|
|
166
|
+
mock.transceive.assert_called_once_with([0x26], last_tx_bits=7, tx_crc=False, rx_crc=False, timeout=0.5)
|
|
135
167
|
|
|
136
168
|
|
|
137
169
|
class TestReqa:
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|