Remote

The remote interface works as a networked bridge between the computer running the application and the computer owning the physical CAN interface.

Multiple clients may connect to the same server simultaneously. Each client will create its own bus instance on the server, so this must be supported by the real interface.

Server

The computer which owns the CAN interface must start a server which accepts incoming connections. If more than one channel is to be shared, multiple servers must be started on different ports.

Start a server using default interface and channel:

$ canserver

Specify interface, channel and port number explicitly:

$ canserver --interface kvaser --channel 0 --port 54702

It can also be started as a module:

$ python -m can.interfaces.remote

Client

The application must specify remote as interface and host:port as channel. The port number can be omitted if default port is used. The bitrate to use on the CAN bus can also be specified.

bus = can.interface.Bus('192.168.0.10:54701',
                        bustype='remote',
                        bitrate=500000,
                        can_filters=[
                            {'can_id': 0x11},
                            {'can_mask': 0xff}
                        ])

Alternatively in a .canrc file:

[default]
interface = remote
channel = myhostname:54701

The can_logger.py script could be started like this:

$ can_logger.py -i remote -c myhostname:54701

Internals

The client uses a standard Bus class to connect to the server.

class can.interfaces.remote.RemoteBus(channel, can_filters=None, **config)[source]

Bases: can.bus.BusABC

CAN bus over a network connection bridge.

Parameters:
  • channel (str) – Address of server as host:port (port may be omitted).
  • can_filters (list) –

    A list of dictionaries each containing a “can_id” and a “can_mask”.

    >>> [{"can_id": 0x11, "can_mask": 0x21}]
    

    The filters are handed to the actual CAN interface on the server.

  • bitrate (int) – Bitrate in bits/s to use on CAN bus. May be ignored by the interface.

Any other backend specific configuration will be silently ignored.

recv(timeout=None)[source]

Block waiting for a message from the Bus.

Parameters:timeout (float) – Seconds to wait for a message.
Returns:None on timeout or a Message object.
Return type:can.Message
send(msg, timeout=None)[source]

Transmit a message to CAN bus.

Parameters:msg (can.Message) – A Message object.
Raises:can.interfaces.remote.CanRemoteError – On failed transmission to socket.
shutdown()[source]

Close socket connection.

socket = None

Socket connection to the server

exception can.interfaces.remote.CanRemoteError[source]

Bases: can.CanError

An error occurred on socket connection or on the remote end.

The server uses the following classes to implement the connections.

class can.interfaces.remote.RemoteServer(host='0.0.0.0', port=None, **config)[source]

Bases: SocketServer.ThreadingMixIn, SocketServer.TCPServer

Server for CAN communication.

Parameters:
  • host (str) – Address to listen to.
  • port (int) – Network port to listen to.
  • channel – The can interface identifier. Expected type is backend dependent.
  • bustype (str) – CAN interface to use.
  • bitrate (int) – Forced bitrate in bits/s.
serve_forever(poll_interval=0.5)

Start listening for incoming connections.

shutdown()

Stops the serve_forever loop.

Blocks until the loop has finished. This must be called while serve_forever() is running in another thread, or it will deadlock.

server_close()

Clean-up the server.

clients = None

List of can.interfaces.remote.server.ClientBusConnection instances

class can.interfaces.remote.server.ClientBusConnection(request, client_address, server)[source]

Bases: SocketServer.BaseRequestHandler

A client connection on the server.

send_msg(msg)[source]

Send a CAN message to the bus.

Protocol

The protocol is a stream of events over a TCP socket. Each event starts with one byte that represents the event id, followed by event specific data of arbitrary length in big-endian byte order.

The client start with sending a BusRequest followed by a FilterConfig. The server will reply with a BusResponse.

Each event class inherits from the base event class:

class can.interfaces.remote.events.BaseEvent[source]

Bases: object

Events should inherit this class.

encode()[source]

Convert event data to bytes.

Returns:Bytestring representing the event data.
Return type:bytes
classmethod from_buffer(buf)[source]

Parse the data and return a new event.

Parameters:buf (bytes) – Bytestring representing the event data.
Returns:Event decoded from buffer.
Raises:can.interfaces.remote.events.NeedMoreDataError – If not enough data exists.

The available events that can occurr and their specification is listed below:

class can.interfaces.remote.events.BusRequest(version, bitrate)[source]

Bases: can.interfaces.remote.events.BaseEvent

Request for connecting to CAN bus.

Byte Type Contents
0 U8 Protocol version used by client
1 - 4 S32 Bitrate in bits/s requested
Parameters:
  • version (int) – Network protocol version
  • bitrate (int) – Bitrate to use on CAN
EVENT_ID = 1

Event ID

bitrate = None

Bitrate in bits/s

version = None

Network protocol version

class can.interfaces.remote.events.BusResponse(channel_info)[source]

Bases: can.interfaces.remote.events.BaseEvent

Response after connected to CAN bus.

Byte Type Contents
0 U8 Length of channel info string
1 - x STR Channel info (UTF-8)
Parameters:channel_info (str) – Text describing the channel
EVENT_ID = 2

Event ID

channel_info = None

Text describing the channel

class can.interfaces.remote.events.CanMessage(msg)[source]

Bases: can.interfaces.remote.events.BaseEvent

CAN message being received or transmitted.

Byte Type Contents
0 - 7 F64 Timestamp
8 - 11 U32 Arbitration ID
12 U8 DLC
13 U8
Flags:
  • Bit 0: Extended ID
  • Bit 1: Remote frame
  • Bit 2: Error frame
14 - 21 U8 Data padded to an 8 byte array
Parameters:msg (can.Message) – A Message object.
EVENT_ID = 3

Event ID

msg = None

A can.Message instance.

class can.interfaces.remote.events.TransmitSuccess[source]

Bases: can.interfaces.remote.events.BaseEvent

A message has been successfully transmitted to CAN.

EVENT_ID = 4

Event ID

class can.interfaces.remote.events.RemoteException(exc)[source]

Bases: can.interfaces.remote.events.BaseEvent

An exception has occurred on the server.

Byte Type Contents
0 U8 Length of exception string
1 - x STR Exception description (UTF-8)
Parameters:exc (Exception) – The exception to send.
EVENT_ID = 6

Event ID

exc = None

The exception

class can.interfaces.remote.events.FilterConfig(can_filters=None)[source]

Bases: can.interfaces.remote.events.BaseEvent

CAN filter configuration.

Byte Type Contents
0 U8 Number of filters
1 - 4 U32 CAN ID for filter 1
5 - 8 U32 CAN mask for filter 1
9 - 12 U32 CAN ID for filter 2
13 - 16 U32 CAN mask for filter 2
... ... ...
Parameters:can_filters (list) – List of CAN filters
EVENT_ID = 10

Event ID

can_filters = None

A list of CAN filter dictionaries as: >> {‘can_id’: 0x03, ‘can_mask’: 0xff}

class can.interfaces.remote.events.ConnectionClosed[source]

Bases: can.interfaces.remote.events.BaseEvent

Connection closed by peer.

Will be automatically emitted if the socket is closed.

EVENT_ID = 255

Event ID