|
|
@@ -119,10 +119,10 @@ stats(_) ->
|
|
|
[].
|
|
|
|
|
|
-spec init(map(), map()) -> channel().
|
|
|
-init(ConnInfoT = #{peername := {PeerHost, _},
|
|
|
- sockname := {_, SockPort}},
|
|
|
+init(ConnInfo = #{peername := {PeerHost, _},
|
|
|
+ sockname := {_, SockPort}},
|
|
|
#{ctx := Ctx} = Config) ->
|
|
|
- Peercert = maps:get(peercert, ConnInfoT, undefined),
|
|
|
+ Peercert = maps:get(peercert, ConnInfo, undefined),
|
|
|
Mountpoint = maps:get(mountpoint, Config, <<>>),
|
|
|
ListenerId = case maps:get(listener, Config, undefined) of
|
|
|
undefined -> undefined;
|
|
|
@@ -144,10 +144,6 @@ init(ConnInfoT = #{peername := {PeerHost, _},
|
|
|
}
|
|
|
),
|
|
|
|
|
|
- %% because it is possible to disconnect after init, and then trigger the
|
|
|
- %% $event.disconnected hook and these two fields are required in the hook
|
|
|
- ConnInfo = ConnInfoT#{proto_name => <<"CoAP">>, proto_ver => <<"1">>},
|
|
|
-
|
|
|
Heartbeat = ?GET_IDLE_TIME(Config),
|
|
|
#channel{ ctx = Ctx
|
|
|
, conninfo = ConnInfo
|
|
|
@@ -405,6 +401,25 @@ run_conn_hooks(Input, Channel = #channel{ctx = Ctx,
|
|
|
{ok, Input, Channel}
|
|
|
end.
|
|
|
|
|
|
+enrich_conninfo({Queries, _Msg},
|
|
|
+ Channel = #channel{
|
|
|
+ keepalive = KeepAlive,
|
|
|
+ conninfo = ConnInfo}) ->
|
|
|
+ case Queries of
|
|
|
+ #{<<"clientid">> := ClientId} ->
|
|
|
+ Interval = maps:get(interval, emqx_keepalive:info(KeepAlive)),
|
|
|
+ NConnInfo = ConnInfo#{ clientid => ClientId
|
|
|
+ , proto_name => <<"CoAP">>
|
|
|
+ , proto_ver => <<"1">>
|
|
|
+ , clean_start => true
|
|
|
+ , keepalive => Interval
|
|
|
+ , expiry_interval => 0
|
|
|
+ },
|
|
|
+ {ok, Channel#channel{conninfo = NConnInfo}};
|
|
|
+ _ ->
|
|
|
+ {error, "invalid queries", Channel}
|
|
|
+ end.
|
|
|
+
|
|
|
enrich_clientinfo({Queries, Msg},
|
|
|
Channel = #channel{clientinfo = ClientInfo0}) ->
|
|
|
case Queries of
|
|
|
@@ -580,10 +595,12 @@ process_out(Outs, Result, Channel, _) ->
|
|
|
process_nothing(_, _, Channel) ->
|
|
|
{ok, Channel}.
|
|
|
|
|
|
-process_connection({open, Req}, Result, Channel, Iter) ->
|
|
|
+process_connection({open, Req}, Result,
|
|
|
+ Channel = #channel{conn_state = idle}, Iter) ->
|
|
|
Queries = emqx_coap_message:get_option(uri_query, Req),
|
|
|
case emqx_misc:pipeline(
|
|
|
- [ fun run_conn_hooks/2
|
|
|
+ [ fun enrich_conninfo/2
|
|
|
+ , fun run_conn_hooks/2
|
|
|
, fun enrich_clientinfo/2
|
|
|
, fun set_log_meta/2
|
|
|
, fun auth_connect/2
|
|
|
@@ -594,12 +611,31 @@ process_connection({open, Req}, Result, Channel, Iter) ->
|
|
|
process_connect(ensure_connected(NChannel), Req, Result, Iter);
|
|
|
{error, ReasonCode, NChannel} ->
|
|
|
ErrMsg = io_lib:format("Login Failed: ~ts", [ReasonCode]),
|
|
|
- Payload = erlang:list_to_binary(lists:flatten(ErrMsg)),
|
|
|
+ Payload = iolist_to_binary(ErrMsg),
|
|
|
iter(Iter,
|
|
|
reply({error, bad_request}, Payload, Req, Result),
|
|
|
NChannel)
|
|
|
end;
|
|
|
-
|
|
|
+process_connection({open, Req}, Result,
|
|
|
+ Channel = #channel{
|
|
|
+ conn_state = ConnState,
|
|
|
+ clientinfo = #{clientid := ClientId}}, Iter)
|
|
|
+ when ConnState == connected ->
|
|
|
+ Queries = emqx_coap_message:get_option(uri_query, Req),
|
|
|
+ ErrMsg0 =
|
|
|
+ case Queries of
|
|
|
+ #{<<"clientid">> := ClientId} ->
|
|
|
+ "client has connected";
|
|
|
+ #{<<"clientid">> := ReqClientId} ->
|
|
|
+ ["channel has registered by: ", ReqClientId];
|
|
|
+ _ ->
|
|
|
+ "invalid queries"
|
|
|
+ end,
|
|
|
+ ErrMsg = io_lib:format("Bad Request: ~ts", [ErrMsg0]),
|
|
|
+ Payload = iolist_to_binary(ErrMsg),
|
|
|
+ iter(Iter,
|
|
|
+ reply({error, bad_request}, Payload, Req, Result),
|
|
|
+ Channel);
|
|
|
process_connection({close, Msg}, _, Channel, _) ->
|
|
|
Reply = emqx_coap_message:piggyback({ok, deleted}, Msg),
|
|
|
{shutdown, close, Reply, Channel}.
|