CrackNuts 0.1.0__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.
Potentially problematic release.
This version of CrackNuts might be problematic. Click here for more details.
- cracknuts-0.1.0/PKG-INFO +18 -0
- cracknuts-0.1.0/README.md +3 -0
- cracknuts-0.1.0/pyproject.toml +39 -0
- cracknuts-0.1.0/setup.cfg +4 -0
- cracknuts-0.1.0/src/CrackNuts.egg-info/PKG-INFO +18 -0
- cracknuts-0.1.0/src/CrackNuts.egg-info/SOURCES.txt +25 -0
- cracknuts-0.1.0/src/CrackNuts.egg-info/dependency_links.txt +1 -0
- cracknuts-0.1.0/src/CrackNuts.egg-info/requires.txt +8 -0
- cracknuts-0.1.0/src/CrackNuts.egg-info/top_level.txt +1 -0
- cracknuts-0.1.0/src/cracknuts/__init__.py +1 -0
- cracknuts-0.1.0/src/cracknuts/acquisition/__init__.py +0 -0
- cracknuts-0.1.0/src/cracknuts/acquisition/acquisition.py +214 -0
- cracknuts-0.1.0/src/cracknuts/cracker/__init__.py +0 -0
- cracknuts-0.1.0/src/cracknuts/cracker/abs_cracker.py +355 -0
- cracknuts-0.1.0/src/cracknuts/cracker/basic_cracker.py +282 -0
- cracknuts-0.1.0/src/cracknuts/cracker/protocol.py +59 -0
- cracknuts-0.1.0/src/cracknuts/logger.py +86 -0
- cracknuts-0.1.0/src/cracknuts/solver/__init__.py +0 -0
- cracknuts-0.1.0/src/cracknuts/solver/trace.py +68 -0
- cracknuts-0.1.0/src/cracknuts/support/__init__.py +0 -0
- cracknuts-0.1.0/src/cracknuts/support/marimo/__init__.py +0 -0
- cracknuts-0.1.0/src/cracknuts/support/marimo/cracker_panel.py +148 -0
- cracknuts-0.1.0/src/cracknuts/support/marimo/ui/__init__.py +0 -0
- cracknuts-0.1.0/src/cracknuts/support/marimo/ui/cracker_panel.py +38 -0
- cracknuts-0.1.0/src/cracknuts/utils/__init__.py +0 -0
- cracknuts-0.1.0/src/cracknuts/utils/hex_util.py +42 -0
- cracknuts-0.1.0/tests/test_1.py +6 -0
cracknuts-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: CrackNuts
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A library for nut cracker device.
|
|
5
|
+
Author-email: Dingzb <dingzibiao@gmail.com>
|
|
6
|
+
Maintainer-email: Dingzb <dingzibiao@gmail.com>
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: numpy>=2.0.1
|
|
10
|
+
Requires-Dist: pandas>=2.2.2
|
|
11
|
+
Provides-Extra: test
|
|
12
|
+
Requires-Dist: pytest; extra == "test"
|
|
13
|
+
Provides-Extra: marimo
|
|
14
|
+
Requires-Dist: marimo; extra == "marimo"
|
|
15
|
+
|
|
16
|
+
# CrackNuts
|
|
17
|
+
|
|
18
|
+
TODO
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools >= 61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "CrackNuts"
|
|
7
|
+
description = "A library for nut cracker device."
|
|
8
|
+
dynamic = ["version"]
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Dingzb", email = "dingzibiao@gmail.com" }
|
|
13
|
+
]
|
|
14
|
+
maintainers = [
|
|
15
|
+
{ name = "Dingzb", email = "dingzibiao@gmail.com" }
|
|
16
|
+
]
|
|
17
|
+
dependencies = [
|
|
18
|
+
"numpy >= 2.0.1",
|
|
19
|
+
"pandas >= 2.2.2"
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
|
|
24
|
+
test = [
|
|
25
|
+
'pytest'
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
marimo = [
|
|
29
|
+
'marimo'
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[tool.setuptools.dynamic]
|
|
33
|
+
version = { attr = "cracknuts.__version__" }
|
|
34
|
+
|
|
35
|
+
[tool.pytest.ini_options]
|
|
36
|
+
minversion = "6.0"
|
|
37
|
+
addopts = "-ra -q"
|
|
38
|
+
|
|
39
|
+
[tool.pdm]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: CrackNuts
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A library for nut cracker device.
|
|
5
|
+
Author-email: Dingzb <dingzibiao@gmail.com>
|
|
6
|
+
Maintainer-email: Dingzb <dingzibiao@gmail.com>
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: numpy>=2.0.1
|
|
10
|
+
Requires-Dist: pandas>=2.2.2
|
|
11
|
+
Provides-Extra: test
|
|
12
|
+
Requires-Dist: pytest; extra == "test"
|
|
13
|
+
Provides-Extra: marimo
|
|
14
|
+
Requires-Dist: marimo; extra == "marimo"
|
|
15
|
+
|
|
16
|
+
# CrackNuts
|
|
17
|
+
|
|
18
|
+
TODO
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/CrackNuts.egg-info/PKG-INFO
|
|
4
|
+
src/CrackNuts.egg-info/SOURCES.txt
|
|
5
|
+
src/CrackNuts.egg-info/dependency_links.txt
|
|
6
|
+
src/CrackNuts.egg-info/requires.txt
|
|
7
|
+
src/CrackNuts.egg-info/top_level.txt
|
|
8
|
+
src/cracknuts/__init__.py
|
|
9
|
+
src/cracknuts/logger.py
|
|
10
|
+
src/cracknuts/acquisition/__init__.py
|
|
11
|
+
src/cracknuts/acquisition/acquisition.py
|
|
12
|
+
src/cracknuts/cracker/__init__.py
|
|
13
|
+
src/cracknuts/cracker/abs_cracker.py
|
|
14
|
+
src/cracknuts/cracker/basic_cracker.py
|
|
15
|
+
src/cracknuts/cracker/protocol.py
|
|
16
|
+
src/cracknuts/solver/__init__.py
|
|
17
|
+
src/cracknuts/solver/trace.py
|
|
18
|
+
src/cracknuts/support/__init__.py
|
|
19
|
+
src/cracknuts/support/marimo/__init__.py
|
|
20
|
+
src/cracknuts/support/marimo/cracker_panel.py
|
|
21
|
+
src/cracknuts/support/marimo/ui/__init__.py
|
|
22
|
+
src/cracknuts/support/marimo/ui/cracker_panel.py
|
|
23
|
+
src/cracknuts/utils/__init__.py
|
|
24
|
+
src/cracknuts/utils/hex_util.py
|
|
25
|
+
tests/test_1.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cracknuts
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
File without changes
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import datetime
|
|
3
|
+
import threading
|
|
4
|
+
import time
|
|
5
|
+
import typing
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import zarr
|
|
9
|
+
|
|
10
|
+
from cracknuts import logger
|
|
11
|
+
from cracknuts.cracker.abs_cracker import AbsCracker
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Acquisition(abc.ABC):
|
|
15
|
+
|
|
16
|
+
def __init__(self, cracker: AbsCracker):
|
|
17
|
+
self._logger = logger.get_logger(self)
|
|
18
|
+
self._cracker = cracker
|
|
19
|
+
self._last_wave: np.ndarray | None = np.array([np.zeros(1000)])
|
|
20
|
+
self._running = False
|
|
21
|
+
self._trace_count = 1
|
|
22
|
+
self._on_wave_loaded_callback: typing.Callable = typing.Callable[[np.ndarray], None]
|
|
23
|
+
self._trigger_judge_wait_time: float = 0.2 # second
|
|
24
|
+
self._trigger_judge_timeout: float = 2000000 # microsecond
|
|
25
|
+
|
|
26
|
+
def on_wave_loaded(self, callback: typing.Callable[[np.ndarray], None]) -> None:
|
|
27
|
+
self._on_wave_loaded_callback = callback
|
|
28
|
+
|
|
29
|
+
def run(self, count=1):
|
|
30
|
+
self._logger.debug('Start run mode.')
|
|
31
|
+
self._run(save_data=True, count=count)
|
|
32
|
+
|
|
33
|
+
def run_sync(self, count=1):
|
|
34
|
+
self._do_run(save_data=True, count=count)
|
|
35
|
+
|
|
36
|
+
def test(self, count=1):
|
|
37
|
+
self._logger.debug('Start test mode.')
|
|
38
|
+
self._run(count=count)
|
|
39
|
+
|
|
40
|
+
def stop(self):
|
|
41
|
+
self._running = False
|
|
42
|
+
|
|
43
|
+
def _run(self, save_data: bool = False, count=1):
|
|
44
|
+
threading.Thread(target=self._do_run, kwargs={'save_data': save_data, 'count': count}).start()
|
|
45
|
+
|
|
46
|
+
def _do_run(self, save_data: bool = False, count=1):
|
|
47
|
+
|
|
48
|
+
self._running = True
|
|
49
|
+
# self.connect_scrat()
|
|
50
|
+
# self.config_cracker()
|
|
51
|
+
# self.connect_scrat()
|
|
52
|
+
# self.config_scrat()
|
|
53
|
+
# init
|
|
54
|
+
self._trace_count = count
|
|
55
|
+
self.pre_init()
|
|
56
|
+
self.init() # self.transfer() 用户
|
|
57
|
+
self.save_dataset()
|
|
58
|
+
self.post_init()
|
|
59
|
+
|
|
60
|
+
self._loop()
|
|
61
|
+
|
|
62
|
+
self.pre_finish()
|
|
63
|
+
self.finish()
|
|
64
|
+
if save_data:
|
|
65
|
+
self.save_data()
|
|
66
|
+
self.post_finish()
|
|
67
|
+
|
|
68
|
+
self._running = True
|
|
69
|
+
|
|
70
|
+
def _loop(self):
|
|
71
|
+
for i in range(self._trace_count):
|
|
72
|
+
self._logger.debug('Get wave data: %s', i)
|
|
73
|
+
self.pre_do()
|
|
74
|
+
start = datetime.datetime.now()
|
|
75
|
+
self.do()
|
|
76
|
+
print('count: ', i, 'delay: ', datetime.datetime.now() - start)
|
|
77
|
+
trigger_judge_start_time = datetime.datetime.now().microsecond
|
|
78
|
+
# while self._running:
|
|
79
|
+
# trigger_judge_time = datetime.datetime.now().microsecond - trigger_judge_start_time
|
|
80
|
+
# if trigger_judge_time > self._trigger_judge_timeout:
|
|
81
|
+
# self._logger.error("Triggered judge timeout and will get next waves, "
|
|
82
|
+
# "judge time: %s and timeout is %s",
|
|
83
|
+
# trigger_judge_time, self._trigger_judge_timeout)
|
|
84
|
+
# break
|
|
85
|
+
# self._logger.debug('Judge trigger status.')
|
|
86
|
+
# # if self._is_triggered():
|
|
87
|
+
# # self._last_wave = self._get_waves()
|
|
88
|
+
# # if self._last_wave is not None:
|
|
89
|
+
# # self._logger.debug('Got wave: %s.', self._last_wave.shape)
|
|
90
|
+
# # if self._on_wave_loaded_callback and callable(self._on_wave_loaded_callback):
|
|
91
|
+
# # try:
|
|
92
|
+
# # self._on_wave_loaded_callback(self._last_wave)
|
|
93
|
+
# # except Exception as e:
|
|
94
|
+
# # self._logger.error('Wave loaded event callback error: %s', e.args)
|
|
95
|
+
# # time.sleep(1) # test
|
|
96
|
+
# # break
|
|
97
|
+
# break
|
|
98
|
+
# time.sleep(self._trigger_judge_wait_time)
|
|
99
|
+
self._save_wave()
|
|
100
|
+
self._post_do()
|
|
101
|
+
|
|
102
|
+
def _loop_without_log(self):
|
|
103
|
+
for i in range(self._trace_count):
|
|
104
|
+
# print('yes', self._logger.handlers[0].stream)
|
|
105
|
+
# self._logger.debug('Get wave data: %s', i)
|
|
106
|
+
self.pre_do()
|
|
107
|
+
self.do()
|
|
108
|
+
trigger_judge_start_time = datetime.datetime.now().microsecond
|
|
109
|
+
while self._running:
|
|
110
|
+
trigger_judge_time = datetime.datetime.now().microsecond - trigger_judge_start_time
|
|
111
|
+
if trigger_judge_time > self._trigger_judge_timeout:
|
|
112
|
+
# self._logger.error("Triggered judge timeout and will get next waves, "
|
|
113
|
+
# "judge time: %s and timeout is %s",
|
|
114
|
+
# trigger_judge_time, self._trigger_judge_timeout)
|
|
115
|
+
break
|
|
116
|
+
# self._logger.debug('Judge trigger status.')
|
|
117
|
+
if self._is_triggered():
|
|
118
|
+
self._last_wave = self._get_waves()
|
|
119
|
+
if self._last_wave is not None:
|
|
120
|
+
...
|
|
121
|
+
# self._logger.debug('Got wave: %s.', self._last_wave.shape)
|
|
122
|
+
if self._on_wave_loaded_callback and callable(self._on_wave_loaded_callback):
|
|
123
|
+
try:
|
|
124
|
+
self._on_wave_loaded_callback(self._last_wave)
|
|
125
|
+
except Exception as e:
|
|
126
|
+
...
|
|
127
|
+
# self._logger.error('Wave loaded event callback error: %s', e.args)
|
|
128
|
+
time.sleep(1)
|
|
129
|
+
break
|
|
130
|
+
time.sleep(self._trigger_judge_wait_time)
|
|
131
|
+
self._save_wave()
|
|
132
|
+
self._post_do()
|
|
133
|
+
|
|
134
|
+
def connect_scrat(self):
|
|
135
|
+
"""
|
|
136
|
+
Connect to scrat device
|
|
137
|
+
:return:
|
|
138
|
+
"""
|
|
139
|
+
...
|
|
140
|
+
|
|
141
|
+
def connect_cracker(self):
|
|
142
|
+
"""
|
|
143
|
+
Connect to cracker device.
|
|
144
|
+
:return:
|
|
145
|
+
"""
|
|
146
|
+
self._cracker.connect()
|
|
147
|
+
|
|
148
|
+
def connect_net(self):
|
|
149
|
+
...
|
|
150
|
+
|
|
151
|
+
def config_scrat(self):
|
|
152
|
+
...
|
|
153
|
+
|
|
154
|
+
def config_cracker(self):
|
|
155
|
+
...
|
|
156
|
+
|
|
157
|
+
def pre_init(self):
|
|
158
|
+
...
|
|
159
|
+
|
|
160
|
+
def init(self):
|
|
161
|
+
...
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def post_init(self):
|
|
165
|
+
...
|
|
166
|
+
|
|
167
|
+
def transfer(self):
|
|
168
|
+
...
|
|
169
|
+
|
|
170
|
+
def pre_do(self):
|
|
171
|
+
...
|
|
172
|
+
|
|
173
|
+
def do(self):
|
|
174
|
+
...
|
|
175
|
+
|
|
176
|
+
def _post_do(self):
|
|
177
|
+
...
|
|
178
|
+
|
|
179
|
+
def arm(self):
|
|
180
|
+
...
|
|
181
|
+
|
|
182
|
+
def _is_triggered(self):
|
|
183
|
+
# for test
|
|
184
|
+
time.sleep(0.1)
|
|
185
|
+
return True
|
|
186
|
+
|
|
187
|
+
def _get_waves(self):
|
|
188
|
+
return np.array([np.random.random(1000)])
|
|
189
|
+
|
|
190
|
+
def _save_wave(self):
|
|
191
|
+
...
|
|
192
|
+
|
|
193
|
+
def save_data(self, data_type: str = 'zarr'):
|
|
194
|
+
"""
|
|
195
|
+
Save wave, key and other info to acquisition dataset file.
|
|
196
|
+
"""
|
|
197
|
+
# if data_type == 'zarr':
|
|
198
|
+
# zarr.create()
|
|
199
|
+
...
|
|
200
|
+
|
|
201
|
+
def pre_finish(self):
|
|
202
|
+
...
|
|
203
|
+
|
|
204
|
+
def post_finish(self):
|
|
205
|
+
...
|
|
206
|
+
|
|
207
|
+
def save_dataset(self):
|
|
208
|
+
...
|
|
209
|
+
|
|
210
|
+
def finish(self):
|
|
211
|
+
pass
|
|
212
|
+
|
|
213
|
+
def get_last_wave(self):
|
|
214
|
+
return self._last_wave
|
|
File without changes
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import struct
|
|
3
|
+
import typing
|
|
4
|
+
from abc import ABC
|
|
5
|
+
from abc import abstractmethod
|
|
6
|
+
|
|
7
|
+
from cracknuts import logger
|
|
8
|
+
from cracknuts.cracker import protocol
|
|
9
|
+
import cracknuts.utils.hex_util as hex_util
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Commands:
|
|
13
|
+
"""
|
|
14
|
+
Protocol commands.
|
|
15
|
+
"""
|
|
16
|
+
GET_ID = 0x0001
|
|
17
|
+
GET_NAME = 0x0002
|
|
18
|
+
|
|
19
|
+
SCRAT_ANALOG_CHANNEL_ENABLE = 0x0100
|
|
20
|
+
SCRAT_ANALOG_COUPLING = 0x0101
|
|
21
|
+
SCRAT_ANALOG_VOLTAGE = 0x0102
|
|
22
|
+
SCRAT_ANALOG_BIAS_VOLTAGE = 0x0103
|
|
23
|
+
SCRAT_ANALOG_GAIN = 0x0104
|
|
24
|
+
|
|
25
|
+
SCRAT_DIGITAL_CHANNEL_ENABLE = 0x0110
|
|
26
|
+
SCRAT_DIGITAL_VOLTAGE = 0x0111
|
|
27
|
+
|
|
28
|
+
SCRAT_TRIGGER_MODE = 0x0120
|
|
29
|
+
|
|
30
|
+
SCRAT_ANALOG_TRIGGER_SOURCE = 0x0121
|
|
31
|
+
SCRAT_DIGITAL_TRIGGER_SOURCE = 0x0122
|
|
32
|
+
|
|
33
|
+
SCRAT_ANALOG_TRIGGER_VOLTAGE = 0x0123
|
|
34
|
+
|
|
35
|
+
SCRAT_TRIGGER_DELAY = 0x0124
|
|
36
|
+
|
|
37
|
+
SCRAT_SAMPLE_LENGTH = 0x0125
|
|
38
|
+
|
|
39
|
+
SCRAT_ARM = 0x0126
|
|
40
|
+
|
|
41
|
+
SCRAT_IS_TRIGGERED = 0x0127
|
|
42
|
+
|
|
43
|
+
SCRAT_GET_ANALOG_WAVES = 0x0130
|
|
44
|
+
SCRAT_GET_DIGITAL_WAVES = 0x0130
|
|
45
|
+
|
|
46
|
+
CRACKER_NUT_ENABLE = 0x0200
|
|
47
|
+
CRACKER_NUT_VOLTAGE = 0x0201
|
|
48
|
+
CRACKER_NUT_INTERFACE = 0x0210
|
|
49
|
+
CRACKER_NUT_TIMEOUT = 0x0224
|
|
50
|
+
|
|
51
|
+
CRACKER_SERIAL_BAUD = 0x0220
|
|
52
|
+
CRACKER_SERIAL_WIDTH = 0x0221
|
|
53
|
+
CRACKER_SERIAL_STOP = 0x0222
|
|
54
|
+
CRACKER_SERIAL_ODD_EVE = 0x0223
|
|
55
|
+
CRACKER_SERIAL_DATA = 0x022A
|
|
56
|
+
|
|
57
|
+
CRACKER_SPI_CPOL = 0x0230
|
|
58
|
+
CRACKER_SPI_CPHA = 0x0231
|
|
59
|
+
CRACKER_SPI_DATA_LEN = 0x0232
|
|
60
|
+
CRACKER_SPI_FREQ = 0x0233
|
|
61
|
+
CRACKER_SPI_TIMEOUT = 0x0234
|
|
62
|
+
CRACKER_SPI_DATA = 0x023A
|
|
63
|
+
|
|
64
|
+
CRACKER_I2C_FREQ = 0x0240
|
|
65
|
+
CRACKER_I2C_TIMEOUT = 0x0244
|
|
66
|
+
CRACKER_I2C_DATA = 0x024A
|
|
67
|
+
|
|
68
|
+
CRACKER_CAN_FREQ = 0x0250
|
|
69
|
+
CRACKER_CAN_TIMEOUT = 0x0254
|
|
70
|
+
CRACKER_CA_DATA = 0x025A
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class AbsCracker(ABC):
|
|
74
|
+
"""Cracker
|
|
75
|
+
Cracker
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
def __init__(self, server_address=None):
|
|
79
|
+
"""
|
|
80
|
+
:param server_address: Cracker device address (ip, port)
|
|
81
|
+
"""
|
|
82
|
+
self._logger = logger.get_logger(self)
|
|
83
|
+
self._server_address = server_address
|
|
84
|
+
self._socket: socket.socket | None = None
|
|
85
|
+
self._connection_status = False
|
|
86
|
+
|
|
87
|
+
def set_addr(self, ip, port) -> None:
|
|
88
|
+
self._server_address = ip, port
|
|
89
|
+
|
|
90
|
+
def connect(self):
|
|
91
|
+
"""
|
|
92
|
+
Connect to Cracker device.
|
|
93
|
+
:return: Cracker self.
|
|
94
|
+
"""
|
|
95
|
+
try:
|
|
96
|
+
if not self._socket:
|
|
97
|
+
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
98
|
+
self._socket.settimeout(5)
|
|
99
|
+
self._socket.connect(self._server_address)
|
|
100
|
+
self._connection_status = True
|
|
101
|
+
self._logger.info('Connected to cracker: {}'.format(self._server_address))
|
|
102
|
+
except socket.error as e:
|
|
103
|
+
self._logger.error('Connection failed: %s', e)
|
|
104
|
+
self._connection_status = False
|
|
105
|
+
return self
|
|
106
|
+
|
|
107
|
+
def disconnect(self):
|
|
108
|
+
"""
|
|
109
|
+
Disconnect Cracker device.
|
|
110
|
+
:return: Cracker self.
|
|
111
|
+
"""
|
|
112
|
+
try:
|
|
113
|
+
if self._socket:
|
|
114
|
+
self._socket.close()
|
|
115
|
+
self._socket = None
|
|
116
|
+
self._logger.info(f'Disconnect from {self._server_address}')
|
|
117
|
+
except socket.error as e:
|
|
118
|
+
self._logger.error('Disconnection failed: %s', e)
|
|
119
|
+
finally:
|
|
120
|
+
self._connection_status = False
|
|
121
|
+
return self
|
|
122
|
+
|
|
123
|
+
def reconnect(self):
|
|
124
|
+
"""
|
|
125
|
+
Reconnect to Cracker device.
|
|
126
|
+
:return: Cracker self.
|
|
127
|
+
"""
|
|
128
|
+
self.disconnect()
|
|
129
|
+
self.connect()
|
|
130
|
+
|
|
131
|
+
def get_connection_status(self):
|
|
132
|
+
"""
|
|
133
|
+
Get connection status.
|
|
134
|
+
:return: True or False
|
|
135
|
+
"""
|
|
136
|
+
return self._connection_status
|
|
137
|
+
|
|
138
|
+
def send_and_receive(self, message) -> None | bytes:
|
|
139
|
+
"""
|
|
140
|
+
Send message to socket
|
|
141
|
+
:param message:
|
|
142
|
+
:return:
|
|
143
|
+
"""
|
|
144
|
+
try:
|
|
145
|
+
if not self.get_connection_status():
|
|
146
|
+
self.connect()
|
|
147
|
+
self._logger.debug("Send message to %s: \n%s", self._server_address,
|
|
148
|
+
hex_util.get_bytes_matrix(message))
|
|
149
|
+
self._socket.sendall(message)
|
|
150
|
+
resp_header = self._socket.recv(protocol.RESP_HEADER_SIZE)
|
|
151
|
+
self._logger.debug("Get response header from %s: \n%s", self._server_address,
|
|
152
|
+
hex_util.get_bytes_matrix(resp_header))
|
|
153
|
+
magic, version, direction, status, length = struct.unpack(
|
|
154
|
+
protocol.RESP_HEADER_FORMAT, resp_header
|
|
155
|
+
)
|
|
156
|
+
self._logger.debug(
|
|
157
|
+
"Receive header from %s: %s",
|
|
158
|
+
self._server_address,
|
|
159
|
+
(magic, version, direction, status, length),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
if length == 0:
|
|
163
|
+
return None
|
|
164
|
+
resp_payload = self._socket.recv(length)
|
|
165
|
+
self._logger.debug(
|
|
166
|
+
"Receive payload from %s: \n%s", self._server_address, hex_util.get_bytes_matrix(resp_payload)
|
|
167
|
+
)
|
|
168
|
+
return resp_payload
|
|
169
|
+
except socket.error as e:
|
|
170
|
+
self._logger.error('Send message failed: %s', e)
|
|
171
|
+
return None
|
|
172
|
+
|
|
173
|
+
def send_with_command(self, command: int | bytes, payload: str | bytes = None):
|
|
174
|
+
if isinstance(payload, str):
|
|
175
|
+
payload = bytes.fromhex(payload)
|
|
176
|
+
return self.send_and_receive(protocol.build_send_message(command, payload))
|
|
177
|
+
|
|
178
|
+
def echo(self, payload: str) -> str:
|
|
179
|
+
"""
|
|
180
|
+
length <= 1024
|
|
181
|
+
"""
|
|
182
|
+
self._socket.sendall(payload.encode('ascii'))
|
|
183
|
+
res = self._socket.recv(1024).decode('ascii')
|
|
184
|
+
self._logger.debug(f'Get response: {res}')
|
|
185
|
+
return res
|
|
186
|
+
|
|
187
|
+
def echo_hex(self, payload: str) -> str:
|
|
188
|
+
"""
|
|
189
|
+
length <= 1024
|
|
190
|
+
"""
|
|
191
|
+
payload = bytes.fromhex(payload)
|
|
192
|
+
self._socket.sendall(payload)
|
|
193
|
+
res = self._socket.recv(1024).hex()
|
|
194
|
+
self._logger.debug(f'Get response: {res}')
|
|
195
|
+
return res
|
|
196
|
+
|
|
197
|
+
@abstractmethod
|
|
198
|
+
def get_id(self) -> str:
|
|
199
|
+
...
|
|
200
|
+
|
|
201
|
+
@abstractmethod
|
|
202
|
+
def get_name(self) -> str:
|
|
203
|
+
...
|
|
204
|
+
|
|
205
|
+
@abstractmethod
|
|
206
|
+
def scrat_analog_channel_enable(self, enable: typing.Dict[int, bool]):
|
|
207
|
+
...
|
|
208
|
+
|
|
209
|
+
@abstractmethod
|
|
210
|
+
def scrat_analog_coupling(self, coupling: typing.Dict[int, int]):
|
|
211
|
+
...
|
|
212
|
+
|
|
213
|
+
@abstractmethod
|
|
214
|
+
def scrat_analog_voltage(self, channel: int, voltage: int):
|
|
215
|
+
...
|
|
216
|
+
|
|
217
|
+
@abstractmethod
|
|
218
|
+
def scrat_analog_bias_voltage(self, channel: int, voltage: int):
|
|
219
|
+
...
|
|
220
|
+
|
|
221
|
+
@abstractmethod
|
|
222
|
+
def scrat_digital_channel_enable(self, enable: typing.Dict[int, bool]):
|
|
223
|
+
...
|
|
224
|
+
|
|
225
|
+
@abstractmethod
|
|
226
|
+
def scrat_digital_voltage(self, voltage: int):
|
|
227
|
+
...
|
|
228
|
+
|
|
229
|
+
@abstractmethod
|
|
230
|
+
def scrat_trigger_mode(self, source: int, stop: int):
|
|
231
|
+
...
|
|
232
|
+
|
|
233
|
+
@abstractmethod
|
|
234
|
+
def scrat_analog_trigger_source(self, channel: int):
|
|
235
|
+
...
|
|
236
|
+
|
|
237
|
+
@abstractmethod
|
|
238
|
+
def scrat_digital_trigger_source(self, channel: int):
|
|
239
|
+
...
|
|
240
|
+
|
|
241
|
+
@abstractmethod
|
|
242
|
+
def scrat_analog_trigger_voltage(self, voltage: int):
|
|
243
|
+
...
|
|
244
|
+
|
|
245
|
+
@abstractmethod
|
|
246
|
+
def scrat_trigger_delay(self, delay: int):
|
|
247
|
+
...
|
|
248
|
+
|
|
249
|
+
@abstractmethod
|
|
250
|
+
def scrat_sample_len(self, length: int):
|
|
251
|
+
...
|
|
252
|
+
|
|
253
|
+
@abstractmethod
|
|
254
|
+
def scrat_arm(self):
|
|
255
|
+
...
|
|
256
|
+
|
|
257
|
+
@abstractmethod
|
|
258
|
+
def scrat_is_triggered(self):
|
|
259
|
+
...
|
|
260
|
+
|
|
261
|
+
@abstractmethod
|
|
262
|
+
def scrat_get_analog_wave(self, channel: int, offset: int, sample_count: int):
|
|
263
|
+
...
|
|
264
|
+
|
|
265
|
+
@abstractmethod
|
|
266
|
+
def scrat_get_digital_wave(self, channel: int, offset: int, sample_count: int):
|
|
267
|
+
...
|
|
268
|
+
|
|
269
|
+
@abstractmethod
|
|
270
|
+
def scrat_analog_gain(self, gain: int):
|
|
271
|
+
...
|
|
272
|
+
|
|
273
|
+
@abstractmethod
|
|
274
|
+
def cracker_nut_enable(self, enable: int):
|
|
275
|
+
...
|
|
276
|
+
|
|
277
|
+
@abstractmethod
|
|
278
|
+
def cracker_nut_voltage(self, voltage: int):
|
|
279
|
+
...
|
|
280
|
+
|
|
281
|
+
@abstractmethod
|
|
282
|
+
def cracker_nut_interface(self, interface: typing.Dict[int, bool]):
|
|
283
|
+
...
|
|
284
|
+
|
|
285
|
+
@abstractmethod
|
|
286
|
+
def cracker_nut_timeout(self, timeout: int):
|
|
287
|
+
...
|
|
288
|
+
|
|
289
|
+
@abstractmethod
|
|
290
|
+
def cracker_serial_baud(self, baud: int):
|
|
291
|
+
...
|
|
292
|
+
|
|
293
|
+
@abstractmethod
|
|
294
|
+
def cracker_serial_width(self, width: int):
|
|
295
|
+
...
|
|
296
|
+
|
|
297
|
+
@abstractmethod
|
|
298
|
+
def cracker_serial_stop(self, stop: int):
|
|
299
|
+
...
|
|
300
|
+
|
|
301
|
+
@abstractmethod
|
|
302
|
+
def cracker_serial_odd_eve(self, odd_eve: int):
|
|
303
|
+
...
|
|
304
|
+
|
|
305
|
+
@abstractmethod
|
|
306
|
+
def cracker_serial_data(self, expect_len: int, data: bytes):
|
|
307
|
+
...
|
|
308
|
+
|
|
309
|
+
@abstractmethod
|
|
310
|
+
def cracker_spi_cpol(self, cpol: int):
|
|
311
|
+
...
|
|
312
|
+
|
|
313
|
+
@abstractmethod
|
|
314
|
+
def cracker_spi_cpha(self, cpha: int):
|
|
315
|
+
...
|
|
316
|
+
|
|
317
|
+
@abstractmethod
|
|
318
|
+
def cracker_spi_data_len(self, cpha: int):
|
|
319
|
+
...
|
|
320
|
+
|
|
321
|
+
@abstractmethod
|
|
322
|
+
def cracker_spi_freq(self, freq: int):
|
|
323
|
+
...
|
|
324
|
+
|
|
325
|
+
@abstractmethod
|
|
326
|
+
def cracker_spi_timeout(self, timeout: int):
|
|
327
|
+
...
|
|
328
|
+
|
|
329
|
+
@abstractmethod
|
|
330
|
+
def cracker_spi_data(self, expect_len: int, data: bytes):
|
|
331
|
+
...
|
|
332
|
+
|
|
333
|
+
@abstractmethod
|
|
334
|
+
def cracker_i2c_freq(self, freq: int):
|
|
335
|
+
...
|
|
336
|
+
|
|
337
|
+
@abstractmethod
|
|
338
|
+
def cracker_i2c_timeout(self, timeout: int):
|
|
339
|
+
...
|
|
340
|
+
|
|
341
|
+
@abstractmethod
|
|
342
|
+
def cracker_i2c_data(self, expect_len: int, data: bytes):
|
|
343
|
+
...
|
|
344
|
+
|
|
345
|
+
@abstractmethod
|
|
346
|
+
def cracker_can_freq(self, freq: int):
|
|
347
|
+
...
|
|
348
|
+
|
|
349
|
+
@abstractmethod
|
|
350
|
+
def cracker_can_timeout(self, timeout: int):
|
|
351
|
+
...
|
|
352
|
+
|
|
353
|
+
@abstractmethod
|
|
354
|
+
def cracker_can_data(self, expect_len: int, data: bytes):
|
|
355
|
+
...
|