Skip to content

Commit 1be15ea

Browse files
committedOct 15, 2019
custom errors from thread
1 parent 68da831 commit 1be15ea

File tree

1 file changed

+37
-30
lines changed

1 file changed

+37
-30
lines changed
 

‎python/uds.py

+37-30
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,8 @@ def __init__(self, panda, tx_addr, rx_addr=None, bus=0, timeout=10, debug=False)
286286

287287
def _isotp_thread(self, debug):
288288
try:
289-
rx_frame = {"size": 0, "data": "", "idx": 0, "done": True}
290-
tx_frame = {"size": 0, "data": "", "idx": 0, "done": True}
289+
rx_frame = {"size": 0, "data": b"", "idx": 0, "done": True}
290+
tx_frame = {"size": 0, "data": b"", "idx": 0, "done": True}
291291

292292
# allow all output
293293
self.panda.set_safety_mode(0x1337)
@@ -333,9 +333,16 @@ def _isotp_thread(self, debug):
333333
self.rx_queue.put(rx_frame["data"])
334334
elif rx_data[0] >> 4 == 0x3:
335335
# flow control
336-
assert tx_frame["done"] == False, "tx: no active frame"
337-
# TODO: support wait/overflow
338-
assert rx_data[0] == 0x30, "tx: flow-control requires: continue"
336+
if tx_frame["done"] != False:
337+
tx_frame["done"] = True
338+
self.rx_queue.put(b"\x7F\xFF\xFFtx: no active frame")
339+
# TODO: support wait
340+
if rx_data[0] == 0x31:
341+
tx_frame["done"] = True
342+
self.rx_queue.put(b"\x7F\xFF\xFFtx: flow-control error - wait not supported")
343+
if rx_data[0] == 0x32:
344+
tx_frame["done"] = True
345+
self.rx_queue.put(b"\x7F\xFF\xFFtx: flow-control error - overflow/abort")
339346
delay_ts = rx_data[2] & 0x7F
340347
# scale is 1 milliseconds if first bit == 0, 100 micro seconds if first bit == 1
341348
delay_div = 1000. if rx_data[2] & 0x80 == 0 else 10000.
@@ -346,7 +353,7 @@ def _isotp_thread(self, debug):
346353
for i in range(start, end, 7):
347354
tx_frame["idx"] += 1
348355
# consecutive tx frames
349-
msg = (chr(0x20 | (tx_frame["idx"] & 0xF)).encode("utf8") + tx_frame["data"][i:i+7]).ljust(8, b"\x00")
356+
msg = (chr(0x20 | (tx_frame["idx"] & 0xF)).encode() + tx_frame["data"][i:i+7]).ljust(8, b"\x00")
350357
if (debug): print("S: {} {}".format(hex(self.tx_addr), hexlify(msg)))
351358
self.panda.can_send(self.tx_addr, msg, self.bus)
352359
if delay_ts > 0:
@@ -357,12 +364,12 @@ def _isotp_thread(self, debug):
357364
if not self.tx_queue.empty():
358365
req = self.tx_queue.get(block=False)
359366
# reset rx and tx frames
360-
rx_frame = {"size": 0, "data": "", "idx": 0, "done": True}
367+
rx_frame = {"size": 0, "data": b"", "idx": 0, "done": True}
361368
tx_frame = {"size": len(req), "data": req, "idx": 0, "done": False}
362369
if tx_frame["size"] < 8:
363370
# single frame
364371
tx_frame["done"] = True
365-
msg = (chr(tx_frame["size"]).encode("utf8") + tx_frame["data"]).ljust(8, b"\x00")
372+
msg = (chr(tx_frame["size"]).encode() + tx_frame["data"]).ljust(8, b"\x00")
366373
if (debug): print("S: {} {}".format(hex(self.tx_addr), hexlify(msg)))
367374
self.panda.can_send(self.tx_addr, msg, self.bus)
368375
else:
@@ -379,9 +386,9 @@ def _isotp_thread(self, debug):
379386

