# `Meshcore.Transport`
[🔗](https://github.com/nyannus/meshcore_ex/blob/v0.1.0/lib/meshcore/transport.ex#L1)

Behaviour implemented by byte transports (serial, TCP, BLE, or your own).

A transport is a process started by `Meshcore.Client` with the option
`:owner` set to the client's pid. It talks to its owner exclusively through
messages:

  * `{:meshcore_transport, pid, {:connected, info}}` – the link is up; `info`
    identifies the connection (host, port, address…) and ends up in the
    `:connected` event payload.
  * `{:meshcore_transport, pid, {:frame, binary}}` – one complete companion
    protocol frame (already de-framed).
  * `{:meshcore_transport, pid, {:disconnected, reason}}` – the link was lost
    or could not be established. The transport should stop after sending it.

Connecting must happen **asynchronously** (e.g. in `c:GenServer.handle_continue/2`)
so that `start_link/1` returns immediately; a failed connect is reported as
`{:disconnected, {:connect_failed, reason}}`.

A transport is linked to its owner: if the owner dies the transport dies with
it, and if the transport crashes the owner treats it as a lost connection
and (optionally) reconnects with a fresh process.

# `spec`

```elixir
@type spec() :: {module(), keyword()}
```

A transport module plus its start options.

# `close`

```elixir
@callback close(transport :: pid()) :: :ok
```

Closes the link and stops the transport process.

# `send_frame`

```elixir
@callback send_frame(transport :: pid(), frame :: binary()) :: :ok
```

Sends one protocol frame (the transport adds any wire framing).

Must not block the caller: implement it as a cast. Write failures are
reported to the owner as a `{:disconnected, reason}` message.

# `start_link`

```elixir
@callback start_link(opts :: keyword()) :: GenServer.on_start()
```

Starts the transport. `opts` always contains `:owner`.

---

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