Skip to content
Open
29 changes: 29 additions & 0 deletions doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3691,6 +3691,35 @@ Arguments:
setup/teardown the interface on activate/deactivate. Set this to ``False``
if you are managing the interface externally.

CanInterfaceDriver
~~~~~~~~~~~~~~~~~~
The :any:`CanInterfaceDriver` provides access to local and remote CAN
interfaces. For remote interfaces, the ``helpers/labgrid-raw-interface``
must be installed in the PATH on the exporter (see
`RawNetworkInterfaceDriver`_ for details).

The driver supports:

- Setting up the interface (requires privileges)
- Sending and receiving frames on the CAN interface
- Configuring filters on the socket

Bind to:
iface:
- `NetworkInterface`_
- `RemoteNetworkInterface`_
- `USBNetworkInterface`_

Implements:
- None

Arguments:
- bitrate (int): The CAN bitrate to use when setting up or verifying the
interface.
- dbitrate (int): optional, CAN-FD data bitrate to use when setting up or
verifying the interface. This enables CAN-FD support on the interface
and the socket.

LAA Drivers
~~~~~~~~~~~
Drivers for devices connected via a `Linaro Automation Appliance (LAA)
Expand Down
37 changes: 36 additions & 1 deletion helpers/labgrid-raw-interface
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import subprocess
import json
import struct
import fcntl
import socket

import yaml

Expand Down Expand Up @@ -103,6 +104,31 @@ def handle_ns_macvtap(options):
os.execlp("labgrid-tap-fwd", "labgrid-tap-fwd", str(macvtap_fd.fileno()))


def handle_canpipe(options):
cmd = ["ip", "link", "set", "dev", options.ifname]

subprocess.check_call(cmd + ["down"])

cmd += ["up"]
cmd += ["type", "can"]
cmd += ["bitrate", str(options.bitrate)]

if options.dbitrate is not None:
cmd += ["dbitrate", str(options.dbitrate)]
cmd += ["fd", "on"]
else:
cmd += ["fd", "off"]

subprocess.check_call(cmd)

with socket.socket(socket.PF_CAN, socket.SOCK_RAW | socket.SOCK_NONBLOCK, socket.CAN_RAW) as can:
can.bind((options.ifname,))
can.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FD_FRAMES, 1)

os.set_inheritable(can.fileno(), True)
os.execlp("labgrid-tap-fwd", "labgrid-tap-fwd", str(can.fileno()))


def main(program, options):
if not options.ifname:
raise ValueError("Empty interface name.")
Expand All @@ -116,7 +142,7 @@ def main(program, options):
if options.ifname in denylist:
raise ValueError(f"Interface name '{options.ifname}' is denied in denylist.")

programs = ["tcpreplay", "tcpdump", "ip", "ethtool", "ns-macvtap"]
programs = ["tcpreplay", "tcpdump", "ip", "ethtool", "ns-macvtap", "canpipe"]
if program not in programs:
raise ValueError(f"Invalid program {program} called with wrapper, valid programs are: {programs}")

Expand Down Expand Up @@ -186,6 +212,10 @@ def main(program, options):
handle_ns_macvtap(options)
return

elif program == "canpipe":
handle_canpipe(options)
return

try:
os.execvp(args[0], args)
except FileNotFoundError as e:
Expand Down Expand Up @@ -245,6 +275,11 @@ if __name__ == "__main__":
ns_mactap_parser.add_argument("pid", type=int, help="pid of namespace agent")
ns_mactap_parser.add_argument("--mac-address", type=str, metavar="ADDRESS", help="Set interface MAC address to ADDRESS")

canpipe_parser = subparsers.add_parser("canpipe")
canpipe_parser.add_argument("ifname", type=str, help="CAN interface name")
canpipe_parser.add_argument("bitrate", type=int, help="CAN interface bitrate")
canpipe_parser.add_argument("dbitrate", type=int, default=None, nargs='?', help="CAN interface FD bitrate")

args = parser.parse_args()
try:
main(args.program, args)
Expand Down
1 change: 1 addition & 0 deletions labgrid/driver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@
LAAUSBGadgetMassStorageDriver, LAAUSBDriver, \
LAAButtonDriver, LAALedDriver, LAATempDriver, LAAWattDriver, \
LAAProviderDriver
from .caninterfacedriver import CanInterfaceDriver
Loading
Loading