diff --git a/apps/emqx_gateway_mqttsn/src/emqx_mqttsn_channel.erl b/apps/emqx_gateway_mqttsn/src/emqx_mqttsn_channel.erl index e7061e4a5..d37979ced 100644 --- a/apps/emqx_gateway_mqttsn/src/emqx_mqttsn_channel.erl +++ b/apps/emqx_gateway_mqttsn/src/emqx_mqttsn_channel.erl @@ -443,6 +443,12 @@ handle_in( handle_in(?SN_ADVERTISE_MSG(_GwId, _Radius), Channel) -> % ignore shutdown(normal, Channel); +%% Ack DISCONNECT even if it is not connected +handle_in( + ?SN_DISCONNECT_MSG(_Duration), + Channel = #channel{conn_state = idle} +) -> + handle_out(disconnect, normal, Channel); handle_in( Publish = ?SN_PUBLISH_MSG( diff --git a/apps/emqx_gateway_mqttsn/test/emqx_sn_protocol_SUITE.erl b/apps/emqx_gateway_mqttsn/test/emqx_sn_protocol_SUITE.erl index 55120e7fa..0c4c4e6bf 100644 --- a/apps/emqx_gateway_mqttsn/test/emqx_sn_protocol_SUITE.erl +++ b/apps/emqx_gateway_mqttsn/test/emqx_sn_protocol_SUITE.erl @@ -176,6 +176,18 @@ t_connect(_) -> ?assertEqual(<<3, ?SN_CONNACK, 0>>, receive_response(Socket)), send_disconnect_msg(Socket, undefined), + %% assert: mqttsn gateway will ack disconnect msg with DISCONNECT packet + ?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)), + gen_udp:close(Socket). + +t_first_disconnect(_) -> + SockName = {'mqttsn:udp:default', 1884}, + ?assertEqual(true, lists:keymember(SockName, 1, esockd:listeners())), + + {ok, Socket} = gen_udp:open(0, [binary]), + send_disconnect_msg(Socket, undefined), + + %% assert: mqttsn gateway will ack disconnect msg with DISCONNECT packet ?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)), gen_udp:close(Socket). @@ -1217,7 +1229,7 @@ t_will_case01(_) -> ?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)), send_disconnect_msg(Socket, undefined), - ?assertEqual(udp_receive_timeout, receive_response(Socket)), + ?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)), gen_udp:close(Socket). @@ -1244,7 +1256,7 @@ t_will_test2(_) -> receive_response(Socket), send_disconnect_msg(Socket, undefined), - ?assertEqual(udp_receive_timeout, receive_response(Socket)), + ?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)), gen_udp:close(Socket). @@ -1265,7 +1277,7 @@ t_will_test3(_) -> ?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)), send_disconnect_msg(Socket, undefined), - ?assertEqual(udp_receive_timeout, receive_response(Socket)), + ?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)), gen_udp:close(Socket). @@ -1294,7 +1306,7 @@ t_will_test4(_) -> receive_response(Socket), send_disconnect_msg(Socket, undefined), - ?assertEqual(udp_receive_timeout, receive_response(Socket)), + ?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)), gen_udp:close(Socket). diff --git a/changes/ce/fix-12176.en.md b/changes/ce/fix-12176.en.md new file mode 100644 index 000000000..cb42773e6 --- /dev/null +++ b/changes/ce/fix-12176.en.md @@ -0,0 +1 @@ +Ack the DISCONNECT packet to MQTT-SN client regardless of whether the connection has been successfully established.