380387
# generic uds request
381388
def _uds_request(self, service_type, subfunction=None, data=None):
382-
req = chr(service_type).encode("utf8")
389+
req = chr(service_type).encode()
383390
if subfunction is not None:
384-
req += chr(subfunction).encode("utf8")
391+
req += chr(subfunction).encode()
385392
if data is not None:
386393
req += data
387394
self.tx_queue.put(req)
@@ -407,7 +414,7 @@ def _uds_request(self, service_type, subfunction=None, data=None):
407414
try:
408415
error_desc = _negative_response_codes[error_code]
409416
except Exception:
410-
error_desc = 'unknown error'
417+
error_desc = resp[3:]
411418
# wait for another message if response pending
412419
if error_code == 0x78:
413420
time.sleep(0.1)
@@ -452,7 +459,7 @@ def security_access(self, access_type, security_key=None):
452459
return security_seed
453460

454461
def communication_control(self, control_type, message_type):
455-
data = chr(message_type).encode("utf8")
462+
data = chr(message_type).encode()
456463
self._uds_request(SERVICE_TYPE.COMMUNICATION_CONTROL, subfunction=control_type, data=data)
457464

458465
def tester_present(self, ):
@@ -505,7 +512,7 @@ def response_on_event(self, response_event_type, store_event, window_time, event
505512
def link_control(self, link_control_type, baud_rate_type=None):
506513
if link_control_type == LINK_CONTROL_TYPE.VERIFY_BAUDRATE_TRANSITION_WITH_FIXED_BAUDRATE:
507514
# baud_rate_type = BAUD_RATE_TYPE
508-
data = chr(baud_rate_type).encode("utf8")
515+
data = chr(baud_rate_type).encode()
509516
elif link_control_type == LINK_CONTROL_TYPE.VERIFY_BAUDRATE_TRANSITION_WITH_SPECIFIC_BAUDRATE:
510517
# baud_rate_type = custom value (3 bytes big-endian)
511518
data = struct.pack('!I', baud_rate_type)[1:]
@@ -527,7 +534,7 @@ def read_memory_by_address(self, memory_address, memory_size, memory_address_byt
527534
raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes))
528535
if memory_size_bytes < 1 or memory_size_bytes > 4:
529536
raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes))
530-
data = chr(memory_size_bytes<<4 | memory_address_bytes).encode("utf8")
537+
data = chr(memory_size_bytes<<4 | memory_address_bytes).encode()
531538

532539
if memory_address >= 1<<(memory_address_bytes*8):
533540
raise ValueError('invalid memory_address: {}'.format(memory_address))
@@ -549,7 +556,7 @@ def read_scaling_data_by_identifier(self, data_identifier_type):
549556

550557
def read_data_by_periodic_identifier(self, transmission_mode_type, periodic_data_identifier):
551558
# TODO: support list of identifiers
552-
data = chr(transmission_mode_type).encode("utf8") + chr(periodic_data_identifier).encode("utf8")
559+
data = chr(transmission_mode_type).encode() + chr(periodic_data_identifier).encode()
553560
self._uds_request(SERVICE_TYPE.READ_DATA_BY_PERIODIC_IDENTIFIER, subfunction=None, data=data)
554561

