CrackNuts 0.0.1.dev2__py3-none-any.whl

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.
@@ -0,0 +1,83 @@
1
+ import struct
2
+
3
+ __version__ = "1.0.0"
4
+
5
+ DEFAULT_PORT = 9761
6
+
7
+ MAGIC_STR = b"AHCC"
8
+
9
+ # ┌───────────────────────────────────────────┬───────┐
10
+ # │--------------Request Header---------------│-------│
11
+ # │Magic │Version│Direction│Command│RFU│Length│PayLoad│
12
+ # │-------------------------------------------│-------│
13
+ # │ 4B │ 2B │ 1B │ 2B │2B │ 4B │$Length│
14
+ # │-------------------------------------------│-------│
15
+ # │'AHCC'│ 1 │ 'S' │ │ │ │ │
16
+ # └───────────────────────────────────────────┴───────┘
17
+
18
+ REQ_HEADER_FORMAT = ">4sH1sHHI"
19
+ REQ_HEADER_SIZE = struct.calcsize(REQ_HEADER_FORMAT)
20
+
21
+ # ┌──────────────────────────────────────┬───────┐
22
+ # │--------------Response Header---------│-------│
23
+ # │Magic │Version│Direction│Status│Length│PayLoad│
24
+ # │--------------------------------------│-------│
25
+ # │ 4B │ 2B │ 1B │ 2B │ 4B │$Length│
26
+ # │--------------------------------------│-------│
27
+ # │'AHCC'│ 1 │ 'R' │ │ │ │
28
+ # └──────────────────────────────────────┴───────┘
29
+
30
+ RES_HEADER_FORMAT = ">4sH1sHI"
31
+ RES_HEADER_SIZE = struct.calcsize(RES_HEADER_FORMAT)
32
+
33
+ DIRECTION_SEND = b"S"
34
+ DIRECTION_RESPONSE = b"R"
35
+
36
+ # Status Code
37
+ STATUS_OK = 0x0000
38
+ STATUS_BUSY = 0x0001
39
+ STATUS_ERROR = 0x8000
40
+ STATUS_UNSUPPORTED = 0x8001
41
+
42
+
43
+ def version():
44
+ return __version__
45
+
46
+
47
+ def _build_req_message(command: int, rfu: int = 0, payload: bytes = None):
48
+ content = struct.pack(
49
+ REQ_HEADER_FORMAT,
50
+ MAGIC_STR,
51
+ int(__version__.split(".")[0]),
52
+ DIRECTION_SEND,
53
+ command,
54
+ rfu,
55
+ 0 if payload is None else len(payload),
56
+ )
57
+ if payload is not None:
58
+ content += payload
59
+
60
+ return content
61
+
62
+
63
+ def _build_res_message(status: int, payload: bytes = None):
64
+ content = struct.pack(
65
+ RES_HEADER_FORMAT,
66
+ MAGIC_STR,
67
+ int(__version__.split(".")[0]),
68
+ DIRECTION_RESPONSE,
69
+ status,
70
+ 0 if payload is None else len(payload),
71
+ )
72
+ if payload is not None:
73
+ content += payload
74
+
75
+ return content
76
+
77
+
78
+ def build_send_message(command: int, rfu: int = 0, payload: bytes = None):
79
+ return _build_req_message(command, rfu, payload)
80
+
81
+
82
+ def build_response_message(status: int, payload: bytes = None):
83
+ return _build_res_message(status, payload)
@@ -0,0 +1,214 @@
1
+ import typing
2
+
3
+ import numpy as np
4
+
5
+ from cracknuts.cracker.cracker import Cracker, Config
6
+
7
+
8
+ class StatefulCracker(Cracker):
9
+ def __init__(self, cracker: Cracker):
10
+ self._cracker = cracker
11
+ self._config: Config = self._cracker.get_default_config()
12
+
13
+ def get_current_config(self) -> Config:
14
+ return self._config
15
+
16
+ def sync_config_to_cracker(self):
17
+ """
18
+ Sync config to cracker.
19
+ To prevent configuration inconsistencies between the host and the device,
20
+ so all configuration information needs to be written to the device.
21
+ User should call this function before get data from device.
22
+ """
23
+ # if self._config.nut_voltage is not None:
24
+ # self._cracker.nut_voltage(self._config.nut_voltage)
25
+ # if self._config.nut_clock is not None:
26
+ # self._cracker.nut_clock(self._config.nut_clock)
27
+ # if self._config.nut_enable is not None:
28
+ # self._cracker.nut_enable(self._config.nut_enable)
29
+ # if self._config.osc_analog_channel_enable is not None:
30
+ # self._cracker.osc_set_analog_channel_enable(self._config.osc_analog_channel_enable)
31
+ ... # comment for test.
32
+ # todo need complete...
33
+
34
+ def set_addr(self, ip, port) -> None:
35
+ return self._cracker.set_addr(ip, port)
36
+
37
+ def set_uri(self, uri: str) -> None:
38
+ return self._cracker.set_uri(uri)
39
+
40
+ def get_uri(self):
41
+ return self._cracker.get_uri()
42
+
43
+ def connect(self):
44
+ return self._cracker.connect()
45
+
46
+ def disconnect(self):
47
+ return self._cracker.disconnect()
48
+
49
+ def reconnect(self):
50
+ return self._cracker.reconnect()
51
+
52
+ def get_connection_status(self) -> bool:
53
+ return self._cracker.get_connection_status()
54
+
55
+ def send_and_receive(self, message) -> tuple[int, bytes]:
56
+ return self._cracker.send_and_receive(message)
57
+
58
+ def send_with_command(self, command: int, rfu: int = 0, payload: str | bytes = None) -> tuple[int, bytes | None]:
59
+ return self._cracker.send_with_command(command, rfu, payload)
60
+
61
+ def echo(self, payload: str) -> str:
62
+ return self._cracker.echo(payload)
63
+
64
+ def echo_hex(self, payload: str) -> str:
65
+ return self._cracker.echo_hex(payload)
66
+
67
+ def get_id(self) -> str:
68
+ return self._cracker.get_id()
69
+
70
+ def get_name(self) -> str:
71
+ return self._cracker.get_name()
72
+
73
+ def get_version(self) -> str:
74
+ return self._cracker.get_version()
75
+
76
+ def osc_set_analog_channel_enable(self, enable: dict[int, bool]):
77
+ self._config.osc_analog_channel_enable = enable
78
+ return self._cracker.osc_set_analog_channel_enable(enable)
79
+
80
+ def osc_set_analog_coupling(self, coupling: dict[int, int]):
81
+ return self._cracker.osc_set_analog_coupling(coupling)
82
+
83
+ def osc_set_analog_voltage(self, channel: int, voltage: int):
84
+ return self._cracker.osc_set_analog_voltage(channel, voltage)
85
+
86
+ def osc_set_analog_bias_voltage(self, channel: int, voltage: int):
87
+ return self._cracker.osc_set_analog_bias_voltage(channel, voltage)
88
+
89
+ def osc_set_digital_channel_enable(self, enable: dict[int, bool]):
90
+ return self._cracker.osc_set_digital_channel_enable(enable)
91
+
92
+ def osc_set_digital_voltage(self, voltage: int):
93
+ return self._cracker.osc_set_digital_voltage(voltage)
94
+
95
+ def osc_set_trigger_mode(self, source: int, stop: int):
96
+ return self._cracker.osc_set_trigger_mode(source, stop)
97
+
98
+ def osc_set_analog_trigger_source(self, channel: int):
99
+ return self._cracker.osc_set_analog_trigger_source(channel)
100
+
101
+ def osc_set_digital_trigger_source(self, channel: int):
102
+ return self._cracker.osc_set_digital_trigger_source(channel)
103
+
104
+ def osc_set_analog_trigger_voltage(self, voltage: int):
105
+ return self._cracker.osc_set_analog_trigger_voltage(voltage)
106
+
107
+ def osc_set_sample_delay(self, delay: int):
108
+ return self._cracker.osc_set_sample_delay(delay)
109
+
110
+ def osc_set_sample_len(self, length: int):
111
+ self._config.osc_sample_len = length
112
+ return self._cracker.osc_set_sample_len(length)
113
+
114
+ def get_default_config(self) -> typing.Optional["Config"]:
115
+ return self._cracker.get_default_config()
116
+
117
+ def osc_force(self):
118
+ return self._cracker.osc_force()
119
+
120
+ def osc_set_sample_clock(self, clock: int):
121
+ return self._cracker.osc_set_sample_clock(clock)
122
+
123
+ def osc_set_sample_phase(self, phase: int):
124
+ return self._cracker.osc_set_sample_phase(phase)
125
+
126
+ def osc_single(self):
127
+ return self._cracker.osc_single()
128
+
129
+ def osc_is_triggered(self):
130
+ return self._cracker.osc_is_triggered()
131
+
132
+ def osc_get_analog_wave(self, channel: int, offset: int, sample_count: int) -> tuple[int, np.ndarray]:
133
+ return self._cracker.osc_get_analog_wave(channel, offset, sample_count)
134
+
135
+ def osc_get_digital_wave(self, channel: int, offset: int, sample_count: int):
136
+ return self._cracker.osc_get_digital_wave(channel, offset, sample_count)
137
+
138
+ def osc_set_analog_gain(self, channel: int, gain: int):
139
+ return self._cracker.osc_set_analog_gain(channel, gain)
140
+
141
+ def nut_enable(self, enable: int):
142
+ self._config.cracker_nut_enable = enable
143
+ return self._cracker.nut_enable(enable)
144
+
145
+ def nut_voltage(self, voltage: int):
146
+ self._config.cracker_nut_voltage = voltage
147
+ return self._cracker.nut_voltage(voltage)
148
+
149
+ def osc_set_analog_gain_raw(self, channel: int, gain: int):
150
+ return self._cracker.osc_set_analog_gain_raw(channel, gain)
151
+
152
+ def nut_voltage_raw(self, voltage: int):
153
+ return self._cracker.nut_voltage_raw(voltage)
154
+
155
+ def nut_clock(self, clock: int):
156
+ self._config.cracker_nut_clock = clock
157
+ return self._cracker.nut_clock(clock)
158
+
159
+ def nut_interface(self, interface: dict[int, bool]):
160
+ return self._cracker.nut_interface(interface)
161
+
162
+ def nut_timeout(self, timeout: int):
163
+ return self._cracker.nut_timeout(timeout)
164
+
165
+ def cracker_serial_baud(self, baud: int):
166
+ return self._cracker.cracker_serial_baud(baud)
167
+
168
+ def cracker_serial_width(self, width: int):
169
+ return self._cracker.cracker_serial_width(width)
170
+
171
+ def cracker_serial_stop(self, stop: int):
172
+ return self._cracker.cracker_serial_stop(stop)
173
+
174
+ def cracker_serial_odd_eve(self, odd_eve: int):
175
+ return self._cracker.cracker_serial_odd_eve(odd_eve)
176
+
177
+ def cracker_serial_data(self, expect_len: int, data: bytes):
178
+ return self._cracker.cracker_serial_data(expect_len, data)
179
+
180
+ def cracker_spi_cpol(self, cpol: int):
181
+ return self._cracker.cracker_spi_cpol(cpol)
182
+
183
+ def cracker_spi_cpha(self, cpha: int):
184
+ return self._cracker.cracker_spi_cpha(cpha)
185
+
186
+ def cracker_spi_data_len(self, cpha: int):
187
+ return self._cracker.cracker_spi_data_len(cpha)
188
+
189
+ def cracker_spi_freq(self, freq: int):
190
+ return self._cracker.cracker_spi_freq(freq)
191
+
192
+ def cracker_spi_timeout(self, timeout: int):
193
+ return self._cracker.cracker_spi_timeout(timeout)
194
+
195
+ def cracker_spi_data(self, expect_len: int, data: bytes):
196
+ return self._cracker.cracker_spi_data(expect_len, data)
197
+
198
+ def cracker_i2c_freq(self, freq: int):
199
+ return self._cracker.cracker_i2c_freq(freq)
200
+
201
+ def cracker_i2c_timeout(self, timeout: int):
202
+ return self._cracker.cracker_i2c_timeout(timeout)
203
+
204
+ def cracker_i2c_data(self, expect_len: int, data: bytes):
205
+ return self._cracker.cracker_i2c_data(expect_len, data)
206
+
207
+ def cracker_can_freq(self, freq: int):
208
+ return self._cracker.cracker_can_freq(freq)
209
+
210
+ def cracker_can_timeout(self, timeout: int):
211
+ return self._cracker.cracker_can_timeout(timeout)
212
+
213
+ def cracker_can_data(self, expect_len: int, data: bytes):
214
+ return self._cracker.cracker_can_data(expect_len, data)
cracknuts/logger.py ADDED
@@ -0,0 +1,88 @@
1
+ import logging
2
+ from types import ModuleType
3
+
4
+
5
+ _LOG_LEVEL = logging.WARNING
6
+ _LOG_FORMATTER = logging.Formatter("[%(levelname)s] %(asctime)s %(module)s.%(funcName)s:%(lineno)d %(message)s")
7
+ _LOGGERS: dict[str, logging.Logger] = {}
8
+
9
+
10
+ def set_level(
11
+ level: str | int = logging.WARNING,
12
+ logger: str | type | ModuleType | object | None = None,
13
+ ) -> None:
14
+ global _LOG_LEVEL
15
+ if isinstance(level, str):
16
+ level = level.upper()
17
+ if level == "DEBUG":
18
+ _LOG_LEVEL = logging.DEBUG
19
+ elif level == "INFO":
20
+ _LOG_LEVEL = logging.INFO
21
+ elif level == "WARN":
22
+ _LOG_LEVEL = logging.WARNING
23
+ elif level == "ERROR":
24
+ _LOG_LEVEL = logging.ERROR
25
+ elif level == "CRITICAL":
26
+ _LOG_LEVEL = logging.CRITICAL
27
+ else:
28
+ raise ValueError(f"Unrecognized log level {level}.")
29
+ elif level not in [
30
+ logging.DEBUG,
31
+ logging.INFO,
32
+ logging.WARNING,
33
+ logging.ERROR,
34
+ logging.CRITICAL,
35
+ ]:
36
+ raise ValueError(f"Unrecognized log level {level}.")
37
+ else:
38
+ _LOG_LEVEL = level
39
+
40
+ _logger = None
41
+
42
+ if logger:
43
+ if isinstance(logger, ModuleType):
44
+ logger = logger.__name__
45
+ elif isinstance(logger, type):
46
+ logger = logger.__module__ + "." + logger.__name__
47
+ elif isinstance(logger, str):
48
+ logger = logger
49
+ else:
50
+ logger = logger.__class__.__module__ + "." + logger.__class__.__name__
51
+
52
+ _logger = _LOGGERS.get(logger)
53
+
54
+ if not _logger:
55
+ for _logger in _LOGGERS.values():
56
+ _logger.setLevel(_LOG_LEVEL)
57
+ else:
58
+ _logger.setLevel(_LOG_LEVEL)
59
+
60
+
61
+ def get_logger(name: str | type | object | ModuleType, level: int | None = None) -> logging.Logger:
62
+ if isinstance(name, ModuleType):
63
+ name = name.__name__
64
+ elif isinstance(name, type):
65
+ name = name.__module__ + "." + name.__name__
66
+ elif isinstance(name, str):
67
+ name = name
68
+ else:
69
+ name = name.__class__.__module__ + "." + name.__class__.__name__
70
+
71
+ if name in _LOGGERS:
72
+ return _LOGGERS[name]
73
+
74
+ logger = logging.getLogger(name)
75
+ if level is None:
76
+ logger.setLevel(_LOG_LEVEL)
77
+ else:
78
+ logger.setLevel(level)
79
+ stream_handler = logging.StreamHandler()
80
+ stream_handler.setFormatter(_LOG_FORMATTER)
81
+ logger.addHandler(stream_handler)
82
+ _LOGGERS[name] = logger
83
+ logger.propagate = False
84
+ return logger
85
+
86
+
87
+ def default_logger() -> logging.Logger:
88
+ return get_logger("cracknuts")
File without changes