This commit is contained in:
anlicheng 2025-04-21 16:30:28 +08:00
parent bdae5c0fdf
commit c3132fb478
7 changed files with 3089 additions and 3 deletions

View File

@ -0,0 +1,134 @@
%% -*- coding: utf-8 -*-
%% Automatically generated, do not edit
%% Generated by gpb_compile version 4.21.1
-ifndef(message_pb).
-define(message_pb, true).
-define(message_pb_gpb_version, "4.21.1").
-ifndef('AUTH_REQUEST_PB_H').
-define('AUTH_REQUEST_PB_H', true).
-record(auth_request,
{uuid = <<>> :: unicode:chardata() | undefined, % = 1, optional
username = <<>> :: unicode:chardata() | undefined, % = 2, optional
password = <<>> :: unicode:chardata() | undefined, % = 3, optional
salt = <<>> :: unicode:chardata() | undefined, % = 4, optional
token = <<>> :: unicode:chardata() | undefined, % = 5, optional
timestamp = 0 :: non_neg_integer() | undefined % = 6, optional, 32 bits
}).
-endif.
-ifndef('AUTH_REPLY_PB_H').
-define('AUTH_REPLY_PB_H', true).
-record(auth_reply,
{code = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
message = <<>> :: unicode:chardata() | undefined % = 2, optional
}).
-endif.
-ifndef('SESSION_REQUEST_PB_H').
-define('SESSION_REQUEST_PB_H', true).
-record(session_request,
{
}).
-endif.
-ifndef('SESSION_REPLY_PB_H').
-define('SESSION_REPLY_PB_H', true).
-record(session_reply,
{a = false :: boolean() | 0 | 1 | undefined % = 1, optional
}).
-endif.
-ifndef('DATA_PB_H').
-define('DATA_PB_H', true).
-record(data,
{device_uuid = <<>> :: unicode:chardata() | undefined, % = 1, optional
service_name = <<>> :: unicode:chardata() | undefined, % = 2, optional
at = 0 :: integer() | undefined, % = 3, optional, 32 bits
tags = [] :: [{unicode:chardata(), unicode:chardata()}] | undefined, % = 4
fields = [] :: [iodata()] | undefined % = 5, repeated
}).
-endif.
-ifndef('PING_PB_H').
-define('PING_PB_H', true).
-record(ping,
{adcode = <<>> :: unicode:chardata() | undefined, % = 1, optional
boot_time = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits
province = <<>> :: unicode:chardata() | undefined, % = 3, optional
city = <<>> :: unicode:chardata() | undefined, % = 4, optional
efka_version = <<>> :: unicode:chardata() | undefined, % = 5, optional
kernel_arch = <<>> :: unicode:chardata() | undefined, % = 6, optional
ips = [] :: [unicode:chardata()] | undefined, % = 7, repeated
cpu_core = 0 :: non_neg_integer() | undefined, % = 8, optional, 32 bits
cpu_load = 0 :: non_neg_integer() | undefined, % = 9, optional, 32 bits
cpu_temperature = 0.0 :: float() | integer() | infinity | '-infinity' | nan | undefined, % = 10, optional
disk = [] :: [integer()] | undefined, % = 11, repeated, 32 bits
memory = [] :: [integer()] | undefined, % = 12, repeated, 32 bits
interfaces = [] :: [iodata()] | undefined % = 13, repeated
}).
-endif.
-ifndef('SERVICE_INFORM_PB_H').
-define('SERVICE_INFORM_PB_H', true).
-record(service_inform,
{name = <<>> :: unicode:chardata() | undefined, % = 1, optional
props = <<>> :: unicode:chardata() | undefined, % = 2, optional
version = <<>> :: unicode:chardata() | undefined, % = 3, optional
version_copy = <<>> :: unicode:chardata() | undefined, % = 4, optional
status = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits
at = 0 :: non_neg_integer() | undefined % = 6, optional, 32 bits
}).
-endif.
-ifndef('FEEDBACK_STEP_PB_H').
-define('FEEDBACK_STEP_PB_H', true).
-record(feedback_step,
{task_id = <<>> :: unicode:chardata() | undefined, % = 1, optional
code = 0 :: non_neg_integer() | undefined % = 2, optional, 32 bits
}).
-endif.
-ifndef('FEEDBACK_RESULT_PB_H').
-define('FEEDBACK_RESULT_PB_H', true).
-record(feedback_result,
{task_id = <<>> :: unicode:chardata() | undefined, % = 1, optional
task_type = <<>> :: unicode:chardata() | undefined, % = 2, optional
time = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits
code = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits
reason = <<>> :: unicode:chardata() | undefined, % = 5, optional
error = <<>> :: unicode:chardata() | undefined % = 6, optional
}).
-endif.
-ifndef('EVENT_PB_H').
-define('EVENT_PB_H', true).
-record(event,
{event_type = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
params = <<>> :: iodata() | undefined % = 2, optional
}).
-endif.
-ifndef('AI_EVENT_PB_H').
-define('AI_EVENT_PB_H', true).
-record(ai_event,
{event_type = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
params = <<>> :: iodata() | undefined % = 2, optional
}).
-endif.
-ifndef('DIRECTIVE_PB_H').
-define('DIRECTIVE_PB_H', true).
-record(directive,
{device_uuid = <<>> :: unicode:chardata() | undefined, % = 1, optional
version = <<>> :: unicode:chardata() | undefined, % = 2, optional
directive_type = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits
timeout = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits
directive = <<>> :: iodata() | undefined % = 5, optional
}).
-endif.
-endif.