555562
def dynamically_define_data_identifier(self, dynamic_definition_type, dynamic_data_identifier, source_definitions, memory_address_bytes=4, memory_size_bytes=1):
@@ -561,9 +568,9 @@ def dynamically_define_data_identifier(self, dynamic_definition_type, dynamic_da
561568
data = struct.pack('!H', dynamic_data_identifier)
562569
if dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.DEFINE_BY_IDENTIFIER:
563570
for s in source_definitions:
564-
data += struct.pack('!H', s["data_identifier"]) + chr(s["position"]).encode("utf8") + chr(s["memory_size"]).encode("utf8")
571+
data += struct.pack('!H', s["data_identifier"]) + chr(s["position"]).encode() + chr(s["memory_size"]).encode()
565572
elif dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.DEFINE_BY_MEMORY_ADDRESS:
566-
data += chr(memory_size_bytes<<4 | memory_address_bytes).encode("utf8")
573+
data += chr(memory_size_bytes<<4 | memory_address_bytes).encode()
567574
for s in source_definitions:
568575
if s["memory_address"] >= 1<<(memory_address_bytes*8):
569576
raise ValueError('invalid memory_address: {}'.format(s["memory_address"]))
@@ -589,7 +596,7 @@ def write_memory_by_address(self, memory_address, memory_size, data_record, memo
589596
raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes))
590597
if memory_size_bytes < 1 or memory_size_bytes > 4:
591598
raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes))
592-
data = chr(memory_size_bytes<<4 | memory_address_bytes).encode("utf8")
599+
data = chr(memory_size_bytes<<4 | memory_address_bytes).encode()
593600

594601
if memory_address >= 1<<(memory_address_bytes*8):
595602
raise ValueError('invalid memory_address: {}'.format(memory_address))
@@ -606,15 +613,15 @@ def clear_diagnostic_information(self, dtc_group_type):
606613
self._uds_request(SERVICE_TYPE.CLEAR_DIAGNOSTIC_INFORMATION, subfunction=None, data=data)
607614

608615
def read_dtc_information(self, dtc_report_type, dtc_status_mask_type=DTC_STATUS_MASK_TYPE.ALL, dtc_severity_mask_type=DTC_SEVERITY_MASK_TYPE.ALL, dtc_mask_record=0xFFFFFF, dtc_snapshot_record_num=0xFF, dtc_extended_record_num=0xFF):
609-
data = ''
616+
data = b''
610617
# dtc_status_mask_type
611618
if dtc_report_type == DTC_REPORT_TYPE.NUMBER_OF_DTC_BY_STATUS_MASK or \
612619
dtc_report_type == DTC_REPORT_TYPE.DTC_BY_STATUS_MASK or \
613620
dtc_report_type == DTC_REPORT_TYPE.MIRROR_MEMORY_DTC_BY_STATUS_MASK or \
614621
dtc_report_type == DTC_REPORT_TYPE.NUMBER_OF_MIRROR_MEMORY_DTC_BY_STATUS_MASK or \
615622
dtc_report_type == DTC_REPORT_TYPE.NUMBER_OF_EMISSIONS_RELATED_OBD_DTC_BY_STATUS_MASK or \
616623
dtc_report_type == DTC_REPORT_TYPE.EMISSIONS_RELATED_OBD_DTC_BY_STATUS_MASK:
617-
data += chr(dtc_status_mask_type).encode("utf8")
624+
data += chr(dtc_status_mask_type).encode()
618625
# dtc_mask_record
619626
if dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_IDENTIFICATION or \
620627
dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_RECORD_BY_DTC_NUMBER or \
@@ -630,26 +637,26 @@ def read_dtc_information(self, dtc_report_type, dtc_status_mask_type=DTC_STATUS_
630637
# dtc_extended_record_num
631638
if dtc_report_type == DTC_REPORT_TYPE.DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER or \
632639
dtc_report_type == DTC_REPORT_TYPE.MIRROR_MEMORY_DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER:
633-
data += chr(dtc_extended_record_num).encode("utf8")
640+
data += chr(dtc_extended_record_num).encode()
634641
# dtc_severity_mask_type
635642
if dtc_report_type == DTC_REPORT_TYPE.NUMBER_OF_DTC_BY_SEVERITY_MASK_RECORD or \
636643
dtc_report_type == DTC_REPORT_TYPE.DTC_BY_SEVERITY_MASK_RECORD:
637-
data += chr(dtc_severity_mask_type).encode("utf8") + chr(dtc_status_mask_type).encode("utf8")
644+
data += chr(dtc_severity_mask_type).encode() + chr(dtc_status_mask_type).encode()
638645

639646
resp = self._uds_request(SERVICE_TYPE.READ_DTC_INFORMATION, subfunction=dtc_report_type, data=data)
640647

641648
# TODO: parse response
642649
return resp
643650

644-
def input_output_control_by_identifier(self, data_identifier_type, control_option_record, control_enable_mask_record=''):
651+
def input_output_control_by_identifier(self, data_identifier_type, control_option_record, control_enable_mask_record=b''):
645652
data = struct.pack('!H', data_identifier_type) + control_option_record + control_enable_mask_record
646653
resp = self._uds_request(SERVICE_TYPE.INPUT_OUTPUT_CONTROL_BY_IDENTIFIER, subfunction=None, data=data)
647654
resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None
648655
if resp_id != data_identifier_type:
649656
raise ValueError('invalid response data identifier: {}'.format(hex(resp_id)))
650657
return resp[2:]
651658

652-
def routine_control(self, routine_control_type, routine_identifier_type, routine_option_record=''):
659+
def routine_control(self, routine_control_type, routine_identifier_type, routine_option_record=b''):
653660
data = struct.pack('!H', routine_identifier_type) + routine_option_record
654661
resp = self._uds_request(SERVICE_TYPE.ROUTINE_CONTROL, subfunction=routine_control_type, data=data)
655662
resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None
@@ -658,13 +665,13 @@ def routine_control(self, routine_control_type, routine_identifier_type, routine
658665
return resp[2:]
659666

660667
def request_download(self, memory_address, memory_size, memory_address_bytes=4, memory_size_bytes=4, data_format=0x00):
661-
data = chr(data_format).encode("utf8")
668+
data = chr(data_format).encode()
662669

663670
if memory_address_bytes < 1 or memory_address_bytes > 4:
664671
raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes))
665672
if memory_size_bytes < 1 or memory_size_bytes > 4:
666673
raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes))
667-
data += chr(memory_size_bytes<<4 | memory_address_bytes).encode("utf8")
674+
data += chr(memory_size_bytes<<4 | memory_address_bytes).encode()
668675

