The UDS client is a simple client that works synchronously and can handle a single request/response at a time. When requesting a service, the client executes these tasks:
- Builds a payload
- Calls the connection empty_rxqueue method.
- Sends the request
- Waits for a response, with timeout
- Interprets the response data
- Validates the response content
- Returns the response
The goal of this client is to simplify the usage of the Services object by exposing only useful arguments, hiding repetitive values, handling exceptions and logging. It can detect usage errors as well as malformed server responses.
The client will raise a NegativeResponseException<NegativeResponseException>
when the server responds with a negative response.
The client may raise InvalidResponseException<InvalidResponseException>
if the payload is incomplete or if the underlying service raises this exception while parsing the response data.
The client may raise UnexpectedResponseException<UnexpectedResponseException>
if the response from the server does not match the last request sent. For example, if the service number in the response is different from the service number in the request. Another case would be if the echo of a parameter for a specific service does not match the request. For instance, if an ECUReset subfunction is the reset type, a valid server response will include an echo of the reset type in its payload.
udsoncan.client.Client
The client configuration must be a dictionary with the following keys defined:
exception_on_negative_response
When set to True, the client will raise a NegativeResponseException<NegativeResponseException>
when the server responds with a negative response. When set to False, the returned Response will have its property positive set to False
exception_on_invalid_response
When set to True, the client will raise a InvalidResponseException<InvalidResponseException>
when the underlying service interpret_response raises the same exception. When set to False, the returned Response will have its property valid set to False
exception_on_unexpected_response
When set to True
, the client will raise a UnexpectedResponseException<UnexpectedResponseException>
when the server returns a response that is not expected. For instance, a response for a different service or when the subfunction echo doesn't match the request. When set to False
, the returned Response will have its property unexpected
set to True in the same case.
security_algo
The implementation of the security algorithm necessary for the SecurityAccess<SecurityAccess>
service. This function must have the following signatures:
SomeAlgorithm(level, seed, params)
- param level
The requested security level.
- type level
int
- param seed
The seed given by the server
- type seed
bytes
- param params
The value provided by the client configuration
security_algo_params
- return
The security key
- rtype
bytes
Warning
Starting from v1.12, parameters are passed by name, so their order is not important, but their name is. Also, for backward compatibility, Python reflection is used to pass only arguments present in the signature. So a signature such as SomeAlgorithm()
would be accepted.
See an example <example_security_algo>
security_algo_params
This value will be given to the security algorithm defined in config['security_algo']
. This value can be any Python object, including a dictionary.
data_identifiers
This configuration is a dictionary that is mapping an integer (the data identifier) with a DidCodec<DidCodec>
. These codecs will be used to convert values to byte payload and vice-versa when sending/receiving data for a service that needs a DID, i.e.:
ReadDataByIdentifier<ReadDataByIdentifier>
WriteDataByIdentifier<WriteDataByIdentifier>
ReadDTCInformation<ReadDTCInformation>
with subfunctionreportDTCSnapshotRecordByDTCNumber
andreportDTCSnapshotRecordByRecordNumber
Possible configuration values are
string
: The string will be used as a pack/unpack string when processing the dataDidCodec
(class or instance) : The encode/decode method will be used to process the data
input_output
This configuration is a dictionary that is mapping an integer (the IO data identifier) with a DidCodec<DidCodec>
specifically for the InputOutputControlByIdentifier<InputOutputControlByIdentifier>
service. Just like config[data_identifers], these codecs will be used to convert values to byte payload and vice-versa when sending/receiving data.
Since InputOutputControlByIdentifier<InputOutputControlByIdentifier>
supports composite codecs, it is possible to provide a sub-dictionary as a codec specifying the bitmasks.
Possible configuration values are:
string
: The string will be used as a pack/unpack string when processing the dataDidCodec
(class or instance) : The encode/decode method will be used to process the data
dict
: The dictionary entry indicates a composite DID. Three subkeys must be defined as:
codec
: The codec, a string or a DidCodec class/instancemask
: A dictionary mapping the mask name with a bitmask_size
: An integer indicating on how many bytes must the mask be encoded
See this example<iocontrol_composite_did>
to see how IO codecs are defined.
tolerate_zero_padding
This value will be passed to the services 'interpret_response' when the parameter is supported as in ReadDataByIdentifier<ReadDataByIdentifier>
, ReadDTCInformation<ReadDTCInformation>
. It has to ignore trailing zeros in the response data to avoid falsely raising InvalidResponseException<InvalidResponseException>
if the underlying protocol uses some zero-padding.
ignore_all_zero_dtc
This value is used with the ReadDTCInformation<ReadDTCInformation>
service when reading DTCs. It will skip any DTC that has an ID of 0x000000. If the underlying protocol uses zero-padding, it may generate a valid response data of all zeros. This parameter is different from config['tolerate_zero_padding']
.
Consider a server response that contains a list of DTCs where all DTCs must be 4 bytes long (ID and status). Say that the server returns a single DTC of value 0x123456, with status 0x78 over a transport protocol that uses zero-padding. Let's study 5 different payloads.
1234567800
(invalid)123456780000
(invalid)12345678000000
(invalid)1234567800000000
(valid)123456780000000000
(invalid)
In this situation, all cases except case 4 would raise a InvalidResponseException<InvalidResponseException>
because of their incorrect lengths (unless config['tolerate_zero_padding']
is set to True). Case 4 would return 2 DTCs, the second DTC with an ID of 0x000000 and a status of 0x00. Setting config['ignore_all_zero_dtc']
to True will make the functions return only the first valid DTC.
server_address_format
The MemoryLocation<MemoryLocation>
server_address_format is the value to use when none is specified explicitly for methods expecting a parameter of type MemoryLocation<MemoryLocation>
.
See an example<example_default_memloc_format>
server_memorysize_format
The MemoryLocation<MemoryLocation>
server_memorysize_format is the value to use when none is specified explicitly for methods expecting a parameter of type MemoryLocation<MemoryLocation>
See an example<example_default_memloc_format>
extended_data_size
This is the description of all the DTC extended data record sizes. This value is used to decode the server response when requesting a DTC extended data. The value must be specified as follows:
config['extended_data_size'] = {
0x123456 : 45, # Extended data for DTC 0x123456 is 45 bytes long
0x123457 : 23 # Extended data for DTC 0x123457 is 23 bytes long
}
dtc_snapshot_did_size
The number of bytes used to encode a data identifier specifically for ReadDTCInformation<ReadDTCInformation>
subfunction reportDTCSnapshotRecordByDTCNumber
and reportDTCSnapshotRecordByRecordNumber
. The UDS standard does not specify a DID size although all other services expect a DID encoded over 2 bytes (16 bits). Default value of 2
standard_version
The standard version to use, valid values are : 2006, 2013, 2020. Default value is 2020
request_timeout
Maximum amount of time in seconds to wait for a response of any kind, positive or negative, after sending a request. After this time is elapsed, a TimeoutException will be raised regardless of other timeouts value or previous client responses. In particular even if the server requests that the client wait, by returning response requestCorrectlyReceived-ResponsePending (0x78), this timeout will still trigger.
If you wish to disable this behaviour and have your server wait for as long as it takes for the ECU to finish whatever activity you have requested, set this value to None.
Default value of 5
p2_timeout
Maximum amount of time in seconds to wait for a first response (positive, negative, or NRC 0x78). After this time is elapsed, a TimeoutException will be raised if no response has been received. See ISO 14229-2:2013 (UDS Session Layer Services) for more details. Default value of 1
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 (requestCorrectlyReceived-ResponsePending). After this time is elapsed, a TimeoutException will be raised if no response has been received. See ISO 14229-2:2013 (UDS Session Layer Services) for more details. Default value of 5
use_server_timing
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.
This parameter has no effect when config['standard_version']
is set to 2006
.
Default value is True
The UDS standard proposes a mechanism to avoid treating useless positive responses. For all services using a subfunction byte, the client can set bit 7 of the subfunction byte to signal that no response is necessary if the response is positive. This bit is called the suppressPosRspMsgIndicationBit
The Client
object lets you use that feature by using suppress_positive_response
into a with
statement. See the following example:
with client.suppress_positive_response:
client.tester_present()
When suppress_positive_response
is asking for a service using a subfunction byte, the client will set suppressPosRspMsgIndicationBit before sending the request. The client will not wait for any response and will disregard negative responses if they happen. The response returned by the client function will always be None
in that case.
If suppress_positive_response
is asking for a service with no subfunction byte, the directive will be ignored and a warning message will be logged.
For mean of testing, it may be useful to send invalid payloads to the server and still want the Client
object to parse the response of the server.
It is possible to do so by using the payload_override
property into a with
statement. See the following example:
with client.payload_override(b'\x11\x22\x33'): # Client will send 112233 (hex) in every call within this "with" statement
client.tester_present()
It is also possible to override with a function that modify the original output
def my_func(payload):
return payload + b'\x00' # Add extra 00 to the payload
with client.payload_override(my_func): # Client will append 00 to its output
client.tester_present()
When using that feature, the client will process the response from the server just like if a valid request was sent. The response may be Invalid<InvalidResponseException>
, Unexpected<UnexpectedResponseException>
or Negative<NegativeResponseException>
.
Note
It is possible to change the behaviour of the client on failing requests. See the client parameters exception_on_invalid_response<config_exception_on_invalid_response>
, exception_on_unexpected_response<config_exception_on_unexpected_response>
and exception_on_negative_response<config_exception_on_negative_response>
udsoncan.client.Client.read_extended_timing_parameters
udsoncan.client.Client.reset_default_timing_parameters
udsoncan.client.Client.read_active_timing_parameters
udsoncan.client.Client.set_timing_parameters
udsoncan.client.Client.clear_dtc
udsoncan.client.Client.communication_control
udsoncan.client.Client.control_dtc_setting
udsoncan.client.Client.change_session
udsoncan.client.Client.dynamically_define_did
Note
See an example<example_define_dynamic_did>
showing how to define a dynamic DID.
udsoncan.client.Client.clear_dynamically_defined_did
udsoncan.client.Client.clear_all_dynamically_defined_did
udsoncan.client.Client.ecu_reset
udsoncan.client.Client.io_control
udsoncan.client.Client.link_control
udsoncan.client.Client.read_data_by_identifier
udsoncan.client.Client.get_dtc_by_status_mask
udsoncan.client.Client.get_user_defined_memory_dtc_by_status_mask
udsoncan.client.Client.get_emission_dtc_by_status_mask
udsoncan.client.Client.get_mirrormemory_dtc_by_status_mask
udsoncan.client.Client.get_dtc_by_status_severity_mask
udsoncan.client.Client.get_number_of_dtc_by_status_mask
udsoncan.client.Client.get_mirrormemory_number_of_dtc_by_status_mask
udsoncan.client.Client.get_number_of_emission_dtc_by_status_mask
udsoncan.client.Client.get_number_of_dtc_by_status_severity_mask
udsoncan.client.Client.get_dtc_severity
udsoncan.client.Client.get_supported_dtc
udsoncan.client.Client.get_first_test_failed_dtc
udsoncan.client.Client.get_first_confirmed_dtc
udsoncan.client.Client.get_most_recent_test_failed_dtc
udsoncan.client.Client.get_most_recent_confirmed_dtc
udsoncan.client.Client.get_dtc_with_permanent_status
udsoncan.client.Client.get_dtc_fault_counter
udsoncan.client.Client.get_dtc_snapshot_identification
udsoncan.client.Client.get_dtc_snapshot_by_dtc_number
udsoncan.client.Client.get_user_defined_dtc_snapshot_by_dtc_number
udsoncan.client.Client.get_dtc_snapshot_by_record_number
udsoncan.client.Client.get_dtc_extended_data_by_dtc_number
udsoncan.client.Client.get_dtc_extended_data_by_record_number
udsoncan.client.Client.get_user_defined_dtc_extended_data_by_dtc_number
udsoncan.client.Client.get_mirrormemory_dtc_extended_data_by_dtc_number
udsoncan.client.Client.read_memory_by_address
Note
See an example<example_default_memloc_format>
showing how to use default format configuration.
udsoncan.client.Client.request_download
Note
See an example<example_default_memloc_format>
showing how to use default format configuration.
udsoncan.client.Client.request_transfer_exit
udsoncan.client.Client.request_upload
Note
See an example<example_default_memloc_format>
showing how to use default format configuration.
udsoncan.client.Client.start_routine
udsoncan.client.Client.stop_routine
udsoncan.client.Client.get_routine_result
udsoncan.client.Client.request_seed
udsoncan.client.Client.send_key
udsoncan.client.Client.unlock_security_access
Note
See this example<example_security_algo>
to see how to define the security algorithm
udsoncan.client.Client.tester_present
udsoncan.client.Client.transfer_data
udsoncan.client.Client.write_data_by_identifier
Note
If the DID Codec that is written is defined with a pack string (default codec), multiple values may be passed with a tuple.
udsoncan.client.Client.write_memory_by_address
udsoncan.client.Client.add_file
udsoncan.client.Client.delete_file
udsoncan.client.Client.replace_file
udsoncan.client.Client.read_file
udsoncan.client.Client.read_dir
udsoncan.client.Client.resume_file