Packages
grizzly
0.22.2
9.1.4
9.1.2
9.1.1
9.1.0
9.0.0
8.15.3
8.15.2
8.15.1
8.15.0
8.14.0
8.13.0
8.12.0
8.11.3
8.11.2
8.11.1
8.11.0
8.10.0
8.9.0
8.8.1
8.8.0
8.7.1
8.7.0
8.6.12
8.6.11
8.6.10
8.6.9
8.6.8
8.6.7
retired
8.6.6
8.6.5
8.6.4
8.6.3
8.6.2
8.6.1
8.6.0
8.5.3
8.5.2
8.5.1
8.5.0
8.4.0
8.3.0
8.2.3
8.2.2
8.2.1
8.2.0
8.1.0
8.0.1
8.0.0
7.4.3
7.4.2
7.4.1
7.4.0
7.3.0
7.2.0
7.1.4
7.1.3
7.1.2
7.1.1
7.1.0
7.0.4
7.0.3
7.0.2
7.0.1
7.0.0
6.8.8
6.8.7
6.8.6
6.8.5
6.8.4
6.8.3
6.8.2
6.8.1
6.8.0
6.7.1
6.7.0
6.6.1
6.6.0
6.5.1
6.5.0
6.4.0
6.3.0
6.2.0
6.1.1
6.1.0
6.0.1
6.0.0
5.4.1
5.4.0
5.3.0
5.2.8
5.2.7
5.2.6
5.2.5
5.2.4
5.2.3
5.2.2
5.2.1
5.2.0
5.1.2
5.1.1
5.1.0
5.0.2
5.0.1
5.0.0
4.0.1
4.0.0
3.0.0
2.1.0
2.0.0
1.0.1
1.0.0
0.22.7
0.22.6
0.22.5
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.1
0.21.0
0.20.2
0.20.1
0.20.0
0.19.1
0.19.0
0.18.3
0.18.2
0.18.1
0.18.0
0.17.7
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.2
0.16.1
0.16.0
0.15.11
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.9.0-rc.4
0.9.0-rc.3
0.9.0-rc.2
0.9.0-rc.1
0.9.0-rc.0
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.3
0.4.2
Elixir Z-Wave library
Current section
Files
Jump to
Current section
Files
lib/grizzly/transport.ex
defmodule Grizzly.Transport do
@moduledoc """
Behaviour and functions for communicating to `zipgateway`
"""
defmodule Response do
@moduledoc """
The response from parse response
"""
alias Grizzly.ZWave.Command
@type t() :: %__MODULE__{
port: :inet.port_number() | nil,
ip_address: :inet.ip_address() | nil,
command: Command.t()
}
@enforce_keys [:command]
defstruct port: nil, ip_address: nil, command: nil
end
alias Grizzly.ZWave.{Command, DecodeError}
@opaque t() :: %__MODULE__{impl: module(), assigns: map()}
@type socket() :: :ssl.sslsocket() | :inet.socket()
@type args() :: [
ip_address: :inet.ip_address(),
port: :inet.port_number(),
transport: t()
]
@type parse_opt() :: {:raw, boolean()}
@typedoc """
After starting a server options can be passed back to the caller so that the
caller can do any other work it might seem fit.
Options:
* - `:strategy` - this informs the caller if the transport needs to wait for
connects to accept or if the socket can just process incoming messages.
If the strategy is `:accept` that is to mean the socket is okay to start
accepting new connections.
"""
@type listen_option() :: {:strategy, :none | :accept}
@enforce_keys [:impl]
defstruct assigns: %{}, impl: nil
@callback open(keyword()) :: {:ok, t()} | {:error, :timeout}
@callback listen(t()) :: {:ok, t(), [listen_option()]} | {:error, any()}
@callback accept(t()) :: {:ok, t()} | {:error, any()}
@callback handshake(t()) :: {:ok, t()} | {:error, any()}
@callback send(t(), binary(), keyword()) :: :ok
@callback parse_response(any(), [parse_opt()]) ::
{:ok, Response.t() | binary() | :connection_closed} | {:error, DecodeError.t()}
@callback close(t()) :: :ok
@doc """
Make a new `Grizzly.Transport`
If need to optionally assign some priv data you can map that into this function.
"""
@spec new(module(), map()) :: t()
def new(impl, assigns \\ %{}) do
%__MODULE__{
impl: impl,
assigns: assigns
}
end
@doc """
Update the assigns with this field and value
"""
@spec assigns(t(), atom(), any()) :: t()
def assigns(transport, assign, assign_value) do
new_assigns = Map.put(transport.assigns, assign, assign_value)
%__MODULE__{transport | assigns: new_assigns}
end
@doc """
Get the assign value for the field
"""
@spec assign(t(), atom(), any()) :: any()
def assign(transport, assign, default \\ nil),
do: Map.get(transport.assigns, assign, default)
@doc """
Listen using a transport
"""
@spec listen(t()) :: {:ok, t(), [listen_option()]} | {:error, any()}
def listen(transport) do
%__MODULE__{impl: transport_impl} = transport
transport_impl.listen(transport)
end
@doc """
Accept a new connection
"""
@spec accept(t()) :: {:ok, t()} | {:error, any()}
def accept(transport) do
%__MODULE__{impl: transport_impl} = transport
transport_impl.accept(transport)
end
@doc """
Preform the handshake
"""
@spec handshake(t()) :: {:ok, t()} | {:error, any()}
def handshake(transport) do
%__MODULE__{impl: transport_impl} = transport
transport_impl.handshake(transport)
end
@doc """
Open the transport
"""
@spec open(module(), args()) :: {:ok, t()} | {:error, :timeout}
def open(transport_module, args) do
transport_module.open(args)
end
@doc """
Send binary data using a transport
"""
@spec send(t(), binary(), keyword()) :: :ok
def send(transport, binary, opts \\ []) do
%__MODULE__{impl: transport_impl} = transport
transport_impl.send(transport, binary, opts)
end
@doc """
Parse the response for the transport
"""
@spec parse_response(t(), any()) ::
{:ok, Response.t() | binary() | :connection_closed} | {:error, DecodeError.t()}
def parse_response(transport, response, opts \\ []) do
%__MODULE__{impl: transport_impl} = transport
opts = [transport: transport] ++ opts
transport_impl.parse_response(response, opts)
end
end