'SocketCAN in dotnet core

I am writing software for the device on Linux, and which should work with the CAN interface. Ideally, I would like to work with the interface without connecting third-party libraries from c ++. Is it possible?



Solution 1:[1]

I solved this problem using native function. Here example to bind socket, can read and write message with native functions write( or aio_write) and read. CanPublisher in UDSim as example

const int Siocgifindex = 0x8933;
private const int PfCan = 29;
private const int SockRaw = 3;
private const int CanRaw = 1;
private const int CanMtu = 16;

[DllImport("libc", SetLastError = true)]
private static extern int socket(int domain, int type, int protocol);
[DllImport("libc", SetLastError = true)]
private static extern int ioctl(int fd, int request, ref Ifreq mtu);
[DllImport("libc", SetLastError = true)]
private static extern int bind(int fd, ref SockaddrCan addr, int addrlen);


[StructLayout(LayoutKind.Sequential)]
struct SockaddrCan
{
    public ushort can_family;
    public int can_ifindex;
    public uint rx_id;
    public uint tx_id;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct Ifreq
{
    public Ifreq(string ifr_name)
    {
        this.ifr_name = ifr_name;
        this.ifr_ifindex = 0; // ifru_ivalue
        this.ifru_mtu = 0;
    }

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string ifr_name;
    public int ifr_ifindex;
    public uint ifru_mtu;
}

var addr = new SockaddrCan();
var s = socket(PfCan, SockRaw, CanRaw);
var ifr = new Ifreq("vcan0");
var ret = ioctl(s, Siocgifindex, ref ifr);
addr.can_ifindex = ifr.ifr_ifindex;
addr.can_family = PfCan;
ret = bind(s, ref addr, Marshal.SizeOf(addr));

Solution 2:[2]

You need to look at the SocketCAN library that is part of Linux. You can also use candump and cansend to help you develop and also look at the candump.c and cansend.c source files for inspiration.

I see there is a dotnet tag, if you want to use CAN in dotnet I suggest you write a small C library to handle the CAN stuff. Then marshal that to dotnet, once you have access in dotnet you can wrap things in classes and create whatever abstractions you need.

Solution 3:[3]

I have written a .NET managed wrapper library for SocketCAN called SocketCAN# (SocketCANSharp): https://github.com/derek-will/SocketCANSharp

SocketCAN# enables utilizing Raw CAN, ISO-TP, Broadcast Manager, and J1939 sockets in a .NET application on Linux.

Some sample code:

IEnumerable<CanNetworkInterface> collection = CanNetworkInterface.GetAllInterfaces(true);

var iface = collection.FirstOrDefault(i =>  i.Name.Equals("vcan0"));

using (var rawCanSocket = new RawCanSocket())
{
    rawCanSocket.Bind(iface);
    int bytesWritten = rawCanSocket.Write(
        new CanFrame(0x123, new byte[] { 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }));
}

Underneath the library uses P/Invoke to call the native libc functions and marshal the various types back and fourth between the managed and unmanaged code.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ????? ???????
Solution 2
Solution 3 Derek W