# `EtherCAT.Simulator.Transport.Udp`
[🔗](https://github.com/sid2baker/ethercat/blob/main/lib/ethercat/simulator/transport/udp.ex#L1)

UDP endpoint for `EtherCAT.Simulator`.

This binds a real UDP socket and forwards EtherCAT UDP payloads to a running
simulator segment, so the normal `UdpSocket` transport can talk to simulated
slaves without any test-specific seam in the master runtime.

It also owns UDP-edge fault injection for cases that cannot be modeled at the
datagram-execution layer, such as malformed EtherCAT frame headers,
deliberately mismatched datagram indices, or stale previous-response replay.

Supported reply-fault injection forms:

- `EtherCAT.Simulator.Transport.Udp.Fault.truncate()`
- `EtherCAT.Simulator.Transport.Udp.Fault.wrong_idx() |> EtherCAT.Simulator.Transport.Udp.Fault.next(count)`
- `EtherCAT.Simulator.Transport.Udp.Fault.script([mode, ...])`

Supported modes:

- `:truncate`
- `:unsupported_type`
- `:wrong_idx`
- `:replay_previous`

# `fault`

```elixir
@type fault() ::
  {:corrupt_next_response, frame_fault_mode()}
  | {:corrupt_next_responses, pos_integer(), frame_fault_mode()}
  | {:corrupt_response_script, [frame_fault_mode(), ...]}
```

# `frame_fault_mode`

```elixir
@type frame_fault_mode() ::
  :truncate | :unsupported_type | :wrong_idx | :replay_previous
```

# `state`

```elixir
@type state() :: %{
  socket: :gen_udp.socket(),
  ip: :inet.ip_address(),
  port: :inet.port_number(),
  pending_faults: [frame_fault_mode()],
  last_response_payload: binary() | nil
}
```

# `child_spec`

```elixir
@spec child_spec(keyword()) :: Supervisor.child_spec()
```

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `clear_faults`

```elixir
@spec clear_faults() :: :ok | {:error, :not_found}
```

# `info`

```elixir
@spec info() :: {:ok, map()} | {:error, term()}
```

# `inject_fault`

```elixir
@spec inject_fault(EtherCAT.Simulator.Transport.Udp.Fault.t() | fault()) ::
  :ok | {:error, :invalid_fault | :not_found}
```

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
