Skip to content

Commit 350f22f

Browse files
author
CI
committed
Sync to GitHub
1 parent 7be6570 commit 350f22f

2 files changed

Lines changed: 95 additions & 1 deletion

File tree

lib/bacnet/stack/transport/mstp_transport.ex

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,10 +753,60 @@ if Code.ensure_loaded?(Circuits.UART) do
753753
GenServer.call(transport, :disable_token_passing)
754754
end
755755

756+
@doc """
757+
Configures the transport.
758+
759+
Only some of the available `t:open_options/0` can be configured,
760+
unsupported options can only be changed by re-starting the transport completely.
761+
762+
The following options are supported:
763+
- `baudrate`
764+
- `log_communication`
765+
- `log_communication_rcv`
766+
- `max_info_frames`
767+
- `max_master_address`
768+
769+
For a description of each option, see `open/2`.
770+
771+
Note that reconfiguring the baudrate on the fly MAY lead to invalid frames!
772+
May also lead to dropping token.
773+
"""
774+
@spec configure(TransportBehaviour.transport(), open_options()) :: :ok | {:error, term()}
775+
def configure(transport, opts) when is_server(transport) and is_list(opts) do
776+
unless Keyword.keyword?(opts) do
777+
raise ArgumentError, "configure/2 expected a keyword list, got: #{inspect(opts)}"
778+
end
779+
780+
Enum.each(opts, fn
781+
{:baudrate, val} when is_integer(val) and val > 0 ->
782+
true
783+
784+
{:log_communication, val} when is_boolean(val) ->
785+
true
786+
787+
{:log_communication_rcv, val} when is_boolean(val) ->
788+
true
789+
790+
{:max_info_frames, val} when is_integer(val) and val > 0 ->
791+
true
792+
793+
{:max_master_address, val} when is_integer(val) and val > 0 ->
794+
true
795+
796+
{key, val} ->
797+
raise ArgumentError,
798+
"configure/2 received unsupported combination - key: " <>
799+
inspect(key) <> ", value: " <> inspect(val)
800+
end)
801+
802+
GenServer.call(transport, {:configure, Map.new(opts)})
803+
end
804+
756805
@doc false
757806
def init({callback, opts}) do
758807
new_opts =
759808
opts
809+
|> Map.put_new(:baudrate, 38_400)
760810
|> Map.put_new(:log_communication, false)
761811
|> Map.put_new(:max_info_frames, 1)
762812
|> Map.put_new(:max_master_address, @max_master_addr)
@@ -766,7 +816,7 @@ if Code.ensure_loaded?(Circuits.UART) do
766816
with {:ok, uart_pid} <- UART.start_link() do
767817
{UART.open(uart_pid, Map.fetch!(opts, :port_name),
768818
active: true,
769-
speed: Map.get(opts, :baudrate, 38_400),
819+
speed: new_opts.baudrate,
770820
data_bits: 8,
771821
stop_bits: 1,
772822
parity: :none,
@@ -1464,6 +1514,35 @@ if Code.ensure_loaded?(Circuits.UART) do
14641514
{:reply, {:error, :slave_mode}, state}
14651515
end
14661516

1517+
def handle_call({:configure, %{} = opts}, _from, %State{} = state) do
1518+
log_debug(fn -> "BacMstpTransport: Received configure request" end)
1519+
1520+
new_opts = Map.merge(state.opts, opts)
1521+
1522+
reply =
1523+
case Map.fetch(opts, :baudrate) do
1524+
{:ok, baudrate} ->
1525+
with :ok <- UART.configure(state.uart_pid, speed: baudrate) do
1526+
ReceiveFSM.configure(state.receive_fsm, %{
1527+
baudrate: baudrate,
1528+
log_communication: new_opts.log_communication_rcv
1529+
})
1530+
end
1531+
1532+
:error ->
1533+
:ok
1534+
end
1535+
1536+
case reply do
1537+
:ok ->
1538+
new_state = %{state | opts: new_opts}
1539+
{:reply, :ok, new_state}
1540+
1541+
_other ->
1542+
{:reply, reply, state}
1543+
end
1544+
end
1545+
14671546
def handle_call(_call, _from, state) do
14681547
{:noreply, state}
14691548
end

lib/bacnet/stack/transport/mstp_transport/receive_fsm.ex

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ if Code.ensure_loaded?(Circuits.UART) do
9494
:gen_statem.call(server, :reset_event_count)
9595
end
9696

97+
@doc """
98+
Configures the options.
99+
"""
100+
@spec configure(pid(), map() | Keyword.t()) :: :ok
101+
def configure(server, opts) when is_pid(server) and (is_map(opts) or is_list(opts)) do
102+
:gen_statem.call(server, {:configure, Map.new(opts)})
103+
end
104+
97105
@doc false
98106
def callback_mode(), do: [:handle_event_function, :state_enter]
99107

@@ -209,6 +217,13 @@ if Code.ensure_loaded?(Circuits.UART) do
209217
{:keep_state, %{data | event_count: 0}, [{:reply, from, :ok}]}
210218
end
211219

220+
# Handles :gen_statem.call({:configure, opts})
221+
def handle_event({:call, from}, {:configure, %{} = opts}, _state, %StateData{} = data) do
222+
log_debug(fn -> "BacMstpTransport_ReceiveFSM: Received configure call" end)
223+
224+
{:keep_state, %{data | opts: Map.merge(data.opts, opts)}, [{:reply, from, :ok}]}
225+
end
226+
212227
# --- Receiving Data ---
213228

214229
@spec handle_receive_data(binary(), atom(), StateData.t()) ::

0 commit comments

Comments
 (0)