can_socket 0.1.3 copy "can_socket: ^0.1.3" to clipboard
can_socket: ^0.1.3 copied to clipboard

Pure Dart FFI bindings for Linux SocketCAN. Raw CAN, CAN FD, BCM, ISO-TP, and J1939.

can_socket #

Pure Dart FFI bindings for Linux SocketCAN. Provides raw CAN, CAN FD, BCM (Broadcast Manager), ISO-TP, and J1939 socket access via direct libc calls -- no native plugin compilation required.

Features #

Socket type Class Description
CAN_RAW CanSocket Standard CAN and CAN FD frame send/receive
CAN_BCM CanBcmSocket Kernel-level cyclic TX and content-change RX filtering
CAN_ISOTP CanIsotpSocket ISO 15765-2 transport (segmentation/reassembly for UDS/OBD-II)
CAN_J1939 CanJ1939Socket SAE J1939 PGN-level communication with transparent segmentation

Additional capabilities:

  • CAN FD (flexible data-rate) frames up to 64 bytes
  • Hardware-level CAN filters (CanFilter)
  • Isolate-based async frameStream for non-blocking reception
  • Loopback and error-mask configuration
  • All Linux SocketCAN constants exported for advanced use

Platform support #

Platform Status
Linux (SocketCAN) Supported
macOS / Windows Not supported (no SocketCAN)

Getting started #

Prerequisites #

  • Dart SDK >= 3.7.0
  • Linux with SocketCAN support
  • A CAN interface (physical or virtual)

Set up a virtual CAN interface #

sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0

Install #

dependencies:
  can_socket: ^0.1.0

Usage #

Send and receive CAN frames #

import 'dart:typed_data';
import 'package:can_socket/can_socket.dart';

void main() {
  final socket = CanSocket('vcan0');

  // Send a standard CAN frame.
  socket.send(CanFrame(
    id: 0x123,
    data: Uint8List.fromList([0xDE, 0xAD, 0xBE, 0xEF]),
  ));

  // Blocking receive with timeout.
  final frame = socket.receive(timeoutMs: 1000);
  if (frame != null) {
    print('Received: $frame');
  }

  socket.close();
}

Async frame stream #

final socket = CanSocket('vcan0');
final sub = socket.frameStream.listen((frame) {
  print('${frame.id.toRadixString(16)}: ${frame.data}');
});

await Future.delayed(const Duration(seconds: 5));
await sub.cancel();
socket.close();

Hardware filters #

final socket = CanSocket('vcan0');
// Only receive CAN IDs 0x200 and 0x300.
socket.setFilters([
  CanFilter.exact(0x200),
  CanFilter.exact(0x300),
]);

CAN FD #

final socket = CanSocket('vcan0', canFd: true);
socket.send(CanFrame(
  id: 0x456,
  isFd: true,
  isBrs: true,
  data: Uint8List(64),
));

BCM cyclic transmission #

final bcm = CanBcmSocket('vcan0');
bcm.txSetup(BcmTxConfig(
  canId: 0x100,
  frames: [CanFrame(id: 0x100, data: Uint8List.fromList([1, 2, 3]))],
  ival2Us: 100000, // 100 ms interval
));
// Kernel sends the frame every 100 ms until stopped.
bcm.txDelete(0x100);
bcm.close();

ISO-TP (UDS / OBD-II) #

final isotp = CanIsotpSocket('vcan0', txId: 0x7E0, rxId: 0x7E8);
isotp.send(Uint8List.fromList([0x22, 0xF1, 0x86])); // ReadDataByIdentifier
final response = isotp.receive(timeoutMs: 5000);
print('Response: $response');
isotp.close();

J1939 #

final j1939 = CanJ1939Socket('vcan0',
    name: 0x123456789ABCDEF0, pgn: 0xF004, addr: 0x00);
j1939.send(
  Uint8List.fromList([0x01, 0x02]),
  destAddr: 0x01,
  destPgn: 0xF004,
);
final (:data, :srcAddr, :pgn) = j1939.receive(timeoutMs: 1000);
j1939.close();

Testing #

# Set up vcan0 first (see above), then:
dart test

License #

Apache 2.0 -- see LICENSE for details.

0
likes
150
points
31
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Pure Dart FFI bindings for Linux SocketCAN. Raw CAN, CAN FD, BCM, ISO-TP, and J1939.

Homepage
Repository (GitHub)
View/report issues

Topics

#can-bus #socketcan #ffi

License

unknown (license)

Dependencies

ffi

More

Packages that depend on can_socket