EtherCAT.Bus.Transport.UdpSocket (ethercat v0.4.2)

Copy Markdown View Source

UDP/IP transport for EtherCAT (spec §2.6).

Encapsulates EtherCAT frames in UDP/IP packets per Table 8:

  • UDP destination port: 0x88A4 (34980) — the only header field ESCs check
  • UDP payload = EtherCAT payload (Bus.Frame.encode/1 output)
  • ESC accepts frames with any source/destination IP address
  • ESC clears the UDP checksum on forwarded frames (cannot update on-the-fly)

Implements the EtherCAT.Bus.Transport behaviour.

Options

  • :host — destination IP tuple (default: {255, 255, 255, 255} broadcast)
  • :port — destination UDP port (default: 34980 = 0x88A4)

Summary

Functions

Close the UDP socket. Returns the struct with raw set to nil.

Drain buffered datagrams and disable active delivery.

Returns nil — UDP sockets don't use OS interface link monitoring.

Match a {:udp, raw, _ip, _port, data} message from this socket.

Returns a string identifier for telemetry: "host:port".

Open a UDP socket bound to port 0x88A4.

Returns true when the socket is open.

Re-arm — delegates to set_active_once/1 (UDP has no drain issue).

Send an EtherCAT payload as a UDP datagram.

Arm for one async delivery via {:active, :once}.

Returns nil — UDP has no Ethernet-level source MAC.

Types

t()

@type t() :: %EtherCAT.Bus.Transport.UdpSocket{
  host: :inet.ip_address(),
  port: :inet.port_number(),
  raw: :gen_udp.socket() | nil
}

Functions

close(sock)

@spec close(t()) :: t()

Close the UDP socket. Returns the struct with raw set to nil.

drain(udp_socket)

@spec drain(t()) :: :ok

Drain buffered datagrams and disable active delivery.

interface(udp_socket)

@spec interface(t()) :: nil

Returns nil — UDP sockets don't use OS interface link monitoring.

match(udp_socket, arg2)

@spec match(t(), term()) :: {:ok, binary(), integer(), nil} | :ignore

Match a {:udp, raw, _ip, _port, data} message from this socket.

Returns {:ok, ecat_payload, rx_at, nil} when the message belongs to this socket. src_mac is always nil for UDP (no Ethernet headers). The UDP checksum is cleared by the ESC (spec §2.6) — no validation needed.

name(udp_socket)

@spec name(t()) :: String.t()

Returns a string identifier for telemetry: "host:port".

open(opts)

@spec open(keyword()) :: {:ok, t()} | {:error, term()}

Open a UDP socket bound to port 0x88A4.

open?(udp_socket)

@spec open?(t()) :: boolean()

Returns true when the socket is open.

rearm(sock)

@spec rearm(t()) :: :ok

Re-arm — delegates to set_active_once/1 (UDP has no drain issue).

send(udp_socket, ecat_payload)

@spec send(t(), binary()) :: {:ok, integer()} | {:error, term()}

Send an EtherCAT payload as a UDP datagram.

set_active_once(udp_socket)

@spec set_active_once(t()) :: :ok

Arm for one async delivery via {:active, :once}.

src_mac(udp_socket)

@spec src_mac(t()) :: nil

Returns nil — UDP has no Ethernet-level source MAC.