Skip to content

Commit 50e2a07

Browse files
author
PAVOT Christophe
committed
Make P2/P2* configurable by user
1 parent 63ae076 commit 50e2a07

File tree

1 file changed

+38
-19
lines changed

1 file changed

+38
-19
lines changed

udsoncan/client.py

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,17 @@ class Client:
2222
:param config: The :ref:`client configuration<client_config>`
2323
:type config: dict
2424
25-
:param request_timeout: Maximum amount of time to wait for a response after sending a request (in seconds). After this time is elapsed, a TimeoutException will be raised.
25+
:param request_timeout: Maximum amount of time in seconds to wait for the final response (positive or negative except NRC 0x78) after sending a request.
26+
After this time is elapsed, a TimeoutException will be raised. If less than or equal to p2_star, NRC 0x78 (requestCorrectlyReceived-ResponsePending) responses are not supported.
2627
:type request_timeout: int
28+
29+
:param p2_timeout: Maximum amount of time in seconds to wait for a response (positive, negative, or NRC 0x78). After this time is elapsed, a TimeoutException will be raised.
30+
See ISO 14229-2 (UDS Session Layer Services).
31+
:type p2_timeout: int
32+
33+
:param p2_star_timeout: Maximum amount of time in seconds to wait for a response (positive, negative, or NRC0x78) after the reception of a negative response with code 0x78
34+
(requestCorrectlyReceived-ResponsePending). After this time is elapsed, a TimeoutException will be raised. See ISO 14229-2 (UDS Session Layer Services).
35+
:type p2_star_timeout: int
2736
"""
2837

2938
class SuppressPositiveResponse:
@@ -37,9 +46,11 @@ def __enter__(self):
3746
def __exit__(self, type, value, traceback):
3847
self.enabled = False
3948

40-
def __init__(self, conn, config=default_client_config, request_timeout = 1):
49+
def __init__(self, conn, config=default_client_config, request_timeout=5, p2_timeout=1, p2_star_timeout=5):
4150
self.conn = conn
4251
self.request_timeout = request_timeout
52+
self.p2_timeout = p2_timeout
53+
self.p2_star_timeout = p2_star_timeout
4354
self.config = dict(config) # Makes a copy of given configuration
4455
self.suppress_positive_response = Client.SuppressPositiveResponse()
4556
self.last_response = None
@@ -1409,13 +1420,19 @@ def read_dtc_information(self, subfunction, status_mask=None, severity_mask=None
14091420

14101421
# Basic transmission of requests. This will need to be improved
14111422
def send_request(self, request, timeout=-1):
1412-
# P2 server max and P2* server max are usually resp. 50ms and 5000ms. However, P2 server max is set to a lax value of 1000ms
1413-
# to avoid a timeout due to Python setup increased latencies.
1414-
p2_server_max = 1
1415-
p2_star_server_max = 5
1423+
if timeout < 0:
1424+
# Timeout not provided by user: defaults to Client request_timeout value
1425+
overall_timeout = self.request_timeout
1426+
else:
1427+
overall_timeout = timeout
14161428

1417-
if timeout is not None and timeout < 0:
1418-
timeout = self.request_timeout
1429+
if overall_timeout > self.p2_star_timeout:
1430+
current_timeout = self.p2_timeout
1431+
response_pending_supported = True
1432+
else:
1433+
# NRC 0x78 (RequestCorrectlyReceived_ResponsePending) not supported
1434+
current_timeout = overall_timeout
1435+
response_pending_supported = False
14191436

14201437
self.conn.empty_rxqueue()
14211438
self.logger.debug("Sending request to server")
@@ -1436,23 +1453,22 @@ def send_request(self, request, timeout=-1):
14361453

14371454
done_receiving = False
14381455

1439-
if timeout is not None:
1440-
timeout_time = time.time() + timeout
1456+
if response_pending_supported:
1457+
overall_timeout_time = time.time() + overall_timeout
14411458
else:
1442-
timeout_time = None
1459+
overall_timeout_time = None
14431460

1444-
current_timeout = p2_server_max
14451461
while not done_receiving:
14461462
done_receiving = True
14471463
self.logger.debug("Waiting for server response")
14481464
try:
14491465
payload = self.conn.wait_frame(timeout=current_timeout, exception=True)
14501466
except TimeoutException:
1451-
raise TimeoutException('Did not receive response in time (request timeout=%.3f sec)' % current_timeout)
1467+
raise TimeoutException('Did not receive response in time (timeout=%.3f sec)' % current_timeout)
14521468
except Exception as e:
14531469
raise e
1454-
if timeout_time is not None and timeout_time - time.time() < 0:
1455-
raise TimeoutException('Did not receive response in time (overall timeout=%.3f sec)' % timeout)
1470+
if overall_timeout_time is not None and overall_timeout_time - time.time() < 0:
1471+
raise TimeoutException('Did not receive final response in time (request timeout=%.3f sec)' % overall_timeout)
14561472

14571473
response = Response.from_payload(payload)
14581474
self.last_response = response
@@ -1470,10 +1486,13 @@ def send_request(self, request, timeout=-1):
14701486
self.logger.warning('Given response code "%s" (0x%02x) is not a supported negative response code according to UDS standard.' % (response.code_name, response.code))
14711487

14721488
if response.code == Response.Code.RequestCorrectlyReceived_ResponsePending:
1473-
# Received a 0x78 NRC: timeout is now set to P2* server max
1474-
current_timeout = p2_star_server_max
1475-
done_receiving = False
1476-
self.logger.debug("Server requested to wait with response code %s (0x%02x), timeout is now set to %.3f seconds" % (response.code_name, response.code, current_timeout))
1489+
if response_pending_supported:
1490+
# Received a 0x78 NRC: timeout is now set to P2*
1491+
current_timeout = self.p2_star_timeout
1492+
done_receiving = False
1493+
self.logger.debug("Server requested to wait with response code %s (0x%02x), timeout is now set to %.3f seconds" % (response.code_name, response.code, current_timeout))
1494+
else:
1495+
raise NegativeResponseException(response, "RequestCorrectlyReceived_ResponsePending not supported")
14771496
else:
14781497
raise NegativeResponseException(response)
14791498

0 commit comments

Comments
 (0)