View File

@ -8,6 +8,7 @@
%%%-------------------------------------------------------------------
-module(efka_agent).
-author("anlicheng").
-include("message_pb.hrl").
-behaviour(gen_server).

View File

@ -0,0 +1,41 @@
%%%-------------------------------------------------------------------
%%% @author anlicheng
%%% @copyright (C) 2025, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 21. 4 2025 16:18
%%%-------------------------------------------------------------------
-module(efka_codec).
-author("anlicheng").
-include("message_pb.hrl").
%%
-define(PACKET_REQUEST, 16#01).
-define(PACKET_RESPONSE, 16#02).
%%
-define(PACKET_PUBLISH, 16#03).
-define(PACKET_PUBLISH_RESPONSE, 16#04).
%% API
-export([auth_request/1]).
-spec auth_request(PacketId :: integer()) -> binary().
auth_request(PacketId) when is_integer(PacketId), PacketId > 0 ->
{ok, AuthInfo} = application:get_env(efka, auth),
UUID = proplists:get_value(uuid, AuthInfo),
Username = proplists:get_value(username, AuthInfo),
Password = proplists:get_value(password, AuthInfo),
Salt = proplists:get_value(salt, AuthInfo),
Token = proplists:get_value(token, AuthInfo),
RequestBin = message_pb:encode_msg(#auth_request{
uuid = unicode:characters_to_binary(UUID),
username = unicode:characters_to_binary(Username),
password = unicode:characters_to_binary(Password),
salt = unicode:characters_to_binary(Salt),
token = unicode:characters_to_binary(Token),
timestamp = efka_util:timestamp()
}),
<<?PACKET_REQUEST, PacketId:32, RequestBin/binary>>.

View File

@ -11,8 +11,88 @@
%% API
-export([get_file_md5/1]).
-export([timestamp/0, number_format/2, timestamp_ms/0, float_to_binary/2, int_format/2]).
-export([chunks/2, rand_bytes/1, uuid/0, md5/1]).
-export([json_data/1, json_error/2]).
get_file_md5(FilePath) when is_list(FilePath) ->
{ok, FileData} = file:read_file(FilePath),
Md5Binary = crypto:hash(md5, FileData),
string:lowercase(lists:flatten([io_lib:format("~2.16.0b", [X]) || X <- binary_to_list(Md5Binary)])).
%%
timestamp_ms() ->
{Mega, Seconds, Micro} = os:timestamp(),
(Mega * 1000000 + Seconds) * 1000 + Micro div 1000.
timestamp() ->
{Mega, Seconds, _Micro} = os:timestamp(),
Mega * 1000000 + Seconds.
number_format(Num, _Decimals) when is_integer(Num) ->
Num;
number_format(Float, Decimals) when is_float(Float) ->
list_to_float(float_to_list(Float, [{decimals, Decimals}, compact])).
int_format(Num, Len) when is_integer(Num), Len > 0 ->
S = integer_to_list(Num),
case length(S) > Len of
true ->
list_to_integer(lists:sublist(S, 1, Len));
false ->
Num
end.
%%
-spec chunks(list(), integer()) -> [list()].
chunks(List, Size) when is_list(List), is_integer(Size), Size > 0, length(List) =< Size ->
[List];
chunks(List, Size) when is_list(List), is_integer(Size), Size > 0 ->
chunks0(List, Size, Size, [], []).
chunks0([], _, _, [], AccTarget) ->
lists:reverse(AccTarget);
chunks0([], _, _, Target, AccTarget) ->
lists:reverse([lists:reverse(Target) | AccTarget]);
chunks0(List, Size, 0, Target, AccTarget) ->
chunks0(List, Size, Size, [], [lists:reverse(Target) | AccTarget]);
chunks0([Hd | Tail], Size, Num, Target, AccTarget) ->
chunks0(Tail, Size, Num - 1, [Hd | Target], AccTarget).
json_data(Data) ->
jiffy:encode(#{
<<"result">> => Data
}, [force_utf8]).
json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) ->
jiffy:encode(#{
<<"error">> => #{
<<"code">> => ErrCode,
<<"message">> => ErrMessage
}
}, [force_utf8]).
uuid() ->
rand_bytes(16).
-spec rand_bytes(Size :: integer()) -> string().
rand_bytes(Size) when is_integer(Size), Size > 0 ->
Size1 = erlang:ceil(Size / 2),
Bytes = crypto:strong_rand_bytes(Size1),
S = lists:flatten([integer_to_list(E, 16) || <<E:4>> <= Bytes]),
lists:sublist(string:to_lower(S), 1, Size).
-spec md5(Str :: binary()) -> binary().
md5(Str) when is_binary(Str) ->
list_to_binary(lists:flatten([hex(X) || <<X:4>> <= erlang:md5(Str)])).
hex(N) when N < 10 ->
$0 + N;
hex(N) ->
$a + (N - 10).
-spec float_to_binary(Num :: number(), integer()) -> binary().
float_to_binary(V, _) when is_integer(V) ->
integer_to_binary(V);
float_to_binary(V, Decimals) when is_float(V), is_integer(Decimals) ->
S = float_to_list(V, [{decimals, Decimals}, compact]),
list_to_binary(S).

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,16 @@
{tls_server, [
{host, "localhost"},
{port, 443}
]},
{auth, [
{uuid, "uuid1234"},
{username, "test"},
{password, "password1234"},
{salt, "salt2345"},
{token, "token124"}
]}
]},
%% 系统日志配置系统日志为lager, 支持日志按日期自动分割

View File

@ -10,5 +10,5 @@ sed -i '' 's/include(\"gpb.hrl\")/include_lib(\"gpb\/include\/gpb.hrl\")/g' mess
#sed -i '' 's/sdlv_4_info/sdl_v4_info/g' sdlan_pb.erl
#sed -i '' 's/sdlv_6_info/sdl_v6_info/g' sdlan_pb.erl
mv message_pb.hrl ./apps/efka/include
mv message_pb.erl ./apps/efka/src
mv message_pb.hrl ./apps/efka/include/
mv message_pb.erl ./apps/efka/src/proto/