py-uds-demo 26.0.1__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.
- py_uds_demo/__init__.py +0 -0
- py_uds_demo/__main__.py +57 -0
- py_uds_demo/core/__init__.py +0 -0
- py_uds_demo/core/client.py +80 -0
- py_uds_demo/core/server.py +227 -0
- py_uds_demo/core/utils/__init__.py +0 -0
- py_uds_demo/core/utils/helpers.py +314 -0
- py_uds_demo/core/utils/responses.py +55 -0
- py_uds_demo/core/utils/services/__init__.py +0 -0
- py_uds_demo/core/utils/services/data_transmission.py +398 -0
- py_uds_demo/core/utils/services/diagnostic_and_commmunication_management.py +755 -0
- py_uds_demo/core/utils/services/input_output_contol.py +63 -0
- py_uds_demo/core/utils/services/negative_response.py +1 -0
- py_uds_demo/core/utils/services/remote_activation_of_routine.py +80 -0
- py_uds_demo/core/utils/services/stored_data_transmission.py +132 -0
- py_uds_demo/core/utils/services/upload_download.py +189 -0
- py_uds_demo/interface/__init__.py +0 -0
- py_uds_demo/interface/api.py +30 -0
- py_uds_demo/interface/cli.py +51 -0
- py_uds_demo/interface/gui.py +83 -0
- py_uds_demo/interface/web.py +422 -0
- py_uds_demo-26.0.1.dist-info/METADATA +53 -0
- py_uds_demo-26.0.1.dist-info/RECORD +24 -0
- py_uds_demo-26.0.1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
def split_integer_to_bytes(value: int) -> list[int]:
|
|
2
|
+
"""Splits an integer into a list of bytes (little-endian).
|
|
3
|
+
|
|
4
|
+
Args:
|
|
5
|
+
value: The integer to split.
|
|
6
|
+
|
|
7
|
+
Returns:
|
|
8
|
+
A list of integers, where each integer is a byte.
|
|
9
|
+
"""
|
|
10
|
+
return [(value >> (i * 8)) & 0xFF for i in range((value.bit_length() + 7) // 8)]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Sid:
|
|
14
|
+
"""Service Identifiers (SIDs) for UDS.
|
|
15
|
+
|
|
16
|
+
This class contains constants for all service identifiers as defined in
|
|
17
|
+
the ISO 14229 standard. Each SID has a long name and a short alias.
|
|
18
|
+
|
|
19
|
+
See Also:
|
|
20
|
+
ISO 14229
|
|
21
|
+
"""
|
|
22
|
+
def __init__(self) -> None:
|
|
23
|
+
# Diagnostic and communication management
|
|
24
|
+
self.DIAGNOSTIC_SESSION_CONTROL = self.DSC = 0x10
|
|
25
|
+
self.ECU_RESET = self.ER = 0x11
|
|
26
|
+
self.SECURITY_ACCESS = self.SA = 0x27
|
|
27
|
+
self.COMMUNICATION_CONTROL = self.CC = 0X28
|
|
28
|
+
self.TESTER_PRESENT = self.TP = 0x3E
|
|
29
|
+
self.ACCESS_TIMING_PARAMETER = self.ATP = 0x83
|
|
30
|
+
self.SECURED_DATA_TRANSMISSION = self.SDT = 0x84
|
|
31
|
+
self.CONTROL_DTC_SETTING = self.CDTCS = 0x85
|
|
32
|
+
self.RESPONSE_ON_EVENT = self.ROE = 0x86
|
|
33
|
+
self.LINK_CONTROL = self.LC = 0x87
|
|
34
|
+
# Data transmission
|
|
35
|
+
self.READ_DATA_BY_IDENTIFIER = self.RDBI = 0x22
|
|
36
|
+
self.READ_MEMORY_BY_ADDRESS = self.RMBA = 0x23
|
|
37
|
+
self.READ_SCALING_DATA_BY_IDENTIFIER = self.RSDBI = 0x24
|
|
38
|
+
self.READ_DATA_BY_PERIODIC_IDENTIFIER = self.RDBPI = 0x2A
|
|
39
|
+
self.DYNAMICALLY_DEFINE_DATA_IDENTIFIER = self.DDDI = 0x2C
|
|
40
|
+
self.WRITE_DATA_BY_IDENTIFIER = self.WDBI = 0x2E
|
|
41
|
+
self.WRITE_MEMORY_BY_ADDRESS = self.WMBA = 0x3D
|
|
42
|
+
# Stored data transmission
|
|
43
|
+
self.CLEAR_DIAGNOSTIC_INFORMATION = self.CDTCI = 0x14
|
|
44
|
+
self.READ_DTC_INFORMATION = self.RDTCI = 0x19
|
|
45
|
+
# Input Output control
|
|
46
|
+
self.INPUT_OUTPUT_CONTROL_BY_IDENTIFIER = self.IOCBI = 0x2F
|
|
47
|
+
# Remote activation of routine
|
|
48
|
+
self.ROUTINE_CONTROL = self.RC = 0x31
|
|
49
|
+
# Upload download
|
|
50
|
+
self.REQUEST_DOWNLOAD = self.RD = 0x34
|
|
51
|
+
self.REQUEST_UPLOAD = self.RU = 0x35
|
|
52
|
+
self.TRANSFER_DATA = self.TD = 0x36
|
|
53
|
+
self.REQUEST_TRANSFER_EXIT = self.RTE = 0x37
|
|
54
|
+
self.REQUEST_FILE_TRANSFER = self.RFT = 0x38
|
|
55
|
+
# Negative Response
|
|
56
|
+
self.NEGATIVE_RESPONSE = self.NR = 0x7F
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class Sfid:
|
|
60
|
+
"""Sub-function Identifiers (SFIDs) for UDS.
|
|
61
|
+
|
|
62
|
+
This class contains constants for all sub-function identifiers as defined
|
|
63
|
+
in the ISO 14229 standard. Each SFID has a long name and a short alias.
|
|
64
|
+
|
|
65
|
+
See Also:
|
|
66
|
+
ISO 14229
|
|
67
|
+
"""
|
|
68
|
+
def __init__(self) -> None:
|
|
69
|
+
# diagnostic_session_control
|
|
70
|
+
self.DEFAULT_SESSION = self.DS = 0x01
|
|
71
|
+
self.PROGRAMMING_SESSION = self.PRGS = 0x02
|
|
72
|
+
self.EXTENDED_SESSION = self.EXTDS = 0x03
|
|
73
|
+
self.SAFETY_SYSTEM_DIAGNOSTIC_SESSION = self.SSDS = 0x04
|
|
74
|
+
# ecu_reset
|
|
75
|
+
self.HARD_RESET = self.HR = 0x01
|
|
76
|
+
self.KEY_ON_OFF_RESET = self.KOFFONR = 0x02
|
|
77
|
+
self.SOFT_RESET = self.SR = 0x03
|
|
78
|
+
self.ENABLE_RAPID_POWER_SHUTDOWN = self.ERPSD = 0x04
|
|
79
|
+
self.DISABLE_RAPID_POWER_SHUTDOWN = self.DRPSD = 0x05
|
|
80
|
+
# security_access
|
|
81
|
+
self.REQUEST_SEED = self.RSD = 0x01
|
|
82
|
+
self.SEND_KEY = self.SK = 0x02
|
|
83
|
+
# communication_control
|
|
84
|
+
self.ENABLE_RX_AND_TX = self.ERXTX = 0x00
|
|
85
|
+
self.ENABLE_RX_AND_DISABLE_TX = self.ERXDTX = 0x01
|
|
86
|
+
self.DISABLE_RX_AND_ENABLE_TX = self.DRXETX = 0x02
|
|
87
|
+
self.DISABLE_RX_AND_TX = self.DRXTX = 0x03
|
|
88
|
+
self.ENABLE_RX_AND_DISABLE_TX_WITH_ENHANCED_ADDRESS_INFORMATION = self.ERXDTXWEAI = 0x04
|
|
89
|
+
self.ENABLE_RX_AND_TX_WITH_ENHANCED_ADDRESS_INFORMATION = self.ERXTXWEAI = 0x05
|
|
90
|
+
# tester_present
|
|
91
|
+
self.ZERO_SUB_FUNCTION = self.ZSUBF = 0x00
|
|
92
|
+
self.ZERO_SUB_FUNCTION_SUPRESS_RESPONSE = 0x80
|
|
93
|
+
# access_timing_parameter
|
|
94
|
+
self.READ_EXTENDED_TIMING_PARAMETER_SET = self.RETPS = 0x01
|
|
95
|
+
self.SET_TIMING_PARAMETERS_TO_DEFAULT_VALUE = self.STPTDV = 0x02
|
|
96
|
+
self.READ_CURRENTLY_ACTIVE_TIMING_PARAMETERS = self.RCATP = 0x03
|
|
97
|
+
self.SET_TIMING_PARAMETERS_TO_GIVEN_VALUES = self.STPTGV = 0x04
|
|
98
|
+
# control_dtc_setting
|
|
99
|
+
self.ON = self.ON = 0x01
|
|
100
|
+
self.OFF = self.OFF = 0x02
|
|
101
|
+
# response_on_event
|
|
102
|
+
self.DO_NOT_STORE_EVENT = self.DNSE = 0x00
|
|
103
|
+
self.STORE_EVENT = self.SE = 0x01
|
|
104
|
+
self.STOP_RESPONSE_ON_EVENT = self.STPROE = 0x00
|
|
105
|
+
self.ON_DTC_STATUS_CHANGE = self.ONDTCS = 0x01
|
|
106
|
+
self.ON_TIMER_INTERRUPT = self.OTI = 0x02
|
|
107
|
+
self.ON_CHANGE_OF_DATA_IDENTIFIER = self.OCODID = 0x03
|
|
108
|
+
self.REPORT_ACTIVATED_EVENTS = self.RAE = 0x04
|
|
109
|
+
self.START_RESPONSE_ON_EVENT = self.STRTROE = 0x05
|
|
110
|
+
self.CLEAR_RESPONSE_ON_EVENT = self.CLRROE = 0x06
|
|
111
|
+
self.ON_COMPARISON_OF_VALUE = self.OCOV = 0x07
|
|
112
|
+
# link_control
|
|
113
|
+
self.VERIFY_MODE_TRANSITION_WITH_FIXED_PARAMETER = self.VMTWFP = 0x01
|
|
114
|
+
self.VERIFY_MODE_TRANSITION_WITH_SPECIFIC_PARAMETER = self.VMTWSP = 0x02
|
|
115
|
+
self.TRANSITION_MODE = self.TM = 0x03
|
|
116
|
+
# dynamically_define_data_identifier
|
|
117
|
+
self.DEFINE_BY_IDENTIFIER = self.DBID = 0x01
|
|
118
|
+
self.DEFINE_BY_MEMORY_ADDRESS = self.DBMA = 0x02
|
|
119
|
+
self.CLEAR_DYNAMICALLY_DEFINED_DATA_IDENTIFIER = self.CDDDID = 0x03
|
|
120
|
+
# read_dtc_information
|
|
121
|
+
self.REPORT_NUMBER_OF_DTC_BY_STATUS_MASK = self.RNODTCBSM = 0x01
|
|
122
|
+
self.REPORT_DTC_BY_STATUS_MASK = self.RDTCBSM = 0x02
|
|
123
|
+
self.REPORT_DTC_SNAPSHOT_IDENTIFICATION = self.RDTCSSI = 0x03
|
|
124
|
+
self.REPORT_DTC_SNAPSHOT_RECORD_BY_DTC_NUMBER = self.RDTCSSBDTC = 0x04
|
|
125
|
+
self.READ_DTC_STORED_DATA_BY_RECORD_NUMBER = self.RDTCSDBRN = 0x05
|
|
126
|
+
self.REPORT_DTC_EXT_DATA_RECORD_BY_DTC_NUMBER = self.RDTCEDRBDN = 0x06
|
|
127
|
+
self.REPORT_NUMBER_OF_DTC_BY_SEVERITY_MASK_RECORD = self.RNODTCBSMR = 0x07
|
|
128
|
+
self.REPORT_DTC_BY_SEVERITY_MASK_RECORD = self.RDTCBSMR = 0x08
|
|
129
|
+
self.REPORT_SEVERITY_INFORMATION_OF_DTC = self.RSIODTC = 0x09
|
|
130
|
+
self.REPORT_MIRROR_MEMORY_DTC_EXT_DATA_RECORD_BY_DTC_NUMBER = self.RMDEDRBDN = 0x10
|
|
131
|
+
self.REPORT_SUPPORTED_DTC = self.RSUPDTC = 0x0A
|
|
132
|
+
self.REPORT_FIRST_TEST_FAILED_DTC = self.RFTFDTC = 0x0B
|
|
133
|
+
self.REPORT_FIRST_CONFIRMED_DTC = self.RFCDTC = 0x0C
|
|
134
|
+
self.REPORT_MOST_RECENT_TEST_FAILED_DTC = self.RMRTFDTC = 0x0D
|
|
135
|
+
self.REPORT_MOST_RECENT_CONFIRMED_DTC = self.RMRCDTC = 0x0E
|
|
136
|
+
self.REPORT_MIRROR_MEMORY_DTC_BY_STATUS_MASK = self.RMMDTCBSM = 0x0F
|
|
137
|
+
self.REPORT_NUMBER_OF_MIRROR_MEMORY_DTC_BY_STATUS_MASK = self.RNOMMDTCBSM = 0x11
|
|
138
|
+
self.REPORT_NUMBER_OF_EMISSION_OBD_DTC_BY_STATUS_MASK = self.RNOOEBDDTCBSM = 0x12
|
|
139
|
+
self.REPORT_EMISSION_OBD_DTC_BY_STATUS_MASK = self.ROBDDTCBSM = 0x13
|
|
140
|
+
self.REPORT_DTC_FAULT_DETECTION_COUNTER = self.RDTCFDC = 0x14
|
|
141
|
+
self.REPORT_DTC_WITH_PERMANENT_STATUS = self.RDTCWPS = 0x15
|
|
142
|
+
self.REPORT_DTC_EXT_DATA_RECORD_BY_RECORD_NUMBER = self.RDTCEDRBR = 0x16
|
|
143
|
+
self.REPORT_USER_DEF_MEMORY_DTC_BY_STATUS_MASK = self.RUDMDTCBSM = 0x17
|
|
144
|
+
self.REPORT_USER_DEF_MEMORY_DTC_SNAPSHOT_RECORD_BY_DTC_NUMBER = self.RUDMDTCSSBDTC = 0x18
|
|
145
|
+
self.REPORT_USER_DEF_MEMORY_DTC_EXT_DATA_RECORD_BY_DTC_NUMBER = self.RUDMDTCEDRBDN = 0x19
|
|
146
|
+
self.REPORT_WWH_OBD_DTC_BY_MASK_RECORD = self.ROBDDTCBMR = 0x42
|
|
147
|
+
self.REPORT_WWH_OBD_DTC_WITH_PERMANENT_STATUS = self.RWWHOBDDTCWPS = 0x55
|
|
148
|
+
self.START_ROUTINE = self.STR = 0x01
|
|
149
|
+
self.STOP_ROUTINE = self.STPR = 0x02
|
|
150
|
+
self.REQUEST_ROUTINE_RESULT = self.RRR = 0x03
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class Nrc:
|
|
154
|
+
"""Negative Response Codes (NRCs) for UDS.
|
|
155
|
+
|
|
156
|
+
This class contains constants for all negative response codes as defined
|
|
157
|
+
in the ISO 14229 standard. Each NRC has a long name and a short alias.
|
|
158
|
+
|
|
159
|
+
See Also:
|
|
160
|
+
ISO 14229
|
|
161
|
+
"""
|
|
162
|
+
def __init__(self) -> None:
|
|
163
|
+
self.GENERAL_REJECT = self.GR = 0x10
|
|
164
|
+
self.SERVICE_NOT_SUPPORTED = self.SNS = 0x11
|
|
165
|
+
self.SUB_FUNCTION_NOT_SUPPORTED = self.SFNS = 0x12
|
|
166
|
+
self.INCORRECT_MESSAGE_LENGTH_OR_INVALID_FORMAT = self.IMLOIF = 0x13
|
|
167
|
+
self.RESPONSE_TOO_LONG = self.RTL = 0x14
|
|
168
|
+
self.BUSY_REPEAT_REQUEST = self.BRR = 0x21
|
|
169
|
+
self.CONDITIONS_NOT_CORRECT = self.CNC = 0x22
|
|
170
|
+
self.REQUEST_SEQUENCE_ERROR = self.RSE = 0x24
|
|
171
|
+
self.NO_RESPONSE_FROM_SUBNET_COMPONENT = self.NRFSC = 0x25
|
|
172
|
+
self.FAILURE_PREVENTS_EXECUTION_OF_REQUESTED_ACTION = self.FPEORA = 0x26
|
|
173
|
+
self.REQUEST_OUT_OF_RANGE = self.ROOR = 0x31
|
|
174
|
+
self.SECURITY_ACCESS_DENIED = self.SAD = 0x33
|
|
175
|
+
self.INVALID_KEY = self.IK = 0x35
|
|
176
|
+
self.EXCEEDED_NUMBER_OF_ATTEMPTS = self.ENOA = 0x36
|
|
177
|
+
self.REQUIRED_TIME_DELAY_NOT_EXPIRED = self.RTDNE = 0x37
|
|
178
|
+
self.UPLOAD_DOWNLOAD_NOT_ACCEPTED = self.UDNA = 0x70
|
|
179
|
+
self.TRANSFER_DATA_SUSPENDED = self.TDS = 0x71
|
|
180
|
+
self.GENERAL_PROGRAMMING_FAILURE = self.GPF = 0x72
|
|
181
|
+
self.WRONG_BLOCK_SEQUENCE_COUNTER = self.WBSC = 0x73
|
|
182
|
+
self.REQUEST_CORRECTLY_RECEIVED_RESPONSE_PENDING = self.RCRRP = 0x78
|
|
183
|
+
self.SUB_FUNCTION_NOT_SUPPORTED_IN_ACTIVE_SESSION = self.SFNSIAS = 0x7E
|
|
184
|
+
self.SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION = self.SNSIAS = 0x7F
|
|
185
|
+
self.RPM_TOO_HIGH = self.RPMTH = 0x81
|
|
186
|
+
self.RPM_TOO_LOW = self.RPMTL = 0x82
|
|
187
|
+
self.ENGINE_IS_RUNNING = self.EIR = 0x83
|
|
188
|
+
self.ENGINE_IS_NOT_RUNNING = self.EINR = 0x84
|
|
189
|
+
self.ENGINE_RUN_TIME_TOO_LOW = self.ERTTL = 0x85
|
|
190
|
+
self.TEMPERATURE_TOO_HIGH = self.TEMPTH = 0x86
|
|
191
|
+
self.TEMPERATURE_TOO_LOW = self.TEMPTL = 0x87
|
|
192
|
+
self.VEHICLE_SPEED_TOO_HIGH = self.VSTH = 0x88
|
|
193
|
+
self.VEHICLE_SPEED_TOO_LOW = self.VSTL = 0x89
|
|
194
|
+
self.THROTTLE_OR_PEDAL_TOO_HIGH = self.TPTH = 0x8A
|
|
195
|
+
self.THROTTLE_OR_PEDAL_TOO_LOW = self.TPTL = 0x8B
|
|
196
|
+
self.TRANSMISSION_RANGE_NOT_IN_NEUTRAL = self.TRNIN = 0x8C
|
|
197
|
+
self.TRANSMISSION_RANGE_NOT_IN_GEAR = self.TRNIG = 0x8D
|
|
198
|
+
self.BRAKE_SWITCH_NOT_CLOSED = self.BSNC = 0x8F
|
|
199
|
+
self.SHIFTER_LEVER_NOT_IN_PARK = self.SLNIP = 0x90
|
|
200
|
+
self.TORQUE_CONVERTER_CLUTCH_LOCKED = self.TCCL = 0x91
|
|
201
|
+
self.VOLTAGE_TOO_HIGH = self.VTH = 0x92
|
|
202
|
+
self.VOLTAGE_TOO_LOW = self.VTL = 0x93
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class Did:
|
|
206
|
+
"""Diagnostic Identifiers (DIDs) for UDS.
|
|
207
|
+
|
|
208
|
+
This class contains constants for various diagnostic identifiers.
|
|
209
|
+
"""
|
|
210
|
+
def __init__(self) -> None:
|
|
211
|
+
self.VEHICLE_IDENTIFICATION_NUMBER = 0xF190
|
|
212
|
+
self.MANUFACTURER_SPARE_PART_NUMBER = 0xF187
|
|
213
|
+
self.MANUFACTURER_ECU_SOFTWARE_NUMBER = 0xF188
|
|
214
|
+
self.MANUFACTURER_ECU_SOFTWARE_VERSION = 0xF189
|
|
215
|
+
self.ECU_MANUFACTURING_DATE = 0xF18B
|
|
216
|
+
self.ECU_SERIAL_NUMBER = 0xF18C
|
|
217
|
+
self.SUPPORTED_FUNCTIONAL_UNITS = 0xF18D
|
|
218
|
+
self.SYSTEM_SUPPLIER_ECU_SOFTWARE_NUMBER = 0xF194
|
|
219
|
+
self.SYSTEM_SUPPLIER_ECU_SOFTWARE_VERSION = 0xF195
|
|
220
|
+
self.PROGRAMMING_DATE = 0xF199
|
|
221
|
+
self.REPAIR_SHOP_CODE = 0xF198
|
|
222
|
+
self.EXHAUST_REGULATION_TYPE_APPROVAL_NUMBER = 0xF196
|
|
223
|
+
self.INSTALLATION_DATE = 0xF19D
|
|
224
|
+
self.ACTIVE_DIAGNOSTIC_SESSION = 0xFF01
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class Memory:
|
|
228
|
+
"""A simulated memory map for the UDS server.
|
|
229
|
+
|
|
230
|
+
This class holds memory addresses, their corresponding values, and other
|
|
231
|
+
data like DTCs and writable DIDs.
|
|
232
|
+
|
|
233
|
+
Attributes:
|
|
234
|
+
writable_dids (list): A list of DIDs that are writable.
|
|
235
|
+
did_data (dict): A dictionary to store data for DIDs.
|
|
236
|
+
memory_map (dict): A dictionary representing the memory layout.
|
|
237
|
+
dtcs (list): A list of Diagnostic Trouble Codes.
|
|
238
|
+
"""
|
|
239
|
+
def __init__(self) -> None:
|
|
240
|
+
self.writable_dids = [0xF198, 0xF199] # Example: Repair Shop Code and Programming Date
|
|
241
|
+
self.did_data = {}
|
|
242
|
+
self.memory_map = {
|
|
243
|
+
0x1000: [0x11, 0x22, 0x33, 0x44],
|
|
244
|
+
0x2000: [0xAA, 0xBB, 0xCC, 0xDD],
|
|
245
|
+
}
|
|
246
|
+
self.dtcs = [
|
|
247
|
+
[0x9A, 0x01, 0x01], # Example DTC 1
|
|
248
|
+
[0x9A, 0x02, 0x01], # Example DTC 2
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
@property
|
|
252
|
+
def vehicle_identification_number(self):
|
|
253
|
+
"""The vehicle identification number (VIN)."""
|
|
254
|
+
return split_integer_to_bytes(0x1234567890)
|
|
255
|
+
|
|
256
|
+
@property
|
|
257
|
+
def manufacturer_spare_part_number(self):
|
|
258
|
+
"""The manufacturer's spare part number."""
|
|
259
|
+
return split_integer_to_bytes(0x1111111111)
|
|
260
|
+
|
|
261
|
+
@property
|
|
262
|
+
def manufacturer_ecu_software_number(self):
|
|
263
|
+
"""The manufacturer's ECU software number."""
|
|
264
|
+
return split_integer_to_bytes(0x20250801)
|
|
265
|
+
|
|
266
|
+
@property
|
|
267
|
+
def manufacturer_ecu_software_version(self):
|
|
268
|
+
"""The manufacturer's ECU software version."""
|
|
269
|
+
return split_integer_to_bytes(0x202508010203)
|
|
270
|
+
|
|
271
|
+
@property
|
|
272
|
+
def ecu_manufacturing_date(self):
|
|
273
|
+
"""The ECU manufacturing date."""
|
|
274
|
+
return split_integer_to_bytes(0x20250801)
|
|
275
|
+
|
|
276
|
+
@property
|
|
277
|
+
def ecu_serial_number(self):
|
|
278
|
+
"""The ECU serial number."""
|
|
279
|
+
return split_integer_to_bytes(0x1234567890)
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def supported_functional_units(self):
|
|
283
|
+
"""The supported functional units."""
|
|
284
|
+
return split_integer_to_bytes(0x00000001)
|
|
285
|
+
|
|
286
|
+
@property
|
|
287
|
+
def system_supplier_ecu_software_number(self):
|
|
288
|
+
"""The system supplier's ECU software number."""
|
|
289
|
+
return split_integer_to_bytes(0x20250801)
|
|
290
|
+
|
|
291
|
+
@property
|
|
292
|
+
def system_supplier_ecu_software_version(self):
|
|
293
|
+
"""The system supplier's ECU software version."""
|
|
294
|
+
return split_integer_to_bytes(0x202508010203)
|
|
295
|
+
|
|
296
|
+
@property
|
|
297
|
+
def programming_date(self):
|
|
298
|
+
"""The programming date."""
|
|
299
|
+
return split_integer_to_bytes(0x20250801)
|
|
300
|
+
|
|
301
|
+
@property
|
|
302
|
+
def repair_shop_code(self):
|
|
303
|
+
"""The repair shop code."""
|
|
304
|
+
return split_integer_to_bytes(0x123456)
|
|
305
|
+
|
|
306
|
+
@property
|
|
307
|
+
def exhaust_regulation_type_approval_number(self):
|
|
308
|
+
"""The exhaust regulation type approval number."""
|
|
309
|
+
return split_integer_to_bytes(0x123456)
|
|
310
|
+
|
|
311
|
+
@property
|
|
312
|
+
def ecu_installation_date(self):
|
|
313
|
+
"""The ECU installation date."""
|
|
314
|
+
return split_integer_to_bytes(0x20250801)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
class PositiveResponse:
|
|
2
|
+
"""Handles the creation of positive UDS responses."""
|
|
3
|
+
|
|
4
|
+
def __init__(self) -> None:
|
|
5
|
+
"""Initializes the PositiveResponse handler."""
|
|
6
|
+
pass
|
|
7
|
+
|
|
8
|
+
def report_positive_response(self, sid: int, data: list) -> list:
|
|
9
|
+
"""Constructs a positive response message.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
sid: The service identifier of the request.
|
|
13
|
+
data: A list of integers representing the response data.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
A list of integers representing the complete positive response
|
|
17
|
+
message, including the positive response SID.
|
|
18
|
+
"""
|
|
19
|
+
return [sid + 0x40] + data
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class NegativeResponse:
|
|
23
|
+
"""Handles the creation of negative UDS responses."""
|
|
24
|
+
|
|
25
|
+
def __init__(self) -> None:
|
|
26
|
+
"""Initializes the NegativeResponse handler."""
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
def report_negative_response(self, sid: int, nrc: int) -> list:
|
|
30
|
+
"""Constructs a negative response message.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
sid: The service identifier of the request.
|
|
34
|
+
nrc: The negative response code.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
A list of integers representing the complete negative response
|
|
38
|
+
message.
|
|
39
|
+
"""
|
|
40
|
+
return [0x7F, sid, nrc]
|
|
41
|
+
|
|
42
|
+
def check_subfunction_supported(
|
|
43
|
+
self, sfid: int, supported_subfunctions: list
|
|
44
|
+
) -> bool:
|
|
45
|
+
"""Checks if a sub-function is supported.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
sfid: The sub-function identifier to check.
|
|
49
|
+
supported_subfunctions: A list of supported sub-function
|
|
50
|
+
identifiers.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
True if the sub-function is supported, False otherwise.
|
|
54
|
+
"""
|
|
55
|
+
return sfid in supported_subfunctions
|
|
File without changes
|