669676
if memory_address >= 1<<(memory_address_bytes*8):
670677
raise ValueError('invalid memory_address: {}'.format(memory_address))
@@ -683,13 +690,13 @@ def request_download(self, memory_address, memory_size, memory_address_bytes=4,
683690
return max_num_bytes # max number of bytes per transfer data request
684691

685692
def request_upload(self, memory_address, memory_size, memory_address_bytes=4, memory_size_bytes=4, data_format=0x00):
686-
data = chr(data_format).encode("utf8")
693+
data = chr(data_format).encode()
687694

688695
if memory_address_bytes < 1 or memory_address_bytes > 4:
689696
raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes))
690697
if memory_size_bytes < 1 or memory_size_bytes > 4:
691698
raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes))
692-
data += chr(memory_size_bytes<<4 | memory_address_bytes).encode("utf8")
699+
data += chr(memory_size_bytes<<4 | memory_address_bytes).encode()
693700

694701
if memory_address >= 1<<(memory_address_bytes*8):
695702
raise ValueError('invalid memory_address: {}'.format(memory_address))
@@ -707,8 +714,8 @@ def request_upload(self, memory_address, memory_size, memory_address_bytes=4, me
707714

708715
return max_num_bytes # max number of bytes per transfer data request
709716

710-
def transfer_data(self, block_sequence_count, data=''):
711-
data = chr(block_sequence_count).encode("utf8") + data
717+
def transfer_data(self, block_sequence_count, data=b''):
718+
data = chr(block_sequence_count).encode() + data
712719
resp = self._uds_request(SERVICE_TYPE.TRANSFER_DATA, subfunction=None, data=data)
713720
resp_id = resp[0] if len(resp) > 0 else None
714721
if resp_id != block_sequence_count:

0 commit comments

Comments
 (0)