diff --git a/apps/iot/include/iot.hrl b/apps/iot/include/iot.hrl index 8a2353e..d45b7fc 100644 --- a/apps/iot/include/iot.hrl +++ b/apps/iot/include/iot.hrl @@ -66,28 +66,8 @@ update_ts = 0 :: integer() }). -%% 主机定义 --record(host, { - %% ID - id :: binary(), - %% 名称 - name :: binary(), - %% 型号 - model :: binary(), - %% 单元网格编号 - cell_id :: integer(), - %% 接入时间 - activated_ts = 0 :: integer(), - %% 最后上线时间 - update_ts = 0 :: integer(), - %% 主机状态 - status = ?HOST_STATUS_INACTIVE :: integer() -}). - %% 主机指标, 主机和指标之间是一对一的关系,可以分离出新的表 -record(host_metric, { - %% ID - host_id :: binary(), %% cpu相关 cpus = [], %% cpu温度 @@ -100,6 +80,27 @@ interfaces = [] }). +%% 主机定义 +-record(host, { + %% ID + id :: binary(), + %% 名称 + name :: binary(), + %% 型号 + model :: binary(), + %% 单元网格编号 + cell_id :: integer(), + %% aes的key, 后续通讯需要基于这个加密 + aes :: binary(), + metric = #host_metric{}, + %% 接入时间 + activated_ts = 0 :: integer(), + %% 最后上线时间 + update_ts = 0 :: integer(), + %% 主机状态 + status = ?HOST_STATUS_INACTIVE :: integer() +}). + %% 终端设备表 -record(terminal, { %% 设备ID diff --git a/apps/iot/src/iot_cipher_aes.erl b/apps/iot/src/iot_cipher_aes.erl new file mode 100644 index 0000000..3bc1e80 --- /dev/null +++ b/apps/iot/src/iot_cipher_aes.erl @@ -0,0 +1,23 @@ +%%%------------------------------------------------------------------- +%%% @author aresei +%%% @copyright (C) 2018, +%%% @doc +%%% +%%% @end +%%% Created : 29. 六月 2018 09:30 +%%%------------------------------------------------------------------- +-module(iot_cipher_aes). +-author("aresei"). + +%% API +-export([encrypt/3, decrypt/3]). + +%% 基于aes的加密算法 +-spec encrypt(binary(), binary(), binary()) -> binary(). +encrypt(Key, IVec, PlainText) when is_binary(Key), is_binary(IVec), is_binary(PlainText) -> + crypto:crypto_one_time(aes_128_cfb128, Key, IVec, PlainText, true). + +%% 基于aes的解密算法 +-spec decrypt(binary(), binary(), binary()) -> binary(). +decrypt(Key, IVec, CipherText) when is_binary(Key), is_binary(IVec), is_binary(CipherText) -> + crypto:crypto_one_time(aes_128_cfb128, Key, IVec, CipherText, false). \ No newline at end of file diff --git a/apps/iot/src/iot_cipher_rsa.erl b/apps/iot/src/iot_cipher_rsa.erl new file mode 100644 index 0000000..613ba3a --- /dev/null +++ b/apps/iot/src/iot_cipher_rsa.erl @@ -0,0 +1,22 @@ +%%%------------------------------------------------------------------- +%%% @author aresei +%%% @copyright (C) 2018, +%%% @doc +%%% +%%% @end +%%% Created : 21. 六月 2018 09:51 +%%%------------------------------------------------------------------- +-module(iot_cipher_rsa). +-author("aresei"). + +%% API +-export([decode/1, encode/2]). + +%% 解密数据 +decode(EncBin) when is_binary(EncBin) -> + PrivateKey = private_key(), + public_key:decrypt_private(EncBin, PrivateKey). + +%% 解密数据 +encode(Data, PublicKey) when is_binary(Data), is_binary(PublicKey) -> + ok. \ No newline at end of file diff --git a/apps/iot/src/iot_message_handler.erl b/apps/iot/src/iot_message_handler.erl new file mode 100644 index 0000000..35f50c4 --- /dev/null +++ b/apps/iot/src/iot_message_handler.erl @@ -0,0 +1,93 @@ +%%%------------------------------------------------------------------- +%%% @author aresei +%%% @copyright (C) 2023, +%%% @doc +%%% +%%% @end +%%% Created : 18. 2月 2023 21:39 +%%%------------------------------------------------------------------- +-module(iot_message_handler). +-author("aresei"). +-include("iot.hrl"). + +%% API +-export([]). + +handle(<<"server.register">>, Msg = #{<<"c_id">> := ClientId, <<"r">> := PubKey, + <<"m">> := #{<<"cpu_core">> := CpuCore, <<"memory">> := Memory, <<"disk">> := Disk, <<"boot_time">> := BootTime, <<"efka_version">> := EfkaVersion, <<"kernel_arch">> := KernelArch, <<"ipv4_1">> := Ip1, <<"ipv4_2">> := Ip2}}) -> + + Aes = iot_util:rand_bytes(16), + Host = #host{ + id = ClientId, + aes = Aes, + metric = #host_metric{ + %% cpu相关 + cpus = [ + #cpu_metric{ + %% cpu编号 + num = 1, + %% 负载 + load = 0 + }, + #cpu_metric{ + %% cpu编号 + num = 2, + %% 负载 + load = 0 + } + ], + %% cpu温度 + cpu_temperature = 0, + %% 内存状态 + memory = #memory_metric{ + %% 使用量 + used = 0, + %% 总量 + total = Memory + }, + %% 硬盘状态 + disk = #disk_metric{ + total = Disk + }, + %% 接口状态 + interfaces = [] + }, + activated_ts = iot_util:current_time(), + update_ts = iot_util:current_time(), + status = ?HOST_STATUS_INACTIVE + }, + + case host_model:add_host(Host) of + ok -> + Reply = #{ + <<"a">> => true, + <<"aes">> => Aes, + <<"reply">> => <<"client.reply.", ClientId/binary>> + }, + EncReply = iot_cipher_rsa:encode(Reply, PubKey), + lager:debug("enc_reply is: ~p", [EncReply]); + {error, Reason} -> + lager:debug("register error is: ~p", [Reason]), + Reply = #{ + <<"a">> => false, + <<"aes">> => <<"">>, + <<"reply">> => <<"client.reply.", ClientId/binary>> + }, + EncReply = iot_cipher_rsa:encode(Reply, PubKey), + lager:debug("enc_reply is: ~p", [EncReply]) + end; + +handle(<<"server.data">>, #{<<"c_id">> := HostId, <<"d">> := Data}) -> + {ok, Host = #host{aes = Aes}} = host_model:get_host(HostId), + + PlainData = iot_cipher_aes:decrypt(Aes, Aes, Data), + case jiffy:decode(PlainData, [return_maps]) of + Metrics when is_list(Metrics) -> + lager:debug("the metric is: ~p", [Metrics]), + ok; + _ -> + lager:debug("the metric is invalid json") + end, + + + ok. \ No newline at end of file diff --git a/apps/iot/src/iot_mnesia.erl b/apps/iot/src/iot_mnesia.erl index f890b6e..8db867d 100644 --- a/apps/iot/src/iot_mnesia.erl +++ b/apps/iot/src/iot_mnesia.erl @@ -32,14 +32,6 @@ init_database() -> {type, set} ]), - %% 主机指标 - mnesia:create_table(host_metric, [ - {attributes, record_info(fields, host_metric)}, - {record_name, host_metric}, - {disc_copies, [node()]}, - {type, set} - ]), - %% 主机终端管理 mnesia:create_table(terminal, [ {attributes, record_info(fields, terminal)}, @@ -75,7 +67,6 @@ copy_database(MasterNode) when is_atom(MasterNode) -> %% 增加表的分区复制 mnesia:add_table_copy(host, node(), ram_copies), - mnesia:add_table_copy(host_metric, node(), ram_copies), mnesia:add_table_copy(terminal, node(), ram_copies), mnesia:add_table_copy(microservice, node(), ram_copies), ok. \ No newline at end of file diff --git a/apps/iot/src/iot_util.erl b/apps/iot/src/iot_util.erl index 261be32..41390d6 100644 --- a/apps/iot/src/iot_util.erl +++ b/apps/iot/src/iot_util.erl @@ -11,7 +11,7 @@ %% API -export([timestamp/0, number_format/2, current_time/0]). --export([step/3, chunks/2, rand_bytes/1]). +-export([step/3, chunks/2, rand_bytes/1, uuid/0]). -export([json_data/1, json_error/2]). -export([queue_limited_in/3]). @@ -64,6 +64,9 @@ json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) } }, [force_utf8]). +uuid() -> + rand_bytes(16). + rand_bytes(Size) when is_integer(Size) -> Bytes = crypto:strong_rand_bytes(Size), S = lists:flatten([integer_to_list(E, 16) || <> <= Bytes]), diff --git a/apps/iot/src/model/host_model.erl b/apps/iot/src/model/host_model.erl index 5787f1c..8bd1dfa 100644 --- a/apps/iot/src/model/host_model.erl +++ b/apps/iot/src/model/host_model.erl @@ -12,7 +12,15 @@ -include_lib("stdlib/include/qlc.hrl"). %% API --export([get_hosts/2, insert/4, change_status/2, delete/1, table_size/0, filter_hosts/3]). +-export([get_host/1, get_hosts/2, add_host/1, change_status/2, delete/1, table_size/0, filter_hosts/3]). + +get_host(HostId) when is_binary(HostId) -> + case mnesia:dirty_read(host, HostId) of + [Host = #host{}] -> + {ok, Host}; + _ -> + undefined + end. %% 获取app信息 get_hosts(Start, Limit) when is_integer(Limit), is_integer(Start), Start >= 0, Limit > 0 -> @@ -57,16 +65,7 @@ filter_hosts(Pred, Start, Limit) when is_function(Pred, 1), is_integer(Limit), i Error end. -insert(Id, Name, Model, CellId) -> - Host = #host{ - id = Id, - name = Name, - model = Model, - cell_id = CellId, - update_ts = 0, - status = ?HOST_STATUS_INACTIVE - }, - +add_host(Host = #host{}) -> case mnesia:transaction(fun() -> mnesia:write(host, Host, write) end) of {atomic, _} -> ok;