# `IEC60870.CS104.Connection`
[🔗](https://github.com/Ultraluv/ex_iec60870/blob/main/lib/iec60870/cs104/connection.ex#L1)

IEC 60870-5-104 Client / Master Connection (`GenServer`), equivalent to `cs104_connection.c`.

Manages:
- TCP / TLS socket connection (`:gen_tcp` / `:ssl`)
- `STARTDT` / `STOPDT` / `TESTFR` state transitions
- 15-bit `N(S)` and `N(R)` sequence numbers and `k` / `w` sliding window
- `T0`, `T1`, `T2`, `T3` timers
- Helper command methods (`send_interrogation_command/4`, `send_clock_sync_command/3`, etc.)

# `connection_event`

```elixir
@type connection_event() ::
  :opened | :closed | :startdt_con_received | :stopdt_con_received | :failed
```

# `state_name`

```elixir
@type state_name() ::
  :idle
  | :inactive
  | :waiting_for_startdt_con
  | :active
  | :waiting_for_stopdt_con
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `close`

```elixir
@spec close(GenServer.server()) :: :ok
```

# `connect`

```elixir
@spec connect(GenServer.server()) :: :ok | {:error, term()}
```

# `connect_async`

```elixir
@spec connect_async(GenServer.server()) :: :ok
```

# `get_apci_parameters`

```elixir
@spec get_apci_parameters(GenServer.server()) :: IEC60870.APCIParameters.t()
```

# `get_app_layer_parameters`

```elixir
@spec get_app_layer_parameters(GenServer.server()) :: IEC60870.AppLayerParameters.t()
```

# `get_state`

```elixir
@spec get_state(GenServer.server()) :: map()
```

# `is_connected?`

```elixir
@spec is_connected?(GenServer.server()) :: boolean()
```

# `is_transmit_buffer_full?`

```elixir
@spec is_transmit_buffer_full?(GenServer.server()) :: boolean()
```

# `send_asdu`

```elixir
@spec send_asdu(GenServer.server(), IEC60870.ASDU.t()) :: :ok | {:error, term()}
```

# `send_clock_sync_command`

Sends `C_CS_NA_1` (TypeID 103) clock synchronization command.

# `send_counter_interrogation_command`

Sends `C_CI_NA_1` (TypeID 101) counter interrogation command.

# `send_interrogation_command`

Sends `C_IC_NA_1` (TypeID 100) interrogation command.

# `send_process_command`

Sends a process command InformationObject wrapped in an ASDU.

# `send_process_command`

# `send_read_command`

Sends `C_RD_NA_1` (TypeID 102) read command.

# `send_start_dt`

```elixir
@spec send_start_dt(GenServer.server()) :: :ok | {:error, term()}
```

# `send_stop_dt`

```elixir
@spec send_stop_dt(GenServer.server()) :: :ok | {:error, term()}
```

# `send_test_command`

Sends `C_TS_NA_1` (TypeID 104) test command.

# `send_test_command_with_timestamp`

Sends `C_TS_TA_1` (TypeID 107) test command with CP56Time2a timestamp.

# `send_test_fr`

```elixir
@spec send_test_fr(GenServer.server()) :: :ok | {:error, term()}
```

# `set_apci_parameters`

```elixir
@spec set_apci_parameters(GenServer.server(), IEC60870.APCIParameters.t()) :: :ok
```

# `set_app_layer_parameters`

```elixir
@spec set_app_layer_parameters(GenServer.server(), IEC60870.AppLayerParameters.t()) ::
  :ok
```

# `set_asdu_handler`

```elixir
@spec set_asdu_handler(
  GenServer.server(),
  (pid(), IEC60870.ASDU.t() -&gt; any()) | (IEC60870.ASDU.t() -&gt; any()) | nil
) :: :ok
```

Sets or updates the ASDU received handler on the connection. Matches `CS104_Connection_setASDUReceivedHandler`.

# `set_connection_handler`

```elixir
@spec set_connection_handler(
  GenServer.server(),
  (pid(), atom() -&gt; any()) | (atom() -&gt; any()) | nil
) ::
  :ok
```

Sets or updates the connection event handler on the connection. Matches `CS104_Connection_setConnectionHandler`.

# `set_originator_address`

```elixir
@spec set_originator_address(GenServer.server(), non_neg_integer()) :: :ok
```

# `start_link`

Starts a `CS104.Connection` process.

Options:
- `:host` - remote IP or hostname (default `"127.0.0.1"`)
- `:port` - remote TCP port (default `2404`, or `19998` if `:tls_opts` is given)
- `:local_ip` - optional local bind address
- `:local_port` - optional local bind port (default `0`)
- `:tls_opts` - optional `:ssl` options list for TLS connections
- `:apci_params` - `%IEC60870.APCIParameters{}`
- `:al_params` - `%IEC60870.AppLayerParameters{}`
- `:owner` - PID to receive `{:iec60870_cs104, pid, event}` messages
- `:connection_handler` - `fn conn_pid, event -> any() end`
- `:asdu_handler` - `fn conn_pid, asdu -> any() end`
- `:raw_message_handler` - `fn conn_pid, raw_bytes, sent? -> any() end`
- `:auto_connect` - boolean (default `false`)
- `:name` - GenServer registration name

---

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