fix
This commit is contained in:
parent
a219095670
commit
b607b90416
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
%% 心跳包检测时间间隔, 15分钟检测一次
|
%% 心跳包检测时间间隔, 15分钟检测一次
|
||||||
-define(HEARTBEAT_INTERVAL, 900 * 1000).
|
-define(HEARTBEAT_INTERVAL, 900 * 1000).
|
||||||
|
-define(AUTH_COMMAND_TIMEOUT, 10000).
|
||||||
|
|
||||||
%% 状态
|
%% 状态
|
||||||
-define(STATE_DENIED, denied).
|
-define(STATE_DENIED, denied).
|
||||||
@ -79,9 +80,9 @@ get_status(Pid) when is_pid(Pid) ->
|
|||||||
gen_statem:call(Pid, get_status).
|
gen_statem:call(Pid, get_status).
|
||||||
|
|
||||||
%% 激活主机, true 表示激活; false表示关闭激活
|
%% 激活主机, true 表示激活; false表示关闭激活
|
||||||
-spec activate(Pid :: pid(), Auth :: boolean()) -> ok.
|
-spec activate(Pid :: pid(), Auth :: boolean()) -> ok | {error, term()}.
|
||||||
activate(Pid, Auth) when is_pid(Pid), is_boolean(Auth) ->
|
activate(Pid, Auth) when is_pid(Pid), is_boolean(Auth) ->
|
||||||
gen_statem:call(Pid, {activate, Auth}).
|
gen_statem:call(Pid, {activate, Auth}, ?AUTH_COMMAND_TIMEOUT + 1000).
|
||||||
|
|
||||||
-spec get_metric(Pid :: pid()) -> {ok, MetricInfo :: map()}.
|
-spec get_metric(Pid :: pid()) -> {ok, MetricInfo :: map()}.
|
||||||
get_metric(Pid) when is_pid(Pid) ->
|
get_metric(Pid) when is_pid(Pid) ->
|
||||||
@ -248,23 +249,28 @@ handle_event({call, From}, {activate, true}, _, State = #state{uuid = UUID, chan
|
|||||||
case is_pid(ChannelPid) of
|
case is_pid(ChannelPid) of
|
||||||
true ->
|
true ->
|
||||||
logger:debug("[iot_host] uuid: ~p, activate: true", [UUID]),
|
logger:debug("[iot_host] uuid: ~p, activate: true", [UUID]),
|
||||||
ssl_channel:activate(ChannelPid, true);
|
start_auth_command(ChannelPid, true, From);
|
||||||
false ->
|
false ->
|
||||||
logger:debug("[iot_host] uuid: ~p, activate: true, no channel", [UUID])
|
logger:debug("[iot_host] uuid: ~p, activate: true, no channel", [UUID])
|
||||||
end,
|
end,
|
||||||
{next_state, ?STATE_ACTIVATED, State, [{reply, From, ok}]};
|
case is_pid(ChannelPid) of
|
||||||
|
true ->
|
||||||
|
{next_state, ?STATE_ACTIVATED, State};
|
||||||
|
false ->
|
||||||
|
{next_state, ?STATE_ACTIVATED, State, [{reply, From, ok}]}
|
||||||
|
end;
|
||||||
|
|
||||||
%% 关闭授权
|
%% 关闭授权
|
||||||
handle_event({call, From}, {activate, false}, _, State = #state{uuid = UUID, channel_pid = ChannelPid}) ->
|
handle_event({call, From}, {activate, false}, _, State = #state{uuid = UUID, channel_pid = ChannelPid}) ->
|
||||||
case is_pid(ChannelPid) of
|
case is_pid(ChannelPid) of
|
||||||
true ->
|
true ->
|
||||||
ssl_channel:activate(ChannelPid, false),
|
|
||||||
logger:debug("[iot_host] uuid: ~p, activate: false", [UUID]),
|
logger:debug("[iot_host] uuid: ~p, activate: false", [UUID]),
|
||||||
ssl_channel:stop(ChannelPid, closed);
|
start_auth_command(ChannelPid, false, From),
|
||||||
|
{keep_state, State};
|
||||||
false ->
|
false ->
|
||||||
logger:debug("[iot_host] uuid: ~p, activate: false, no channel", [UUID])
|
logger:debug("[iot_host] uuid: ~p, activate: false, no channel", [UUID]),
|
||||||
end,
|
{next_state, ?STATE_DENIED, State#state{channel_pid = undefined, has_session = false}, [{reply, From, ok}]}
|
||||||
{next_state, ?STATE_DENIED, State#state{channel_pid = undefined, has_session = false}, [{reply, From, ok}]};
|
end;
|
||||||
|
|
||||||
%% 绑定channel
|
%% 绑定channel
|
||||||
handle_event({call, From}, {attach_channel, ChannelPid}, StateName, State = #state{uuid = UUID, channel_pid = OldChannelPid}) ->
|
handle_event({call, From}, {attach_channel, ChannelPid}, StateName, State = #state{uuid = UUID, channel_pid = OldChannelPid}) ->
|
||||||
@ -304,6 +310,16 @@ handle_event(cast, {handle, {ping, Metrics}}, ?STATE_ACTIVATED, State = #state{u
|
|||||||
handle_event(cast, heartbeat, _, State = #state{heartbeat_counter = HeartbeatCounter}) ->
|
handle_event(cast, heartbeat, _, State = #state{heartbeat_counter = HeartbeatCounter}) ->
|
||||||
{keep_state, State#state{heartbeat_counter = HeartbeatCounter + 1}};
|
{keep_state, State#state{heartbeat_counter = HeartbeatCounter + 1}};
|
||||||
|
|
||||||
|
handle_event(info, {auth_command_result, From, true, _ChannelPid, ok}, _, State) ->
|
||||||
|
{keep_state, State, [{reply, From, ok}]};
|
||||||
|
handle_event(info, {auth_command_result, From, true, _ChannelPid, {error, Reason}}, _, State) ->
|
||||||
|
{keep_state, State, [{reply, From, {error, Reason}}]};
|
||||||
|
handle_event(info, {auth_command_result, From, false, ChannelPid, ok}, _, State) ->
|
||||||
|
ssl_channel:stop(ChannelPid, closed),
|
||||||
|
{next_state, ?STATE_DENIED, State#state{channel_pid = undefined, has_session = false}, [{reply, From, ok}]};
|
||||||
|
handle_event(info, {auth_command_result, From, false, _ChannelPid, {error, Reason}}, _, State) ->
|
||||||
|
{keep_state, State, [{reply, From, {error, Reason}}]};
|
||||||
|
|
||||||
%% 没有收到心跳包,主机下线, 设备状态不变
|
%% 没有收到心跳包,主机下线, 设备状态不变
|
||||||
handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{uuid = UUID, heartbeat_counter = 0, channel_pid = ChannelPid}) ->
|
handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{uuid = UUID, heartbeat_counter = 0, channel_pid = ChannelPid}) ->
|
||||||
logger:warning("[iot_host] uuid: ~p, heartbeat lost, devices will unknown", [UUID]),
|
logger:warning("[iot_host] uuid: ~p, heartbeat lost, devices will unknown", [UUID]),
|
||||||
@ -356,6 +372,15 @@ code_change(_OldVsn, StateName, State = #state{}, _Extra) ->
|
|||||||
container_call(Pid, Request) when is_pid(Pid) ->
|
container_call(Pid, Request) when is_pid(Pid) ->
|
||||||
gen_statem:call(Pid, {container_call, self(), Request}).
|
gen_statem:call(Pid, {container_call, self(), Request}).
|
||||||
|
|
||||||
|
-spec start_auth_command(pid(), boolean(), term()) -> pid().
|
||||||
|
start_auth_command(ChannelPid, Auth, From) when is_pid(ChannelPid), is_boolean(Auth) ->
|
||||||
|
HostPid = self(),
|
||||||
|
spawn(fun() ->
|
||||||
|
Ref = ssl_channel:activate(ChannelPid, Auth),
|
||||||
|
Result = iot_host:await_reply(HostPid, Ref, ?AUTH_COMMAND_TIMEOUT),
|
||||||
|
HostPid ! {auth_command_result, From, Auth, ChannelPid, Result}
|
||||||
|
end).
|
||||||
|
|
||||||
-spec get_route_key(binary()) -> binary().
|
-spec get_route_key(binary()) -> binary().
|
||||||
get_route_key(<<"">>) ->
|
get_route_key(<<"">>) ->
|
||||||
<<"/">>;
|
<<"/">>;
|
||||||
|
|||||||
@ -60,9 +60,7 @@ handle_request("POST", "/host/activate", _, #{<<"uuid">> := UUID, <<"auth">> :=
|
|||||||
{ok, 200, iot_util:json_error(400, <<"host not found">>)};
|
{ok, 200, iot_util:json_error(400, <<"host not found">>)};
|
||||||
{ok, Pid} when is_pid(Pid) ->
|
{ok, Pid} when is_pid(Pid) ->
|
||||||
logger:debug("[host_handler] activate host_id: ~p, start", [UUID]),
|
logger:debug("[host_handler] activate host_id: ~p, start", [UUID]),
|
||||||
ok = iot_host:activate(Pid, true),
|
auth_response(iot_host:activate(Pid, true))
|
||||||
|
|
||||||
{ok, 200, iot_util:json_data(<<"success">>)}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
%% 处理主机的授权的 取消激活
|
%% 处理主机的授权的 取消激活
|
||||||
@ -73,9 +71,7 @@ handle_request("POST", "/host/activate", _, #{<<"uuid">> := UUID, <<"auth">> :=
|
|||||||
{ok, 200, iot_util:json_error(400, <<"host not found">>)};
|
{ok, 200, iot_util:json_error(400, <<"host not found">>)};
|
||||||
{ok, Pid} when is_pid(Pid) ->
|
{ok, Pid} when is_pid(Pid) ->
|
||||||
logger:debug("[host_handler] activate host_id: ~p, start", [UUID]),
|
logger:debug("[host_handler] activate host_id: ~p, start", [UUID]),
|
||||||
ok = iot_host:activate(Pid, false),
|
auth_response(iot_host:activate(Pid, false))
|
||||||
|
|
||||||
{ok, 200, iot_util:json_data(<<"success">>)}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
%% 主机事件发布
|
%% 主机事件发布
|
||||||
@ -98,4 +94,31 @@ handle_request(_, Path, _, _) ->
|
|||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
%% helper methods
|
%% helper methods
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
auth_response(ok) ->
|
||||||
|
{ok, 200, iot_util:json_data(<<"success">>)};
|
||||||
|
auth_response({error, Reason}) ->
|
||||||
|
{ok, auth_error_status(Reason), iot_util:json_error(auth_error_status(Reason), reason_to_binary(Reason))}.
|
||||||
|
|
||||||
|
auth_error_status(timeout) ->
|
||||||
|
504;
|
||||||
|
auth_error_status(<<"timeout">>) ->
|
||||||
|
504;
|
||||||
|
auth_error_status(_) ->
|
||||||
|
400.
|
||||||
|
|
||||||
|
reason_to_binary(Reason) when is_binary(Reason) ->
|
||||||
|
Reason;
|
||||||
|
reason_to_binary(timeout) ->
|
||||||
|
<<"timeout">>;
|
||||||
|
reason_to_binary(invalid_response) ->
|
||||||
|
<<"invalid response">>;
|
||||||
|
reason_to_binary({denied, Reason}) ->
|
||||||
|
reason_to_binary(Reason);
|
||||||
|
reason_to_binary({failed, Reason}) ->
|
||||||
|
reason_to_binary(Reason);
|
||||||
|
reason_to_binary({channel_closed, Reason}) ->
|
||||||
|
<<"channel closed: ", (reason_to_binary(Reason))/binary>>;
|
||||||
|
reason_to_binary(Reason) ->
|
||||||
|
unicode:characters_to_binary(io_lib:format("~p", [Reason])).
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user