fix parser

This commit is contained in:
anlicheng 2025-06-13 16:46:20 +08:00
parent df3e7c4346
commit f8fd7d0c43
4 changed files with 93 additions and 8 deletions

View File

@ -0,0 +1,33 @@
%%%-------------------------------------------------------------------
%%% @author anlicheng
%%% @copyright (C) 2025, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 13. 6 2025 15:08
%%%-------------------------------------------------------------------
-module(modbus_crc).
-author("anlicheng").
%% CRC16 constants
-define(CRC_POLY, 16#A001).
-export([crc16/1]).
-spec crc16(binary()) -> binary().
crc16(Data) ->
crc16(Data, 16#FFFF).
crc16(<<>>, CRC) ->
<<CRC:16/little>>;
crc16(<<Byte:8, Rest/binary>>, CRC0) ->
CRC1 = CRC0 bxor Byte,
CRC2 = lists:foldl(fun(_, C) ->
if C band 1 =:= 1 -> (C bsr 1) bxor ?CRC_POLY;
true -> C bsr 1
end
end,
CRC1,
lists:seq(1,8)),
crc16(Rest, CRC2).

View File

@ -150,8 +150,8 @@ parse_ast0(#block{ident = <<"modbus">>, props = Props}) ->
MapProps = parse_ast1(Props), MapProps = parse_ast1(Props),
#modbus { #modbus {
transport = maps:get(<<"transport">>, MapProps, undefined), transport = maps:get(<<"transport">>, MapProps, undefined),
access_log = maps:get(<<"access_log">>, MapProps, undefined), access_log = map_of_string(<<"access_log">>, MapProps, undefined),
error_log = maps:get(<<"error_log">>, MapProps, undefined) error_log = map_of_string(<<"error_log">>, MapProps, undefined)
}; };
parse_ast0(#block{ident = <<"device", Name0/binary>>, props = Props}) -> parse_ast0(#block{ident = <<"device", Name0/binary>>, props = Props}) ->
MapProps = parse_ast1(Props), MapProps = parse_ast1(Props),
@ -213,9 +213,9 @@ parse_ast1([#block{ident = <<"transport", Name0/binary>>, props = Props}|T], Acc
}; };
<<"tcp">> -> <<"tcp">> ->
#modbus_transport_tcp { #modbus_transport_tcp {
host = maps:get(<<"host">>, PropsMap, undefined), host = map_of_string(<<"host">>, PropsMap, undefined),
port = maps:get(<<"port">>, PropsMap, undefined), port = map_of_integer(<<"port">>, PropsMap, undefined),
timeout = maps:get(<<"timeout">>, PropsMap, undefined) timeout = map_of_time(<<"timeout">>, PropsMap, undefined)
} }
end, end,
parse_ast1(T, [{<<"transport">>, Transport}|Acc]). parse_ast1(T, [{<<"transport">>, Transport}|Acc]).
@ -260,3 +260,31 @@ map_of_integer(Key, M, Def) ->
Def Def
end. end.
map_of_string(Key, M, Def) ->
case maps:is_key(Key, M) of
true ->
[Val0] = maps:get(Key, M),
binary_to_list(Val0);
false ->
Def
end.
map_of_time(Key, M, Def) ->
case maps:is_key(Key, M) of
true ->
[Val0] = maps:get(Key, M),
case re:run(Val0, <<"^(\\d+(?:\\.\\d+)?)(\\D+)$">>, [{capture, all_but_first, binary}]) of
{match, [Val, Unit]} ->
Digit = binary_to_integer(Val),
case Unit of
<<"ms">> ->
Digit;
<<"s">> ->
Digit * 1000
end;
_ ->
Def
end;
false ->
Def
end.

View File

@ -14,6 +14,7 @@
%% API %% API
-export([start_link/1]). -export([start_link/1]).
-export([test/0]).
%% gen_server callbacks %% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
@ -24,6 +25,12 @@
}). }).
test() ->
{ok, Config} = file:read_file("/usr/local/code/cloudkit/modbus/modbus.conf"),
%lager:debug("config is: ~ts", [Config]),
{ok, AST} = modbus_parser:parse(Config),
start_link(AST).
%%%=================================================================== %%%===================================================================
%%% API %%% API
%%%=================================================================== %%%===================================================================
@ -32,7 +39,7 @@
-spec(start_link(AST :: #ast{}) -> -spec(start_link(AST :: #ast{}) ->
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}). {ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
start_link(AST) -> start_link(AST) ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). gen_server:start_link(?MODULE, [AST], []).
%%%=================================================================== %%%===================================================================
%%% gen_server callbacks %%% gen_server callbacks
@ -43,7 +50,10 @@ start_link(AST) ->
-spec(init(Args :: term()) -> -spec(init(Args :: term()) ->
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
{stop, Reason :: term()} | ignore). {stop, Reason :: term()} | ignore).
init([]) -> init([AST = #ast{modbus = Modbus}]) ->
lager:debug("modbus is: ~p", [Modbus]),
{ok, #state{}}. {ok, #state{}}.
%% @private %% @private
@ -98,3 +108,15 @@ code_change(_OldVsn, State = #state{}, _Extra) ->
%%%=================================================================== %%%===================================================================
%%% Internal functions %%% Internal functions
%%%=================================================================== %%%===================================================================
x(#modbus{transport = #modbus_transport_rtu{port = Port, baudrate = Baudrate, stopbits = Stopbits, timeout = Timeout}}) ->
ok;
x(#modbus{transport = #modbus_transport_tcp{host = Host, port = Port, timeout = Timeout0}}) ->
Timeout = case is_integer(Timeout0) andalso Timeout0 > 0 of
true ->
Timeout0;
false ->
2000
end,
gen_tcp:connect(Host, Port, [binary], Timeout).

View File

@ -1,5 +1,6 @@
{"1.2.0", {"1.2.0",
[{<<"fs">>,{pkg,<<"fs">>,<<"6.1.1">>},1}, [
{<<"fs">>,{pkg,<<"fs">>,<<"6.1.1">>},1},
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1}, {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
{<<"gpb">>, {<<"gpb">>,
{git,"https://github.com/tomas-abrahamsson/gpb.git", {git,"https://github.com/tomas-abrahamsson/gpb.git",
@ -17,6 +18,7 @@
{git,"https://github.com/uwiger/parse_trans", {git,"https://github.com/uwiger/parse_trans",
{ref,"6f3645afb43c7c57d61b54ef59aecab288ce1013"}}, {ref,"6f3645afb43c7c57d61b54ef59aecab288ce1013"}},
0}, 0},
{<<"sync">>, {<<"sync">>,
{git,"https://github.com/rustyio/sync.git", {git,"https://github.com/rustyio/sync.git",
{ref,"7dc303ed4ce8d26db82e171dbbd7c41067852c65"}}, {ref,"7dc303ed4ce8d26db82e171dbbd7c41067852c65"}},