Skip to content

Commit

Permalink
fix(uds): Improve logging and timeout in ResponsePending loop
Browse files Browse the repository at this point in the history
  • Loading branch information
ferdinandjarisch authored and rumpelsepp committed Sep 15, 2023
1 parent 2f42730 commit 46028b1
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions src/gallia/services/uds/core/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,19 @@ async def request_unsafe(
# We already had ECUs which thought an infinite
# response_pending loop is a good idea…
# Let's limit this.
n_pending = 0
n_pending = 1
MAX_N_PENDING = 120
n_timeout = 0
waiting_time = 0.5
max_n_timeout = max(timeout if timeout else 0, 10) / waiting_time
max_n_timeout = max(timeout if timeout else 0, 20) / waiting_time
while (
isinstance(resp, service.NegativeResponse)
and resp.response_code
== UDSErrorCodes.requestCorrectlyReceivedResponsePending
):
self.logger.info(
f"Received ResponsePending: {n_pending}/{MAX_N_PENDING}"
)
try:
raw_resp = await self._read(timeout=waiting_time, tags=config.tags)
if raw_resp == b"":
Expand All @@ -122,7 +126,11 @@ async def request_unsafe(
except asyncio.TimeoutError as e:
# Send a tester present to indicate that
# we are still there.
await self._tester_present(supress_resp=True)
await self._tester_present(suppress_resp=True)
self.logger.debug(
"Waiting for next message after ResponsePending: "
f"{n_timeout}/{max_n_timeout}"
)
n_timeout += 1
if n_timeout >= max_n_timeout:
last_exception = MissingResponse(request, str(e))
Expand All @@ -131,7 +139,7 @@ async def request_unsafe(
resp = parse_pdu(raw_resp, request)
n_timeout = 0 # Only raise errors for consecutive timeouts
n_pending += 1
if n_pending >= 120:
if n_pending >= MAX_N_PENDING:
raise RuntimeError(
"ECU appears to be stuck in ResponsePending loop"
)
Expand All @@ -144,12 +152,14 @@ async def request_unsafe(
raise last_exception

async def _tester_present(
self, supress_resp: bool = False, config: UDSRequestConfig | None = None
self, suppress_resp: bool = False, config: UDSRequestConfig | None = None
) -> service.UDSResponse | None:
config = config if config is not None else UDSRequestConfig()
timeout = config.timeout if config.timeout else self.timeout
if supress_resp:
if suppress_resp:
pdu = service.TesterPresentRequest(suppress_response=True).pdu
tags = config.tags if config.tags is not None else []
self.logger.debug(pdu.hex(), extra={"tags": ["write", "uds"] + tags})
await self.transport.write(pdu, timeout, config.tags)
return None
return await self.tester_present(False, config)
Expand Down

0 comments on commit 46028b1

Please sign in to comment.