Skip to content

Commit 7aea5cf

Browse files
authored
Add additional argument for UDS_DSCEnumerator (#4826)
1 parent c91520d commit 7aea5cf

1 file changed

Lines changed: 34 additions & 5 deletions

File tree

scapy/contrib/automotive/uds_scan.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
_SocketUnion, _TransitionTuple, StateGenerator
4242
from scapy.contrib.automotive.uds import UDS, UDS_NR, UDS_DSC, UDS_TP, \
4343
UDS_RDBI, UDS_WDBI, UDS_SA, UDS_RC, UDS_IOCBI, UDS_RMBA, UDS_ER, \
44-
UDS_TesterPresentSender, UDS_CC, UDS_RDBPI, UDS_RD, UDS_TD
44+
UDS_TesterPresentSender, UDS_CC, UDS_RDBPI, UDS_RD, UDS_TD, UDS_DSCPR
4545
# TODO: Refactor this import
4646
from scapy.contrib.automotive.uds_ecu_states import * # noqa: F401, F403
4747
from scapy.error import Scapy_Exception
@@ -89,7 +89,8 @@ class UDS_DSCEnumerator(UDS_Enumerator, StateGeneratingServiceEnumerator):
8989
_supported_kwargs.update({
9090
'delay_state_change': (int, lambda x: x >= 0),
9191
'overwrite_timeout': (bool, None),
92-
'close_socket_when_entering_session_2': (bool, None)
92+
'close_socket_when_entering_session_2': (bool, None),
93+
'support_suppress_positive_response': (bool, None)
9394
})
9495
_supported_kwargs["scan_range"] = (
9596
(list, tuple, range), lambda x: max(x) < 0x100 and min(x) >= 0)
@@ -113,7 +114,13 @@ class UDS_DSCEnumerator(UDS_Enumerator, StateGeneratingServiceEnumerator):
113114
This enumerator will close the socket
114115
if session 2 (ProgrammingSession)
115116
was entered, if True. This will
116-
force a reconnect by the executor."""
117+
force a reconnect by the executor.
118+
:param bool support_suppress_positive_response: False by default.
119+
If True, this enumerator will treat
120+
no response for a DSC request with a
121+
session type > 0x80 as a positive
122+
response and will therefore create a
123+
new state with a session value - 0x80."""
117124

118125
def _get_initial_requests(self, **kwargs):
119126
# type: (Any) -> Iterable[Packet]
@@ -172,6 +179,29 @@ def get_new_edge(self,
172179
except KeyError:
173180
close_socket = False
174181

182+
try:
183+
support_out_of_spec = config[UDS_DSCEnumerator.__name__]["support_suppress_positive_response"] # noqa: E501
184+
except KeyError:
185+
support_out_of_spec = False
186+
187+
if edge is None:
188+
try:
189+
state, req, resp, _, _ = cast(ServiceEnumerator, self).results[-1] # noqa: E501
190+
except IndexError:
191+
return None
192+
193+
if support_out_of_spec and resp is None and req.diagnosticSessionType > 0x80: # noqa: E501
194+
resp = UDS() / UDS_DSCPR(diagnosticSessionType=0x80 - req.diagnosticSessionType) # noqa: E501
195+
new_state = EcuState.get_modified_ecu_state(resp, req, state)
196+
if new_state == state:
197+
return None
198+
else:
199+
edge = (state, new_state)
200+
self._edge_requests[edge] = req
201+
return edge
202+
else:
203+
return None
204+
175205
if edge:
176206
state, new_state = edge
177207
# Force TesterPresent if session is changed
@@ -1210,8 +1240,7 @@ def _random_memory_addr_pkt(addr_len=None): # noqa: E501
12101240
pkt.memorySizeLen = random.randint(1, 4)
12111241
pkt.memoryAddressLen = addr_len or random.randint(1, 4)
12121242
UDS_RMBARandomEnumerator.set_size(pkt, 0x10)
1213-
addr = random.randint(0, 2 ** (8 * pkt.memoryAddressLen) - 1) & \
1214-
(0xffffffff << (4 * pkt.memoryAddressLen))
1243+
addr = random.randint(0, 2 ** (8 * pkt.memoryAddressLen) - 1) & (0xffffffff << (4 * pkt.memoryAddressLen)) # noqa: E501
12151244
UDS_RMBARandomEnumerator.set_addr(pkt, addr)
12161245
return pkt
12171246

0 commit comments

Comments
 (0)