Underlying protocol (Connections)
Basics
Since UDS is an application layer protocol, it must be used over a data transport protocol. The current industry mostly uses ISO-TP protocol (ISO-15765) over CAN bus (ISO-11898).
Controller Area Network (CAN) protocol is a link layer protocol that sends data over small chunks of 8 bytes. ISO-TP is a transport protocol that allow the transmission of larger frames, usually 4095 bytes maximum although the 2016 version of the standard uses sizes defined over 32bits, which would theoretically allow frames of 4GB.
ISO-TP has been designed to be used for UDS. The current ISO-15765 protocol comes in 4 parts. ISO-15765-2 tells how to transmit large frames and ISO-15765-3 defines how to map the ISO-TP fields to a UDS message.
This project does not implement any communication protocol below the UDS layer, but provides a standard interface to interact with them.
How to
Access to the underlying protocol is done through a Connection
object. A user can define his own Connection object by inheriting the BaseConnection
object and implementing the abstract method.
The main interfaces to use with the Connection object are:
- BaseConnection.wait_frame(timeout=None, exception=False)[source]
Waits for the reception of a frame of data from the underlying transport protocol
- Parameters:
timeout (int) – The maximum amount of time to wait before giving up in seconds
exception (bool) – Boolean value indicating if this function may return exceptions. When
True
, all exceptions may be raised, includingTimeoutException
WhenFalse
, all exceptions will be logged asDEBUG
andNone
will be returned.
- Returns:
Received data
- Return type:
bytes or None
Available Connections
Some connections are already avaialble and can be imported from the udsoncan.connections
modules. Each of these connections are meant to address a specific use case.
PythonIsoTpConnection
- class udsoncan.connections.PythonIsoTpConnection(isotp_layer, name=None)[source]
Sends and receives data using a can-isotp Python module which is a Python implementation of the IsoTp transport protocol which can be coupled with python-can module to interract with CAN hardware
can-isotp must be installed in order to use this connection.
See an example
- Parameters:
isotp_layer (
isotp.TransportLayer
) – The IsoTP Transport layer object coming from theisotp
module.name (string) – This name is included in the logger name so that its output can be redirected. The logger name will be
Connection[<name>]
SyncAioIsotpConnection
- class udsoncan.connections.SyncAioIsotpConnection(rx_id, tx_id, name=None, *args, **kwargs)[source]
A wrapper for aioisotp sync variant
aioisotp must be installed in order to use this connection.
See an example
- Parameters:
rxid (int) – The reception CAN id
txid (int) – The transmission CAN id
name (string) – This name is included in the logger name so that its output can be redirected. The logger name will be
Connection[<name>]
args (list) – Optional parameters list passed to aioisotp binding method.
kwargs (dict) – Optional parameters dictionary passed to aioisotp binding method.
rx_id (int) –
tx_id (int) –
SocketConnection
- class udsoncan.connections.SocketConnection(sock, bufsize=4095, name=None)[source]
Sends and receives data through a socket.
- Parameters:
sock (socket.socket) – The socket to use. This socket must be bound and ready to use. Only
send()
andrecv()
will be called by this Connectionbufsize (int) – Maximum buffer size of the socket, this value is passed to
recv()
name (string) – This name is included in the logger name so that its output can be redirected. The logger name will be
Connection[<name>]
IsoTPSocketConnection
- class udsoncan.connections.IsoTPSocketConnection(interface, address, name=None, tpsock=None, **kwargs)[source]
Sends and receives data through an ISO-TP socket. Makes cleaner code than SocketConnection but offers no additional functionality. The can-isotp module must be installed in order to use this connection
- Parameters:
interface (string) – The can interface to use (example:
can0
)address (
isotp.Address
orisotp.AsymmetricAddress
) – The address used to bind the the socket. Before 1.21, txid/rxid were needed here, this has changed with v1.21name (string) – This name is included in the logger name so that its output can be redirected. The logger name will be
Connection[<name>]
tpsock (isotp.socket) – An optional ISO-TP socket to use instead of creating one.
QueueConnection
- class udsoncan.connections.QueueConnection(name=None, mtu=4095)[source]
Sends and receives data using 2 Python native queues.
MyConnection.fromuserqueue
: Data read from this queue whenwait_frame
is calledMyConnection.touserqueue
: Data written to this queue whensend
is called
- Parameters:
mtu (int) – Optional maximum frame size. Messages will be truncated to this size
name (string) – This name is included in the logger name so that its output can be redirected. The logger name will be
Connection[<name>]
J2534Connection
- class udsoncan.connections.J2534Connection(windll, rxid, txid, name=None, debug=False, *args, **kwargs)[source]
Sends and receives data through a J2534 Interface. A windows DLL and a J2534 interface must be installed in order to use this connection
- Parameters:
windll (str) – The path to the windows DLL for the J2534 interface (example: ‘C:/Program Files{x86}../../openport 2.0/op20pt32.dll’)
rxid (int) – The reception CAN id
txid (int) – The transmission CAN id
name (string) – This name is included in the logger name so that its output can be redirected. The logger name will be
Connection[<name>]
debug (boolean) – This will enable windows debugging mode in the dll (see tactrix doc for additional information)
args (list) – Optional parameters list (Unused right now).
kwargs (dict) – Optional parameters dictionary Unused right now).
Defining a new Connection
If all of the above Connection does not suits your needs, you can always implement your own Connection.
In order to define a new connection, 6 methods must be implemented as they will be called by the Client
object.
- abstract BaseConnection.open()[source]
Set up the connection object.
- Returns:
None
- Return type:
BaseConnection
- abstract BaseConnection.close()[source]
Close the connection object
- Returns:
None
- Return type:
None
- abstract BaseConnection.specific_send(payload, timeout=None)[source]
The implementation of the send method.
- Parameters:
payload (bytes) – Data to send
timeout (float | None) –
- Returns:
None
- Return type:
None
- abstract BaseConnection.specific_wait_frame(timeout=None)[source]
The implementation of the
wait_frame
method.
- Parameters:
timeout (int) – The maximum amount of time to wait before giving up
- Returns:
Received data
- Return type:
bytes or None