nfcscript 0.0.14__tar.gz → 0.0.16__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.14 → nfcscript-0.0.16}/PKG-INFO +40 -20
- {nfcscript-0.0.14 → nfcscript-0.0.16}/README.md +39 -19
- {nfcscript-0.0.14 → nfcscript-0.0.16}/pyproject.toml +2 -2
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/cli.py +19 -40
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/reader.py +5 -5
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/trace.py +35 -36
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfcscript.egg-info/PKG-INFO +40 -20
- {nfcscript-0.0.14 → nfcscript-0.0.16}/tests/test_cli.py +2 -42
- {nfcscript-0.0.14 → nfcscript-0.0.16}/tests/test_trace.py +10 -31
- {nfcscript-0.0.14 → nfcscript-0.0.16}/setup.cfg +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/__init__.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/assertions.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/bits.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/checksum.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/delay.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/hex_util.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfc/nfc_cli.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfcscript.egg-info/SOURCES.txt +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfcscript.egg-info/dependency_links.txt +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfcscript.egg-info/entry_points.txt +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfcscript.egg-info/requires.txt +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/src/nfcscript.egg-info/top_level.txt +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/tests/test_assertions.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/tests/test_bits.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/tests/test_checksum.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/tests/test_cli_collect.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/tests/test_delay.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/tests/test_hex_util.py +0 -0
- {nfcscript-0.0.14 → nfcscript-0.0.16}/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.16
|
|
4
4
|
Summary: A plugin-based core engine for DSL-style NFC testing automation.
|
|
5
5
|
Author: crthu
|
|
6
6
|
Requires-Python: >=3.14
|
|
@@ -36,13 +36,13 @@ nfcscript test_card.py -p COM21
|
|
|
36
36
|
nfcscript test_card.py -r acr122u
|
|
37
37
|
|
|
38
38
|
# 开启追踪层
|
|
39
|
-
nfcscript test_card.py --trace-
|
|
39
|
+
nfcscript test_card.py --trace-layer=protocol,debug
|
|
40
40
|
|
|
41
41
|
# 设置日志级别
|
|
42
|
-
nfcscript test_card.py --trace-level
|
|
42
|
+
nfcscript test_card.py --trace-level=driver
|
|
43
43
|
|
|
44
44
|
# 组合使用
|
|
45
|
-
nfcscript test_card.py -p COM21 -r pn532 --trace-
|
|
45
|
+
nfcscript test_card.py -p COM21 -r pn532 --trace-layer=protocol,debug --trace-level=driver
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
### nfc-cli - 交互式命令行
|
|
@@ -120,13 +120,13 @@ from nfc import *
|
|
|
120
120
|
connect()
|
|
121
121
|
|
|
122
122
|
# 开启追踪
|
|
123
|
-
trace.
|
|
124
|
-
trace.
|
|
123
|
+
trace.filter.driver = True
|
|
124
|
+
trace.filter.protocol = True
|
|
125
125
|
|
|
126
126
|
# 寻卡(自动切换协议解析器)
|
|
127
127
|
card_info = active()
|
|
128
128
|
ASSERT_IS_NOT_NONE(card_info, "未扫描到卡片")
|
|
129
|
-
|
|
129
|
+
trace.app(f"UID: {' '.join(f'{b:02X}' for b in card_info.uid)}")
|
|
130
130
|
|
|
131
131
|
# 创建卡片实例
|
|
132
132
|
from nfctester.registry import CardRegistry
|
|
@@ -143,7 +143,7 @@ from nfc import *
|
|
|
143
143
|
|
|
144
144
|
with session() as reader:
|
|
145
145
|
card_info = reader.active()
|
|
146
|
-
|
|
146
|
+
trace.app(f"UID: {card_info.uid}")
|
|
147
147
|
# 自动断开连接
|
|
148
148
|
```
|
|
149
149
|
|
|
@@ -181,14 +181,36 @@ with session() as reader:
|
|
|
181
181
|
|
|
182
182
|
### trace.py
|
|
183
183
|
|
|
184
|
+
**简洁写法(推荐):**
|
|
185
|
+
|
|
184
186
|
| 函数 | 说明 |
|
|
185
187
|
|------|------|
|
|
186
|
-
| `trace.
|
|
187
|
-
| `trace.
|
|
188
|
-
| `trace.
|
|
189
|
-
| `trace.
|
|
190
|
-
| `trace.
|
|
191
|
-
|
|
188
|
+
| `trace.app(msg)` | 输出到 app 层 (level=50) |
|
|
189
|
+
| `trace.debug(msg)` | 输出到 debug 层 (level=10) |
|
|
190
|
+
| `trace.warning(msg)` | 输出到 warning 层 (level=30) |
|
|
191
|
+
| `trace.error(msg)` | 输出到 error 层 (level=40) |
|
|
192
|
+
| `trace.log(msg, layer="app")` | 通用文本日志,指定层 |
|
|
193
|
+
|
|
194
|
+
**属性控制(推荐):**
|
|
195
|
+
|
|
196
|
+
| 属性 | 说明 |
|
|
197
|
+
|------|------|
|
|
198
|
+
| `trace.filter.driver = True` | 启用 driver 层 |
|
|
199
|
+
| `trace.filter.protocol = True` | 启用 protocol 层 |
|
|
200
|
+
| `trace.filter.debug = False` | 禁用 debug 层 |
|
|
201
|
+
| `trace.filter.level = "warning"` | 设置最低日志级别 |
|
|
202
|
+
| `trace.filter.level = 30` | 或用数字 |
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
# 简洁写法
|
|
206
|
+
trace.app("UID: AA BB CC DD")
|
|
207
|
+
trace.debug("[auth] Rt: 80 81")
|
|
208
|
+
|
|
209
|
+
# 属性控制
|
|
210
|
+
trace.filter.driver = True
|
|
211
|
+
trace.filter.protocol = True
|
|
212
|
+
trace.filter.level = "debug"
|
|
213
|
+
```
|
|
192
214
|
|
|
193
215
|
### assertions.py
|
|
194
216
|
|
|
@@ -235,9 +257,8 @@ with session() as reader:
|
|
|
235
257
|
|------|------|--------|
|
|
236
258
|
| `NFC_PORT` | 串口号 | - |
|
|
237
259
|
| `NFC_READER` | 读卡器类型 | - |
|
|
238
|
-
| `
|
|
239
|
-
| `
|
|
240
|
-
| `NFC_TRACE_PROTOCOL` | 开启 PROTOCOL 层追踪 | `false` |
|
|
260
|
+
| `NFC_TRACE_LAYER` | 启用的层 (逗号分隔) | - |
|
|
261
|
+
| `NFC_TRACE_LEVEL` | 最低日志级别 | `warning` |
|
|
241
262
|
| `NFC_CARD_PATH` | 外部卡片模块搜索路径 (分号分隔) | - |
|
|
242
263
|
|
|
243
264
|
支持多层 `.env` 加载:从脚本目录向上搜索所有 `.env` 文件,按从外到内的顺序依次加载(内层覆盖外层同名变量)。
|
|
@@ -252,9 +273,8 @@ with session() as reader:
|
|
|
252
273
|
```
|
|
253
274
|
NFC_PORT=COM20
|
|
254
275
|
NFC_READER=pn532
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
NFC_TRACE_PROTOCOL=true
|
|
276
|
+
NFC_TRACE_LAYER=protocol,warning,error,app
|
|
277
|
+
NFC_TRACE_LEVEL=protocol
|
|
258
278
|
```
|
|
259
279
|
|
|
260
280
|
## AI 编写脚本
|
|
@@ -26,13 +26,13 @@ nfcscript test_card.py -p COM21
|
|
|
26
26
|
nfcscript test_card.py -r acr122u
|
|
27
27
|
|
|
28
28
|
# 开启追踪层
|
|
29
|
-
nfcscript test_card.py --trace-
|
|
29
|
+
nfcscript test_card.py --trace-layer=protocol,debug
|
|
30
30
|
|
|
31
31
|
# 设置日志级别
|
|
32
|
-
nfcscript test_card.py --trace-level
|
|
32
|
+
nfcscript test_card.py --trace-level=driver
|
|
33
33
|
|
|
34
34
|
# 组合使用
|
|
35
|
-
nfcscript test_card.py -p COM21 -r pn532 --trace-
|
|
35
|
+
nfcscript test_card.py -p COM21 -r pn532 --trace-layer=protocol,debug --trace-level=driver
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
### nfc-cli - 交互式命令行
|
|
@@ -110,13 +110,13 @@ from nfc import *
|
|
|
110
110
|
connect()
|
|
111
111
|
|
|
112
112
|
# 开启追踪
|
|
113
|
-
trace.
|
|
114
|
-
trace.
|
|
113
|
+
trace.filter.driver = True
|
|
114
|
+
trace.filter.protocol = True
|
|
115
115
|
|
|
116
116
|
# 寻卡(自动切换协议解析器)
|
|
117
117
|
card_info = active()
|
|
118
118
|
ASSERT_IS_NOT_NONE(card_info, "未扫描到卡片")
|
|
119
|
-
|
|
119
|
+
trace.app(f"UID: {' '.join(f'{b:02X}' for b in card_info.uid)}")
|
|
120
120
|
|
|
121
121
|
# 创建卡片实例
|
|
122
122
|
from nfctester.registry import CardRegistry
|
|
@@ -133,7 +133,7 @@ from nfc import *
|
|
|
133
133
|
|
|
134
134
|
with session() as reader:
|
|
135
135
|
card_info = reader.active()
|
|
136
|
-
|
|
136
|
+
trace.app(f"UID: {card_info.uid}")
|
|
137
137
|
# 自动断开连接
|
|
138
138
|
```
|
|
139
139
|
|
|
@@ -171,14 +171,36 @@ with session() as reader:
|
|
|
171
171
|
|
|
172
172
|
### trace.py
|
|
173
173
|
|
|
174
|
+
**简洁写法(推荐):**
|
|
175
|
+
|
|
174
176
|
| 函数 | 说明 |
|
|
175
177
|
|------|------|
|
|
176
|
-
| `trace.
|
|
177
|
-
| `trace.
|
|
178
|
-
| `trace.
|
|
179
|
-
| `trace.
|
|
180
|
-
| `trace.
|
|
181
|
-
|
|
178
|
+
| `trace.app(msg)` | 输出到 app 层 (level=50) |
|
|
179
|
+
| `trace.debug(msg)` | 输出到 debug 层 (level=10) |
|
|
180
|
+
| `trace.warning(msg)` | 输出到 warning 层 (level=30) |
|
|
181
|
+
| `trace.error(msg)` | 输出到 error 层 (level=40) |
|
|
182
|
+
| `trace.log(msg, layer="app")` | 通用文本日志,指定层 |
|
|
183
|
+
|
|
184
|
+
**属性控制(推荐):**
|
|
185
|
+
|
|
186
|
+
| 属性 | 说明 |
|
|
187
|
+
|------|------|
|
|
188
|
+
| `trace.filter.driver = True` | 启用 driver 层 |
|
|
189
|
+
| `trace.filter.protocol = True` | 启用 protocol 层 |
|
|
190
|
+
| `trace.filter.debug = False` | 禁用 debug 层 |
|
|
191
|
+
| `trace.filter.level = "warning"` | 设置最低日志级别 |
|
|
192
|
+
| `trace.filter.level = 30` | 或用数字 |
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
# 简洁写法
|
|
196
|
+
trace.app("UID: AA BB CC DD")
|
|
197
|
+
trace.debug("[auth] Rt: 80 81")
|
|
198
|
+
|
|
199
|
+
# 属性控制
|
|
200
|
+
trace.filter.driver = True
|
|
201
|
+
trace.filter.protocol = True
|
|
202
|
+
trace.filter.level = "debug"
|
|
203
|
+
```
|
|
182
204
|
|
|
183
205
|
### assertions.py
|
|
184
206
|
|
|
@@ -225,9 +247,8 @@ with session() as reader:
|
|
|
225
247
|
|------|------|--------|
|
|
226
248
|
| `NFC_PORT` | 串口号 | - |
|
|
227
249
|
| `NFC_READER` | 读卡器类型 | - |
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
230
|
-
| `NFC_TRACE_PROTOCOL` | 开启 PROTOCOL 层追踪 | `false` |
|
|
250
|
+
| `NFC_TRACE_LAYER` | 启用的层 (逗号分隔) | - |
|
|
251
|
+
| `NFC_TRACE_LEVEL` | 最低日志级别 | `warning` |
|
|
231
252
|
| `NFC_CARD_PATH` | 外部卡片模块搜索路径 (分号分隔) | - |
|
|
232
253
|
|
|
233
254
|
支持多层 `.env` 加载:从脚本目录向上搜索所有 `.env` 文件,按从外到内的顺序依次加载(内层覆盖外层同名变量)。
|
|
@@ -242,9 +263,8 @@ with session() as reader:
|
|
|
242
263
|
```
|
|
243
264
|
NFC_PORT=COM20
|
|
244
265
|
NFC_READER=pn532
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
NFC_TRACE_PROTOCOL=true
|
|
266
|
+
NFC_TRACE_LAYER=protocol,warning,error,app
|
|
267
|
+
NFC_TRACE_LEVEL=protocol
|
|
248
268
|
```
|
|
249
269
|
|
|
250
270
|
## AI 编写脚本
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nfcscript"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.16"
|
|
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.16"
|
|
38
38
|
commit = true
|
|
39
39
|
tag = true
|
|
40
40
|
allow_dirty = true
|
|
@@ -19,20 +19,6 @@ def _find_dotenv_all(start_dir):
|
|
|
19
19
|
chain.reverse()
|
|
20
20
|
return chain
|
|
21
21
|
|
|
22
|
-
def _parse_level(value: str) -> int:
|
|
23
|
-
"""将字符串解析为解析级别,支持数字和别名"""
|
|
24
|
-
val = value.lower().strip()
|
|
25
|
-
if val in ("0", "false", "no", "off"):
|
|
26
|
-
return 0
|
|
27
|
-
if val in ("1", "simple", "summary"):
|
|
28
|
-
return 1
|
|
29
|
-
if val in ("2", "full", "tree"):
|
|
30
|
-
return 2
|
|
31
|
-
try:
|
|
32
|
-
return int(value)
|
|
33
|
-
except ValueError:
|
|
34
|
-
return 1
|
|
35
|
-
|
|
36
22
|
def run_script(script_path):
|
|
37
23
|
script_dir = os.path.dirname(os.path.abspath(script_path))
|
|
38
24
|
cwd = os.getcwd()
|
|
@@ -55,11 +41,8 @@ def main():
|
|
|
55
41
|
parser.add_argument("script", help="脚本文件路径")
|
|
56
42
|
parser.add_argument("-p", "--port", default=None, help="串口号 (默认: NFC_PORT 环境变量或 COM20)")
|
|
57
43
|
parser.add_argument("-r", "--reader", default=None, help="读卡器类型 (默认: NFC_READER 环境变量或 pn532)")
|
|
58
|
-
parser.add_argument("--trace-
|
|
59
|
-
parser.add_argument("--trace-
|
|
60
|
-
parser.add_argument("--trace-parse", type=int, default=None, choices=[0, 1, 2],
|
|
61
|
-
help="解析级别: 0=关闭 1=简单 2=复杂 (默认: NFC_TRACE_PARSE 或 1)")
|
|
62
|
-
parser.add_argument("--trace-level", default="INFO", help="日志级别 (默认: INFO)")
|
|
44
|
+
parser.add_argument("--trace-layer", default=None, help="启用的层 (逗号分隔: driver,debug,protocol,warning,error,app,all)")
|
|
45
|
+
parser.add_argument("--trace-level", default=None, help="最低日志级别 (driver/debug/protocol/warning/error/app, 默认: warning)")
|
|
63
46
|
|
|
64
47
|
args, extra = parser.parse_known_args()
|
|
65
48
|
|
|
@@ -81,27 +64,23 @@ def main():
|
|
|
81
64
|
|
|
82
65
|
from nfc import trace
|
|
83
66
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
trace.
|
|
101
|
-
trace.set_layer("PROTOCOL", trace_protocol)
|
|
102
|
-
trace.set_parse(_parse_level(trace_parse))
|
|
103
|
-
if trace_width is not None:
|
|
104
|
-
os.environ["CRFT_TRACE_WIDTH"] = trace_width
|
|
67
|
+
# 解析 --trace-layer: 启用指定层 (调试用,默认已开启 protocol/warning/error/app)
|
|
68
|
+
trace_env = os.environ.get("NFC_TRACE_LAYER", "")
|
|
69
|
+
trace_arg = args.trace_layer or trace_env
|
|
70
|
+
if trace_arg:
|
|
71
|
+
trace.filter.level = "driver" # 允许所有层可见
|
|
72
|
+
for name in trace_arg.split(","):
|
|
73
|
+
name = name.strip().lower()
|
|
74
|
+
if name == "all":
|
|
75
|
+
for layer in ["driver", "debug", "protocol", "warning", "error", "app"]:
|
|
76
|
+
setattr(trace.filter, layer, True)
|
|
77
|
+
elif name:
|
|
78
|
+
setattr(trace.filter, name, True)
|
|
79
|
+
|
|
80
|
+
# 解析 --trace-level: 最低级别过滤
|
|
81
|
+
level_env = os.environ.get("NFC_TRACE_LEVEL", "warning")
|
|
82
|
+
level_arg = args.trace_level or level_env
|
|
83
|
+
trace.filter.level = level_arg
|
|
105
84
|
|
|
106
85
|
run_script(args.script)
|
|
107
86
|
|
|
@@ -28,14 +28,14 @@ class _NFCState:
|
|
|
28
28
|
self._reader = CardReaderRegistry.create(reader_type, transport="serial", port=port)
|
|
29
29
|
self._reader.open()
|
|
30
30
|
self._connected = True
|
|
31
|
-
|
|
31
|
+
_trace.log(f"Connected to {reader_type.upper()} on port {port}", layer="app")
|
|
32
32
|
|
|
33
33
|
def disconnect(self):
|
|
34
34
|
if self._connected and self._reader:
|
|
35
35
|
self._reader.close()
|
|
36
36
|
self._connected = False
|
|
37
37
|
self._reader = None
|
|
38
|
-
|
|
38
|
+
_trace.log("Disconnected", layer="app")
|
|
39
39
|
|
|
40
40
|
def ensure_connected(self):
|
|
41
41
|
ASSERT_IS_NOT_NONE(self._reader, msg="NFC driver not connected. Call connect() first.")
|
|
@@ -125,9 +125,9 @@ def active(low_layer: bool = False, ignore_error: bool = False, reqa_cmd: int =
|
|
|
125
125
|
if not ignore_error:
|
|
126
126
|
ASSERT_EQUAL(expected_bcc, data[4], msg=f"CL{cl} BCC 校验失败: data={FORMAT_HEX(data)}")
|
|
127
127
|
elif data[4] != expected_bcc:
|
|
128
|
-
|
|
128
|
+
_trace.log(f"Warning: CL{cl} BCC 校验失败", layer="warning")
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
_trace.log(f"cl{cl}.uid: {FORMAT_HEX(data)}", layer="app")
|
|
131
131
|
has_next = (data[0] == 0x88)
|
|
132
132
|
uid_to_select = data[0:5]
|
|
133
133
|
sak_res = select(cl_level=cl, uid=uid_to_select)
|
|
@@ -137,7 +137,7 @@ def active(low_layer: bool = False, ignore_error: bool = False, reqa_cmd: int =
|
|
|
137
137
|
if not ignore_error:
|
|
138
138
|
ASSERT_IS_NOT_NONE(sak_res, msg=f"CL{cl} SAK 选择失败")
|
|
139
139
|
else:
|
|
140
|
-
|
|
140
|
+
_trace.log(f"Warning: CL{cl} SAK 选择失败", layer="warning")
|
|
141
141
|
|
|
142
142
|
if has_next:
|
|
143
143
|
full_uid.extend(data[1:4])
|
|
@@ -1,67 +1,66 @@
|
|
|
1
1
|
"""
|
|
2
2
|
NFC Script Trace 模块
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
统一日志 API,包装 nfctester.trace 的 6 层日志系统。
|
|
5
|
+
层: driver, debug, protocol, warning, error, app
|
|
6
|
+
|
|
7
|
+
过滤器控制: trace.filter.driver = True, trace.filter.level = "warning"
|
|
5
8
|
"""
|
|
6
9
|
|
|
7
10
|
from typing import Callable
|
|
8
11
|
from nfctester.trace import TraceEvent, trace as _trace
|
|
9
12
|
|
|
10
13
|
|
|
11
|
-
def
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
+
def log(msg: str, layer: str = "app"):
|
|
15
|
+
"""通用文本日志,指定层"""
|
|
16
|
+
_trace.log(msg, layer)
|
|
14
17
|
|
|
15
|
-
Args:
|
|
16
|
-
layer: 层级名称 ("DRIVER" 或 "PROTOCOL")
|
|
17
|
-
enable: True 开启,False 关闭
|
|
18
|
-
"""
|
|
19
|
-
_trace.set_layer(layer, enable)
|
|
20
18
|
|
|
19
|
+
def app(msg: str):
|
|
20
|
+
"""输出到 app 层 (level=50)"""
|
|
21
|
+
_trace.app(msg)
|
|
21
22
|
|
|
22
|
-
def set_level(level: str):
|
|
23
|
-
"""
|
|
24
|
-
设置日志级别。
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
_trace.set_level(level)
|
|
24
|
+
def debug(msg: str):
|
|
25
|
+
"""输出到 debug 层 (level=10)"""
|
|
26
|
+
_trace.debug(msg)
|
|
30
27
|
|
|
31
28
|
|
|
32
|
-
def
|
|
33
|
-
"""
|
|
34
|
-
|
|
29
|
+
def warning(msg: str):
|
|
30
|
+
"""输出到 warning 层 (level=30)"""
|
|
31
|
+
_trace.warning(msg)
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"""
|
|
39
|
-
_trace.
|
|
33
|
+
|
|
34
|
+
def error(msg: str):
|
|
35
|
+
"""输出到 error 层 (level=40)"""
|
|
36
|
+
_trace.error(msg)
|
|
40
37
|
|
|
41
38
|
|
|
42
39
|
def info(msg: str):
|
|
43
|
-
"""输出 INFO 级别日志"""
|
|
40
|
+
"""输出 INFO 级别日志 (无层标签)"""
|
|
44
41
|
_trace.info(msg)
|
|
45
42
|
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
"""输出 ERROR 级别日志"""
|
|
49
|
-
_trace.error(msg)
|
|
44
|
+
# --- 属性控制 ---
|
|
50
45
|
|
|
46
|
+
def __setattr__(name, value):
|
|
47
|
+
"""属性控制: trace.driver = True"""
|
|
48
|
+
setattr(_trace, name, value)
|
|
51
49
|
|
|
52
|
-
def warning(msg: str):
|
|
53
|
-
"""输出 WARNING 级别日志"""
|
|
54
|
-
_trace.warning(msg)
|
|
55
50
|
|
|
51
|
+
def __getattr__(name):
|
|
52
|
+
"""属性获取: trace.driver"""
|
|
53
|
+
return getattr(_trace, name)
|
|
56
54
|
|
|
57
|
-
def success(msg: str):
|
|
58
|
-
"""输出 SUCCESS 级别日志"""
|
|
59
|
-
_trace.success(msg)
|
|
60
55
|
|
|
56
|
+
def set_parse(level: int = 1):
|
|
57
|
+
"""
|
|
58
|
+
设置解析级别。
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
Args:
|
|
61
|
+
level: 0=关闭(hex), 1=简单(hex + 摘要标签)
|
|
62
|
+
"""
|
|
63
|
+
_trace.set_parse(level)
|
|
65
64
|
|
|
66
65
|
|
|
67
66
|
def add_sink(fn: Callable[[TraceEvent], None]):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nfcscript
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.16
|
|
4
4
|
Summary: A plugin-based core engine for DSL-style NFC testing automation.
|
|
5
5
|
Author: crthu
|
|
6
6
|
Requires-Python: >=3.14
|
|
@@ -36,13 +36,13 @@ nfcscript test_card.py -p COM21
|
|
|
36
36
|
nfcscript test_card.py -r acr122u
|
|
37
37
|
|
|
38
38
|
# 开启追踪层
|
|
39
|
-
nfcscript test_card.py --trace-
|
|
39
|
+
nfcscript test_card.py --trace-layer=protocol,debug
|
|
40
40
|
|
|
41
41
|
# 设置日志级别
|
|
42
|
-
nfcscript test_card.py --trace-level
|
|
42
|
+
nfcscript test_card.py --trace-level=driver
|
|
43
43
|
|
|
44
44
|
# 组合使用
|
|
45
|
-
nfcscript test_card.py -p COM21 -r pn532 --trace-
|
|
45
|
+
nfcscript test_card.py -p COM21 -r pn532 --trace-layer=protocol,debug --trace-level=driver
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
### nfc-cli - 交互式命令行
|
|
@@ -120,13 +120,13 @@ from nfc import *
|
|
|
120
120
|
connect()
|
|
121
121
|
|
|
122
122
|
# 开启追踪
|
|
123
|
-
trace.
|
|
124
|
-
trace.
|
|
123
|
+
trace.filter.driver = True
|
|
124
|
+
trace.filter.protocol = True
|
|
125
125
|
|
|
126
126
|
# 寻卡(自动切换协议解析器)
|
|
127
127
|
card_info = active()
|
|
128
128
|
ASSERT_IS_NOT_NONE(card_info, "未扫描到卡片")
|
|
129
|
-
|
|
129
|
+
trace.app(f"UID: {' '.join(f'{b:02X}' for b in card_info.uid)}")
|
|
130
130
|
|
|
131
131
|
# 创建卡片实例
|
|
132
132
|
from nfctester.registry import CardRegistry
|
|
@@ -143,7 +143,7 @@ from nfc import *
|
|
|
143
143
|
|
|
144
144
|
with session() as reader:
|
|
145
145
|
card_info = reader.active()
|
|
146
|
-
|
|
146
|
+
trace.app(f"UID: {card_info.uid}")
|
|
147
147
|
# 自动断开连接
|
|
148
148
|
```
|
|
149
149
|
|
|
@@ -181,14 +181,36 @@ with session() as reader:
|
|
|
181
181
|
|
|
182
182
|
### trace.py
|
|
183
183
|
|
|
184
|
+
**简洁写法(推荐):**
|
|
185
|
+
|
|
184
186
|
| 函数 | 说明 |
|
|
185
187
|
|------|------|
|
|
186
|
-
| `trace.
|
|
187
|
-
| `trace.
|
|
188
|
-
| `trace.
|
|
189
|
-
| `trace.
|
|
190
|
-
| `trace.
|
|
191
|
-
|
|
188
|
+
| `trace.app(msg)` | 输出到 app 层 (level=50) |
|
|
189
|
+
| `trace.debug(msg)` | 输出到 debug 层 (level=10) |
|
|
190
|
+
| `trace.warning(msg)` | 输出到 warning 层 (level=30) |
|
|
191
|
+
| `trace.error(msg)` | 输出到 error 层 (level=40) |
|
|
192
|
+
| `trace.log(msg, layer="app")` | 通用文本日志,指定层 |
|
|
193
|
+
|
|
194
|
+
**属性控制(推荐):**
|
|
195
|
+
|
|
196
|
+
| 属性 | 说明 |
|
|
197
|
+
|------|------|
|
|
198
|
+
| `trace.filter.driver = True` | 启用 driver 层 |
|
|
199
|
+
| `trace.filter.protocol = True` | 启用 protocol 层 |
|
|
200
|
+
| `trace.filter.debug = False` | 禁用 debug 层 |
|
|
201
|
+
| `trace.filter.level = "warning"` | 设置最低日志级别 |
|
|
202
|
+
| `trace.filter.level = 30` | 或用数字 |
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
# 简洁写法
|
|
206
|
+
trace.app("UID: AA BB CC DD")
|
|
207
|
+
trace.debug("[auth] Rt: 80 81")
|
|
208
|
+
|
|
209
|
+
# 属性控制
|
|
210
|
+
trace.filter.driver = True
|
|
211
|
+
trace.filter.protocol = True
|
|
212
|
+
trace.filter.level = "debug"
|
|
213
|
+
```
|
|
192
214
|
|
|
193
215
|
### assertions.py
|
|
194
216
|
|
|
@@ -235,9 +257,8 @@ with session() as reader:
|
|
|
235
257
|
|------|------|--------|
|
|
236
258
|
| `NFC_PORT` | 串口号 | - |
|
|
237
259
|
| `NFC_READER` | 读卡器类型 | - |
|
|
238
|
-
| `
|
|
239
|
-
| `
|
|
240
|
-
| `NFC_TRACE_PROTOCOL` | 开启 PROTOCOL 层追踪 | `false` |
|
|
260
|
+
| `NFC_TRACE_LAYER` | 启用的层 (逗号分隔) | - |
|
|
261
|
+
| `NFC_TRACE_LEVEL` | 最低日志级别 | `warning` |
|
|
241
262
|
| `NFC_CARD_PATH` | 外部卡片模块搜索路径 (分号分隔) | - |
|
|
242
263
|
|
|
243
264
|
支持多层 `.env` 加载:从脚本目录向上搜索所有 `.env` 文件,按从外到内的顺序依次加载(内层覆盖外层同名变量)。
|
|
@@ -252,9 +273,8 @@ with session() as reader:
|
|
|
252
273
|
```
|
|
253
274
|
NFC_PORT=COM20
|
|
254
275
|
NFC_READER=pn532
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
NFC_TRACE_PROTOCOL=true
|
|
276
|
+
NFC_TRACE_LAYER=protocol,warning,error,app
|
|
277
|
+
NFC_TRACE_LEVEL=protocol
|
|
258
278
|
```
|
|
259
279
|
|
|
260
280
|
## AI 编写脚本
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"""cli 模块测试 (_find_dotenv_all /
|
|
1
|
+
"""cli 模块测试 (_find_dotenv_all / run_script)"""
|
|
2
2
|
import os
|
|
3
3
|
import pytest
|
|
4
4
|
from unittest.mock import patch, MagicMock
|
|
5
|
-
from nfc.cli import _find_dotenv_all
|
|
5
|
+
from nfc.cli import _find_dotenv_all
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class TestFindDotenvAll:
|
|
@@ -34,46 +34,6 @@ class TestFindDotenvAll:
|
|
|
34
34
|
assert result[0] != result[1]
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
class TestParseLevel:
|
|
38
|
-
|
|
39
|
-
def test_zero(self):
|
|
40
|
-
assert _parse_level("0") == 0
|
|
41
|
-
|
|
42
|
-
def test_false(self):
|
|
43
|
-
assert _parse_level("false") == 0
|
|
44
|
-
|
|
45
|
-
def test_off(self):
|
|
46
|
-
assert _parse_level("off") == 0
|
|
47
|
-
|
|
48
|
-
def test_one(self):
|
|
49
|
-
assert _parse_level("1") == 1
|
|
50
|
-
|
|
51
|
-
def test_simple(self):
|
|
52
|
-
assert _parse_level("simple") == 1
|
|
53
|
-
|
|
54
|
-
def test_summary(self):
|
|
55
|
-
assert _parse_level("summary") == 1
|
|
56
|
-
|
|
57
|
-
def test_two(self):
|
|
58
|
-
assert _parse_level("2") == 2
|
|
59
|
-
|
|
60
|
-
def test_full(self):
|
|
61
|
-
assert _parse_level("full") == 2
|
|
62
|
-
|
|
63
|
-
def test_tree(self):
|
|
64
|
-
assert _parse_level("tree") == 2
|
|
65
|
-
|
|
66
|
-
def test_case_insensitive(self):
|
|
67
|
-
assert _parse_level("FULL") == 2
|
|
68
|
-
assert _parse_level("False") == 0
|
|
69
|
-
|
|
70
|
-
def test_unknown_falls_to_1(self):
|
|
71
|
-
assert _parse_level("unknown") == 1
|
|
72
|
-
|
|
73
|
-
def test_whitespace(self):
|
|
74
|
-
assert _parse_level(" 2 ") == 2
|
|
75
|
-
|
|
76
|
-
|
|
77
37
|
class TestRunScript:
|
|
78
38
|
|
|
79
39
|
def test_runs_script(self, tmp_path):
|
|
@@ -3,32 +3,6 @@ from unittest.mock import patch, MagicMock
|
|
|
3
3
|
from nfc import trace
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class TestSetLayer:
|
|
7
|
-
|
|
8
|
-
@patch("nfc.trace._trace")
|
|
9
|
-
def test_set_layer_enable(self, mock_trace):
|
|
10
|
-
trace.set_layer("DRIVER", True)
|
|
11
|
-
mock_trace.set_layer.assert_called_once_with("DRIVER", True)
|
|
12
|
-
|
|
13
|
-
@patch("nfc.trace._trace")
|
|
14
|
-
def test_set_layer_disable(self, mock_trace):
|
|
15
|
-
trace.set_layer("PROTOCOL", False)
|
|
16
|
-
mock_trace.set_layer.assert_called_once_with("PROTOCOL", False)
|
|
17
|
-
|
|
18
|
-
@patch("nfc.trace._trace")
|
|
19
|
-
def test_set_layer_default_enable(self, mock_trace):
|
|
20
|
-
trace.set_layer("DRIVER")
|
|
21
|
-
mock_trace.set_layer.assert_called_once_with("DRIVER", True)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class TestSetLevel:
|
|
25
|
-
|
|
26
|
-
@patch("nfc.trace._trace")
|
|
27
|
-
def test_set_level(self, mock_trace):
|
|
28
|
-
trace.set_level("DEBUG")
|
|
29
|
-
mock_trace.set_level.assert_called_once_with("DEBUG")
|
|
30
|
-
|
|
31
|
-
|
|
32
6
|
class TestSetParse:
|
|
33
7
|
|
|
34
8
|
@patch("nfc.trace._trace")
|
|
@@ -54,12 +28,17 @@ class TestLogFunctions:
|
|
|
54
28
|
trace.warning("warn message")
|
|
55
29
|
mock_trace.warning.assert_called_once_with("warn message")
|
|
56
30
|
|
|
57
|
-
@patch("nfc.trace._trace")
|
|
58
|
-
def test_success(self, mock_trace):
|
|
59
|
-
trace.success("ok message")
|
|
60
|
-
mock_trace.success.assert_called_once_with("ok message")
|
|
61
|
-
|
|
62
31
|
@patch("nfc.trace._trace")
|
|
63
32
|
def test_debug(self, mock_trace):
|
|
64
33
|
trace.debug("debug message")
|
|
65
34
|
mock_trace.debug.assert_called_once_with("debug message")
|
|
35
|
+
|
|
36
|
+
@patch("nfc.trace._trace")
|
|
37
|
+
def test_app(self, mock_trace):
|
|
38
|
+
trace.app("app message")
|
|
39
|
+
mock_trace.app.assert_called_once_with("app message")
|
|
40
|
+
|
|
41
|
+
@patch("nfc.trace._trace")
|
|
42
|
+
def test_log(self, mock_trace):
|
|
43
|
+
trace.log("log message", layer="debug")
|
|
44
|
+
mock_trace.log.assert_called_once_with("log message", "debug")
|
|
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
|