Skip to content

Commit 48becd6

Browse files
author
CI
committed
Sync to GitHub
1 parent 6eadfe6 commit 48becd6

3 files changed

Lines changed: 100 additions & 46 deletions

File tree

lib/bacnet/beam_types.ex

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ defmodule BACnet.BeamTypes do
152152
def check_type({:tuple, subtypes}, value) when is_list(subtypes) and is_tuple(value) do
153153
if length(subtypes) == tuple_size(value) do
154154
subtypes
155-
|> Enum.with_index()
155+
|> Stream.with_index()
156156
|> Enum.all?(fn {spec, index} ->
157157
check_type(spec, elem(value, index))
158158
end)
@@ -190,7 +190,6 @@ defmodule BACnet.BeamTypes do
190190
raise ArgumentError, "Unknown type: #{inspect(type)}"
191191
end
192192

193-
# This clause is needed to prevent an infinite loop
194193
defp check_type_validator(type, validator, value) do
195194
if is_function(validator, 1) do
196195
check_type(type, value) and validator.(value)

lib/bacnet/stack/transport/mstp_transport.ex

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2734,17 +2734,26 @@ if Code.ensure_loaded?(Circuits.UART) do
27342734
header = [3, destination, state.local_address, <<data_len::size(16)>>]
27352735
header_crc = EncodingTools.calculate_header_crc(header, 0xFF)
27362736

2737-
# We need ones-complement of the DataCRC
2738-
data_crc = 0xFFFF - EncodingTools.calculate_data_crc(data, 0xFFFF)
2737+
data_payload =
2738+
if data_len > 0 do
2739+
# We need ones-complement of the DataCRC
2740+
data_crc = 0xFFFF - EncodingTools.calculate_data_crc(data, 0xFFFF)
2741+
2742+
[
2743+
data,
2744+
Bitwise.band(data_crc, 0xFF),
2745+
Bitwise.bsr(data_crc, 8)
2746+
]
2747+
else
2748+
[]
2749+
end
27392750

27402751
payload = [
27412752
@mstp_start_byte,
27422753
@mstp_preamble_byte,
27432754
header,
27442755
header_crc,
2745-
data,
2746-
Bitwise.band(data_crc, 0xFF),
2747-
Bitwise.bsr(data_crc, 8)
2756+
data_payload
27482757
]
27492758

27502759
send_uart_data(state, payload)
@@ -2764,17 +2773,26 @@ if Code.ensure_loaded?(Circuits.UART) do
27642773
header = [4, state_data.source_address, state.local_address, <<data_len::size(16)>>]
27652774
header_crc = EncodingTools.calculate_header_crc(header, 0xFF)
27662775

2767-
# We need ones-complement of the DataCRC
2768-
data_crc = 0xFFFF - EncodingTools.calculate_data_crc(data, 0xFFFF)
2776+
data_payload =
2777+
if data_len > 0 do
2778+
# We need ones-complement of the DataCRC
2779+
data_crc = 0xFFFF - EncodingTools.calculate_data_crc(data, 0xFFFF)
2780+
2781+
[
2782+
data,
2783+
Bitwise.band(data_crc, 0xFF),
2784+
Bitwise.bsr(data_crc, 8)
2785+
]
2786+
else
2787+
[]
2788+
end
27692789

27702790
payload = [
27712791
@mstp_start_byte,
27722792
@mstp_preamble_byte,
27732793
header,
27742794
header_crc,
2775-
data,
2776-
Bitwise.band(data_crc, 0xFF),
2777-
Bitwise.bsr(data_crc, 8)
2795+
data_payload
27782796
]
27792797

27802798
send_uart_data(state, payload)
@@ -2787,25 +2805,34 @@ if Code.ensure_loaded?(Circuits.UART) do
27872805
data_len = IO.iodata_length(data)
27882806

27892807
log_debug_comm(state, fn ->
2790-
"BacMstpTransport: Sending BACnet-Data-Expecting-Reply to MS/TP network " <>
2808+
"BacMstpTransport: Sending BACnet-Data-Expecting-Reply to MS/TP network " <>
27912809
"with destination #{destination} " <>
27922810
"and data length #{data_len} bytes"
27932811
end)
27942812

27952813
header = [5, destination, state.local_address, <<data_len::size(16)>>]
27962814
header_crc = EncodingTools.calculate_header_crc(header, 0xFF)
27972815

2798-
# We need ones-complement of the DataCRC
2799-
data_crc = 0xFFFF - EncodingTools.calculate_data_crc(data, 0xFFFF)
2816+
data_payload =
2817+
if data_len > 0 do
2818+
# We need ones-complement of the DataCRC
2819+
data_crc = 0xFFFF - EncodingTools.calculate_data_crc(data, 0xFFFF)
2820+
2821+
[
2822+
data,
2823+
Bitwise.band(data_crc, 0xFF),
2824+
Bitwise.bsr(data_crc, 8)
2825+
]
2826+
else
2827+
[]
2828+
end
28002829

