diff --git a/apps/iot/src/http_handler/http_host_handler.erl b/apps/iot/src/http_handler/http_host_handler.erl index 2ea3246..de02d91 100644 --- a/apps/iot/src/http_handler/http_host_handler.erl +++ b/apps/iot/src/http_handler/http_host_handler.erl @@ -105,37 +105,63 @@ handle_request("POST", "/host/publish_command", _, end end; -%% 处理主机的授权的"激活/取消激活" 处理 -handle_request("POST", "/host/activate", _, #{<<"uuid">> := UUID, <<"auth">> := Auth, <<"timeout">> := Timeout}) when is_binary(UUID), is_boolean(Auth) -> +%% 处理主机的授权的激活 +handle_request("POST", "/host/activate", _, #{<<"uuid">> := UUID, <<"auth">> := true, <<"timeout">> := Timeout}) when is_binary(UUID) -> + case iot_host_sup:ensured_host_started(UUID) of + {error, Reason} -> + lager:debug("[host_handler] activate host_id: ~p, failed with reason: ~p", [UUID, Reason]), + {ok, 200, iot_util:json_error(400, <<"host not found">>)}; + {ok, Pid} when is_pid(Pid) -> + lager:debug("[host_handler] activate host_id: ~p, start", [UUID]), + {ok, Assoc} = iot_host:make_assoc(Pid), + ReplyTopic = iot_host:upstream_topic(UUID), + BinReply = jiffy:encode(#{<<"auth">> => true, <<"reply">> => #{<<"topic">> => ReplyTopic, <<"assoc">> => Assoc}}, [force_utf8]), + + case iot_mqtt_publisher:publish(iot_host:downstream_topic(UUID), <<8:8, BinReply/binary>>, 2) of + {ok, Ref} -> + receive + {ok, Ref, _PacketId} -> + receive + {host_reply, Assoc, #{<<"code">> := 1}} -> + ok = iot_host:activate(Pid, true), + {ok, 200, iot_util:json_data(<<"success">>)}; + {host_reply, Assoc, #{<<"code">> := 0, <<"message">> := Message}} when is_binary(Message) -> + {ok, 200, iot_util:json_error(401, <<"操作失败: "/utf8, Message/binary>>)} + after Timeout * 1000 -> + {ok, 200, iot_util:json_error(401, <<"操作超时,请重试: "/utf8>>)} + end + after Timeout * 1000 -> + lager:debug("[iot_host_handler] host_id uuid: ~p, publish topic success, but get ack timeout", [UUID]), + {ok, 200, iot_util:json_error(401, <<"命令执行超时, 请重试"/utf8>>)} + end; + {error, Reason} -> + lager:debug("[iot_host] host_id uuid: ~p, publish topic get error: ~p", [UUID, Reason]), + {ok, 200, iot_util:json_error(402, <<"发送命令到mqtt服务失败"/utf8>>)} + end + end; + +%% 处理主机的授权的 取消激活 +handle_request("POST", "/host/activate", _, #{<<"uuid">> := UUID, <<"auth">> := false, <<"timeout">> := Timeout}) when is_binary(UUID) -> case iot_host_sup:ensured_host_started(UUID) of {error, Reason} -> lager:debug("[host_handler] activate host_id: ~p, failed with reason: ~p", [UUID, Reason]), {ok, 200, iot_util:json_error(400, <<"host not found">>)}; {ok, Pid} when is_pid(Pid) -> %% 激活的话不管是否存在会话都需要通知 - case iot_host:has_session(Pid) or Auth of + case iot_host:has_session(Pid) of true -> lager:debug("[host_handler] activate host_id: ~p, start", [UUID]), {ok, Assoc} = iot_host:make_assoc(Pid), ReplyTopic = iot_host:upstream_topic(UUID), - Reply = case Auth of - true -> - #{<<"auth">> => true, <<"reply">> => #{<<"topic">> => ReplyTopic, <<"assoc">> => Assoc}}; - false -> - #{<<"auth">> => false, <<"reply">> => #{ <<"topic">> => ReplyTopic, <<"assoc">> => Assoc}} - end, - BinReply = jiffy:encode(Reply, [force_utf8]), + BinReply = jiffy:encode(#{<<"auth">> => false, <<"reply">> => #{<<"topic">> => ReplyTopic, <<"assoc">> => Assoc}}, [force_utf8]), - CommandType = 8, - Topic = iot_host:downstream_topic(UUID), - - case iot_mqtt_publisher:publish(Topic, <>, 2) of + case iot_mqtt_publisher:publish(iot_host:downstream_topic(UUID), <<8:8, BinReply/binary>>, 2) of {ok, Ref} -> receive {ok, Ref, _PacketId} -> receive {host_reply, Assoc, #{<<"code">> := 1}} -> - ok = iot_host:activate(Pid, Auth), + ok = iot_host:activate(Pid, false), {ok, 200, iot_util:json_data(<<"success">>)}; {host_reply, Assoc, #{<<"code">> := 0, <<"message">> := Message}} when is_binary(Message) -> {ok, 200, iot_util:json_error(401, <<"操作失败: "/utf8, Message/binary>>)} @@ -151,7 +177,7 @@ handle_request("POST", "/host/activate", _, #{<<"uuid">> := UUID, <<"auth">> := {ok, 200, iot_util:json_error(402, <<"发送命令到mqtt服务失败"/utf8>>)} end; false -> - ok = iot_host:activate(Pid, Auth), + ok = iot_host:activate(Pid, false), {ok, 200, iot_util:json_data(<<"success">>)} end end;