Skip to content

Commit 0dc7253

Browse files
author
CI
committed
Sync to GitHub
1 parent 224ecab commit 0dc7253

7 files changed

Lines changed: 221 additions & 66 deletions

File tree

lib/bacnet/protocol/apdu/confirmed_service_request.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,9 @@ defmodule BACnet.Protocol.APDU.ConfirmedServiceRequest do
299299
end
300300

301301
unless is_nil(apdu.proposed_window_size) or
302-
(apdu.proposed_window_size >= 0 and apdu.proposed_window_size <= 255) do
302+
(apdu.proposed_window_size >= 1 and apdu.proposed_window_size <= 127) do
303303
raise ArgumentError,
304-
"Proposed window size must be nil or between 0 and 255 inclusive, " <>
304+
"Proposed window size must be nil or between 1 and 127 inclusive, " <>
305305
"got: #{inspect(apdu.proposed_window_size)}"
306306
end
307307

lib/bacnet/protocol/constants.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ defmodule BACnet.Protocol.Constants do
9090
@typedoc """
9191
The maximum amount of segments for segmented requests or responses.
9292
"""
93-
@type max_segments :: 1..64 | :more_than_64 | :unspecified
93+
@type max_segments :: 2 | 4 | 8 | 16 | 32 | 64 | :more_than_64 | :unspecified
9494

9595
###############################
9696

lib/bacnet/stack/client.ex

Lines changed: 95 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,7 @@ defmodule BACnet.Stack.Client do
253253
disable_app_timeout: boolean(),
254254
disable_invoke_id_management: boolean(),
255255
npci_source: NpciTarget.t() | nil,
256-
segmented_rcv_window_overwrite: boolean(),
257-
supervisor_mod: module()
256+
segmented_rcv_window_overwrite: boolean()
258257
}
259258
}
260259

@@ -380,11 +379,56 @@ defmodule BACnet.Stack.Client do
380379
:transport
381380
])
382381

383-
validate_start_link_opts(opts2)
382+
validate_start_link_opts(opts2, "start_link/1")
384383

385384
GenServer.start_link(__MODULE__, Map.new(opts2), genserver_opts)
386385
end
387386

