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.
@@ -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