28012830
payload = [
28022831
@mstp_start_byte,
28032832
@mstp_preamble_byte,
28042833
header,
28052834
header_crc,
2806-
data,
2807-
Bitwise.band(data_crc, 0xFF),
2808-
Bitwise.bsr(data_crc, 8)
2835+
data_payload
28092836
]
28102837

28112838
send_uart_data(state, payload)
@@ -2826,20 +2853,26 @@ if Code.ensure_loaded?(Circuits.UART) do
28262853
header = [6, destination, state.local_address, <<data_len::size(16)>>]
28272854
header_crc = EncodingTools.calculate_header_crc(header, 0xFF)
28282855

2829-
data_crc =
2830-
data
2831-
|> EncodingTools.calculate_data_crc(0xFFFF)
2832-
|> Bitwise.bnot()
2833-
|> Bitwise.band(0xFFFF)
2856+
data_payload =
2857+
if data_len > 0 do
2858+
# We need ones-complement of the DataCRC
2859+
data_crc = 0xFFFF - EncodingTools.calculate_data_crc(data, 0xFFFF)
2860+
2861+
[
2862+
data,
2863+
Bitwise.band(data_crc, 0xFF),
2864+
Bitwise.bsr(data_crc, 8)
2865+
]
2866+
else
2867+
[]
2868+
end
28342869

28352870
payload = [
28362871
@mstp_start_byte,
28372872
@mstp_preamble_byte,
28382873
header,
28392874
header_crc,
2840-
data,
2841-
Bitwise.band(data_crc, 0xFF),
2842-
Bitwise.bsr(data_crc, 8)
2875+
data_payload
28432876
]
28442877

28452878
send_uart_data(state, payload)

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

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -619,28 +619,50 @@ if Code.ensure_loaded?(Circuits.UART) do
619619
data_crc_header: Bitwise.bsl(state_data.data_crc_header, 8) + crc
620620
}
621621

622-
if state_data.data_crc == 0xF0B8 do
623-
log_debug_comm(state_data, fn ->
624-
"BacMstpTransport_ReceiveFSM: Received valid frame of type #{state_data.frame_type} " <>
625-
"with data length #{state_data.data_length}"
626-
end)
622+
cond do
623+
state_data.data_crc == 0xF0B8 ->
624+
log_debug_comm(state_data, fn ->
625+
"BacMstpTransport_ReceiveFSM: Received valid frame of type #{state_data.frame_type} " <>
626+
"with data length #{state_data.data_length}"
627+
end)
627628

628-
handle_mstp_frame(
629-
%{
630-
state_data
631-
| input_buffer: IO.iodata_to_binary(Enum.reverse(state_data.input_buffer)),
632-
data_crc_header: 0,
633-
received_invalid_frame: false,
634-
received_valid_frame: true
635-
},
636-
rest
637-
)
638-
else
639-
Logger.warning(fn ->
640-
"BacMstpTransport_ReceiveFSM: Received frame with bad data - moving to IDLE"
641-
end)
629+
handle_mstp_frame(
630+
%{
631+
state_data
632+
| input_buffer: IO.iodata_to_binary(Enum.reverse(state_data.input_buffer)),
633+
data_crc_header: 0,
634+
received_invalid_frame: false,
635+
received_valid_frame: true
636+
},
637+
rest
638+
)
639+
640+
state_data.frame_type == :test_request ->
641+
log_debug_comm(state_data, fn ->
642+
"BacMstpTransport_ReceiveFSM: Received frame of type #{state_data.frame_type} " <>
643+
"with data length #{state_data.data_length}, but data CRC does not match, " <>
644+
"data will be dropped and frame will propagate without data"
645+
end)
646+
647+
handle_mstp_frame(
648+
%{
649+
state_data
650+
| input_buffer: [],
651+
data_length: 0,
652+
data_crc: 0,
653+
data_crc_header: 0,
654+
received_invalid_frame: false,
655+
received_valid_frame: true
656+
},
657+
rest
658+
)
642659

643-
handle_receive_invalid_or_timeout(state_data, true, rest)
660+
true ->
661+
Logger.warning(fn ->
662+
"BacMstpTransport_ReceiveFSM: Received frame with bad data - moving to IDLE"
663+
end)
664+
665+
handle_receive_invalid_or_timeout(state_data, true, rest)
644666
end
645667
end
646668

0 commit comments

Comments
 (0)