387+
@doc """
388+
Configure the client.
389+
390+
Only some of the available `t:start_options/0` can be configured,
391+
unsupported options can only be changed by re-starting the client completely.
392+
393+
The following options are supported:
394+
- `apdu_retries`
395+
- `apdu_timeout`
396+
- `disable_app_timeout` (note that current active timers will NOT be cancelled)
397+
- `npci_source`
398+
- `segmented_rcv_window_overwrite`
399+
400+
For a description of each option, see `start_link/1`.
401+
"""
402+
@spec configure(server(), start_options()) :: :ok
403+
def configure(server, opts) when is_server(server) and is_list(opts) do
404+
unless Keyword.keyword?(opts) do
405+
raise ArgumentError,
406+
"configure/2 expected opts to be a keyword list, " <>
407+
"got: #{inspect(opts)}"
408+
end
409+
410+
validate_start_link_opts(opts, "configure/2", true)
411+
412+
Enum.each(opts, fn
413+
# Supported options
414+
{key, _val}
415+
when key in [
416+
:apdu_retries,
417+
:apdu_timeout,
418+
:disable_app_timeout,
419+
:npci_source,
420+
:segmented_rcv_window_overwrite
421+
] ->
422+
true
423+
424+
{key, _val} ->
425+
raise ArgumentError,
426+
"configure/2 does not support option " <> inspect(key)
427+
end)
428+
429+
GenServer.call(server, {:configure, Map.new(opts)})
430+
end
431+
388432
@doc """
389433
Add a source to the per-source APDU timeouts map. This is only used for receiving.
390434
@@ -628,6 +672,11 @@ defmodule BACnet.Stack.Client do
628672
end
629673

630674
@doc false
675+
def handle_call({:configure, %{} = opts}, _from, %State{} = state) do
676+
new_state = %{state | opts: Map.merge(state.opts, opts)}
677+
{:reply, :ok, new_state}
678+
end
679+
631680
def handle_call(
632681
{:add_apdu_timeout, source_address, device_id, timeout},
633682
_from,
@@ -2247,7 +2296,8 @@ defmodule BACnet.Stack.Client do
22472296
defp kw_put_new(kw, key, val), do: Keyword.put_new(kw, key, val)
22482297

22492298
# credo:disable-for-lines:50 Credo.Check.Refactor.CyclomaticComplexity
2250-
defp validate_start_link_opts(opts) do
2299+
defp validate_start_link_opts(opts, mfa, skip_check \\ false)
2300+
when is_binary(mfa) and is_boolean(skip_check) do
22512301
case opts[:apdu_retries] do
22522302
nil ->
22532303
:ok
@@ -2257,7 +2307,8 @@ defmodule BACnet.Stack.Client do
22572307

22582308
term ->
22592309
raise ArgumentError,
2260-
"start_link/1 expected apdu_retries to be a non negative integer, " <>
2310+
mfa <>
2311+
" expected apdu_retries to be a non negative integer, " <>
22612312
"got: #{inspect(term)}"
22622313
end
22632314

@@ -2270,7 +2321,8 @@ defmodule BACnet.Stack.Client do
22702321

22712322
term ->
22722323
raise ArgumentError,
2273-
"start_link/1 expected apdu_timeout to be a positive integer, " <>
2324+
mfa <>
2325+
" expected apdu_timeout to be a positive integer, " <>
22742326
"got: #{inspect(term)}"
22752327
end
22762328

@@ -2283,7 +2335,8 @@ defmodule BACnet.Stack.Client do
22832335

22842336
term ->
22852337
raise ArgumentError,
2286-
"start_link/1 expected disable_app_timeout to be a boolean, " <>
2338+
mfa <>
2339+
" expected disable_app_timeout to be a boolean, " <>
22872340
"got: #{inspect(term)}"
22882341
end
22892342

@@ -2296,7 +2349,8 @@ defmodule BACnet.Stack.Client do
22962349

22972350
term ->
22982351
raise ArgumentError,
2299-
"start_link/1 expected disable_invoke_id_management to be a boolean, " <>
2352+
mfa <>
2353+
" expected disable_invoke_id_management to be a boolean, " <>
23002354
"got: #{inspect(term)}"
23012355
end
23022356

@@ -2323,13 +2377,15 @@ defmodule BACnet.Stack.Client do
23232377
(is_tuple(&1) and tuple_size(&1) == 2))
23242378
) do
23252379
raise ArgumentError,
2326-
"start_link/1 expected notification_receiver to be a Process destination or " <>
2380+
mfa <>
2381+
" expected notification_receiver to be a Process destination or " <>
23272382
"list of Process destinations, got: #{inspect(term)}"
23282383
end
23292384

23302385
term ->
23312386
raise ArgumentError,
2332-
"start_link/1 expected notification_receiver to be a Process destination or " <>
2387+
mfa <>
2388+
" expected notification_receiver to be a Process destination or " <>
23332389
"list of Process destinations, got: #{inspect(term)}"
23342390
end
23352391

@@ -2342,7 +2398,8 @@ defmodule BACnet.Stack.Client do
23422398

23432399
term ->
23442400
raise ArgumentError,
2345-
"start_link/1 expected npci_source to be a NpciTarget, " <>
2401+
mfa <>
2402+
" expected npci_source to be a NpciTarget, " <>
23462403
"got: #{inspect(term)}"
23472404
end
23482405

@@ -2361,7 +2418,8 @@ defmodule BACnet.Stack.Client do
23612418

23622419
term ->
23632420
raise ArgumentError,
2364-
"start_link/1 expected segmentator to be a GenServer name, " <>
2421+
mfa <>
2422+
" expected segmentator to be a GenServer name, " <>
23652423
"got: #{inspect(term)}"
23662424
end
23672425

@@ -2380,7 +2438,8 @@ defmodule BACnet.Stack.Client do
23802438

23812439
term ->
23822440
raise ArgumentError,
2383-
"start_link/1 expected segments_store to be a GenServer name, " <>
2441+
mfa <>
2442+
" expected segments_store to be a GenServer name, " <>
23842443
"got: #{inspect(term)}"
23852444
end
23862445

@@ -2393,7 +2452,8 @@ defmodule BACnet.Stack.Client do
23932452

23942453
term ->
23952454
raise ArgumentError,
2396-
"start_link/1 expected segmented_rcv_window_overwrite to be a boolean, " <>
2455+
mfa <>
2456+
" expected segmented_rcv_window_overwrite to be a boolean, " <>
23972457
"got: #{inspect(term)}"
23982458
end
23992459

@@ -2420,29 +2480,32 @@ defmodule BACnet.Stack.Client do
24202480

24212481
term ->
24222482
raise ArgumentError,
2423-
"start_link/1 expected transport to be a tuple of module name " <>
2483+
mfa <>
2484+
" expected transport to be a tuple of module name " <>
24242485
"and TransportBehaviour.transport(), got: #{inspect(term)}"
24252486
end
24262487

2427-
# Unwrap the transport module name
2428-
{transport_mod, _pid} =
2429-
case transport do
2430-
{mod, pid} -> {mod, pid}
2431-
mod -> {mod, nil}
2432-
end
2488+
if not skip_check do
2489+
# Unwrap the transport module name
2490+
{transport_mod, _pid} =
2491+
case transport do
2492+
{mod, pid} -> {mod, pid}
2493+
mod -> {mod, nil}
2494+
end
24332495

2434-
unless Code.ensure_loaded?(transport_mod) do
2435-
raise ArgumentError, "Given transport module #{inspect(transport_mod)} is not loaded"
2436-
end
2496+
unless Code.ensure_loaded?(transport_mod) do
2497+
raise ArgumentError, "Given transport module #{inspect(transport_mod)} is not loaded"
2498+
end
24372499

2438-
unless Enum.any?(transport_mod.__info__(:attributes), fn
2439-
{:behaviour, TransportBehaviour} -> true
2440-
{:behaviour, [TransportBehaviour]} -> true
2441-
_else -> false
2442-
end) do
2443-
raise ArgumentError,
2444-
"Given transport module #{inspect(transport_mod)} does not " <>
2445-
"implement the BACnet transport behaviour"
2500+
unless Enum.any?(transport_mod.__info__(:attributes), fn
2501+
{:behaviour, TransportBehaviour} -> true
2502+
{:behaviour, [TransportBehaviour]} -> true
2503+
_else -> false
2504+
end) do
2505+
raise ArgumentError,
2506+
"Given transport module #{inspect(transport_mod)} does not " <>
2507+
"implement the BACnet transport behaviour"
2508+
end
24462509
end
24472510
end
24482511

0 commit comments

Comments
 (0)