Skip to content

Commit 5b0acb9

Browse files
authored
Add getter for timings (#265)
* Added getter for session timings
1 parent 9fb5c6a commit 5b0acb9

File tree

3 files changed

+52
-11
lines changed

3 files changed

+52
-11
lines changed

doc/source/udsoncan/client.rst

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,18 @@ See :ref:`an example <example_security_algo>`
242242
.. attribute:: use_server_timing
243243
:annotation: (bool)
244244

245-
When using 2013 standard or above, the server is required to provide its P2 and P2* timing values with a DiagnosticSessionControl request. By setting this parameter to ``True``, the value received from the server will be used. When ``False``, these timing values will be ignored and local configuration timing will be used. Note that no timeout value can exceed the ``config['request_timeout']`` as it is meant to avoid the client from hanging for too long.
245+
When using 2013 standard or above, the server is required to provide its P2 and P2* timing values with a DiagnosticSessionControl request.
246+
By setting this parameter to ``True``, the value received from the server will be used. When ``False``, these timing values will be ignored and local configuration timing will be used.
247+
Note that no timeout value can exceed the ``config['request_timeout']`` as it is meant to avoid the client from hanging for too long.
246248

247249
This parameter has no effect when ``config['standard_version']`` is set to ``2006``.
248250

249251
Default value is True
250252

253+
.. note::
254+
255+
The timeouts provided by the server can be obtained via :meth:`get_session_timing<Client.get_session_timing>`
256+
251257

252258
.. _config_nrc78_callback:
253259

@@ -320,6 +326,24 @@ When using that feature, the client will process the response from the server ju
320326

321327
-----
322328

329+
Session timings
330+
---------------
331+
332+
When a request is performed, the client uses the P2 & P2* timeouts value provided by the server in a response to :meth:`change_session<udsoncan.client.Client.change_session>`.
333+
If :meth:`change_session<udsoncan.client.Client.change_session>` is not called yet (or if the standard used is 2006), the values from the configuration will be used : :ref:`p2_timeout<config_p2_timeout>` & :ref:`p2_star_timeout<config_p2_star_timeout>`
334+
335+
The client can provide the received P2 & P2* timeouts value via :meth:`get_session_timing<udsoncan.client.Client.get_session_timing>`
336+
337+
.. automethod:: udsoncan.client.Client.get_session_timing
338+
339+
.. autoclass:: udsoncan.client.SessionTiming
340+
:exclude-members: __init__, __new__
341+
:members:
342+
343+
344+
-----
345+
346+
323347
Methods by services
324348
-------------------
325349

test/client/test_diagnostic_session_control.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ def _test_dsc_success_2013_plus(self):
3434
self.assertEqual(response.service_data.session_param_records, b"\x99\x88\x12\x34")
3535
self.assertEqual(response.service_data.p2_server_max, (0x9988) / 1000)
3636
self.assertEqual(response.service_data.p2_star_server_max, 0x1234 * 10 / 1000)
37-
self.assertEqual(self.udsclient.session_timing['p2_server_max'], response.service_data.p2_server_max)
38-
self.assertEqual(self.udsclient.session_timing['p2_star_server_max'], response.service_data.p2_star_server_max)
37+
self.assertEqual(self.udsclient.get_session_timing().p2_server_max, response.service_data.p2_server_max)
38+
self.assertEqual(self.udsclient.get_session_timing().p2_star_server_max, response.service_data.p2_star_server_max)
3939

4040
def test_dsc_success_2013_plus_ignore_server_timing(self):
4141
request = self.conn.touserqueue.get(timeout=0.2)
@@ -50,8 +50,8 @@ def _test_dsc_success_2013_plus_ignore_server_timing(self):
5050
self.assertEqual(response.service_data.session_param_records, b"\x99\x88\x12\x34")
5151
self.assertEqual(response.service_data.p2_server_max, 0x9988 / 1000)
5252
self.assertEqual(response.service_data.p2_star_server_max, 0x1234 * 10 / 1000)
53-
self.assertIsNone(self.udsclient.session_timing['p2_server_max'])
54-
self.assertIsNone(self.udsclient.session_timing['p2_star_server_max'])
53+
self.assertIsNone(self.udsclient.get_session_timing().p2_server_max)
54+
self.assertIsNone(self.udsclient.get_session_timing().p2_star_server_max)
5555

5656
def test_dsc_success_spr(self):
5757
request = self.conn.touserqueue.get(timeout=0.2)

udsoncan/client.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,17 @@
2323
from typing import Callable, Optional, Union, Dict, List, Any, cast, Type
2424

2525

26-
class SessionTiming(TypedDict):
26+
class SessionTiming:
27+
"""Container for server provided P2 & P2* timeouts."""
28+
2729
p2_server_max: Optional[float]
30+
"""P2 server max provided by the server. ``None`` if not provided yet """
2831
p2_star_server_max: Optional[float]
32+
"""P2* server max provided by the server. ``None`` if not provided yet """
33+
34+
def __init__(self, p2_server_max:Optional[float]=None, p2_star_server_max:Optional[float]=None) -> None:
35+
self.p2_server_max = p2_server_max
36+
self.p2_star_server_max = p2_star_server_max
2937

3038

3139
class Client:
@@ -111,7 +119,7 @@ def __init__(self, conn: BaseConnection, config: ClientConfig = default_client_c
111119
self.payload_override = Client.PayloadOverrider()
112120
self.last_response = None
113121

114-
self.session_timing = cast(SessionTiming, dict(p2_server_max=None, p2_star_server_max=None)) # python 3.7 cast
122+
self.session_timing = SessionTiming(p2_server_max=None, p2_star_server_max=None)
115123

116124
self.refresh_config()
117125

@@ -204,6 +212,15 @@ def decorated(self: "Client", *args, **kwargs):
204212
def service_log_prefix(self, service: Type[BaseService]):
205213
return "%s<0x%02x>" % (service.get_name(), service.request_id())
206214

215+
def get_session_timing(self) -> SessionTiming:
216+
"""Return the session timing provided by the server, including P2 & P2* timeouts.
217+
If the timeout values are ``None``, it means that no timing has been given by the server yet and the timings form the client configuration
218+
(:ref:`p2_timeout<config_p2_timeout>`, :ref:`p2_star_timeout<config_p2_star_timeout>`)
219+
220+
:return: The session timings
221+
"""
222+
return self.session_timing
223+
207224
@standard_error_management
208225
def change_session(self, newsession: int) -> Optional[services.DiagnosticSessionControl.InterpretedResponse]:
209226
"""
@@ -238,8 +255,8 @@ def change_session(self, newsession: int) -> Optional[services.DiagnosticSession
238255
if self.config['use_server_timing']:
239256
self.logger.info('%s - Received new timing parameters. P2=%.3fs and P2*=%.3fs. Using these value from now on.' %
240257
(self.service_log_prefix(services.DiagnosticSessionControl), response.service_data.p2_server_max, response.service_data.p2_star_server_max))
241-
self.session_timing['p2_server_max'] = response.service_data.p2_server_max
242-
self.session_timing['p2_star_server_max'] = response.service_data.p2_star_server_max
258+
self.session_timing.p2_server_max = response.service_data.p2_server_max
259+
self.session_timing.p2_star_server_max = response.service_data.p2_star_server_max
243260

244261
return response
245262

@@ -2174,7 +2191,7 @@ def send_request(self, request: Request, timeout: int = -1) -> Optional[Response
21742191
if timeout < 0:
21752192
# Timeout not provided by user: defaults to Client request_timeout value
21762193
overall_timeout = self.config['request_timeout']
2177-
p2 = self.config['p2_timeout'] if self.session_timing['p2_server_max'] is None else self.session_timing['p2_server_max']
2194+
p2 = self.config['p2_timeout'] if self.session_timing.p2_server_max is None else self.session_timing.p2_server_max
21782195
if overall_timeout is not None:
21792196
single_request_timeout = min(overall_timeout, p2)
21802197
else:
@@ -2285,7 +2302,7 @@ def send_request(self, request: Request, timeout: int = -1) -> Optional[Response
22852302
done_receiving = False
22862303
if not using_p2_star:
22872304
# Received a 0x78 NRC: timeout is now set to P2*
2288-
p2_star = self.config['p2_star_timeout'] if self.session_timing['p2_star_server_max'] is None else self.session_timing['p2_star_server_max']
2305+
p2_star = self.config['p2_star_timeout'] if self.session_timing.p2_star_server_max is None else self.session_timing.p2_star_server_max
22892306
single_request_timeout = p2_star
22902307
using_p2_star = True
22912308
self.logger.debug("Server requested to wait with response code %s (0x%02x), single request timeout is now set to P2* (%.3f seconds)" %

0 commit comments

Comments
 (0)