emqttd_packet.erl 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2012-2016 Feng Lee <feng@emqtt.io>.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. %% @doc MQTT Packet Functions
  17. -module(emqttd_packet).
  18. -include("emqttd.hrl").
  19. -include("emqttd_protocol.hrl").
  20. %% API
  21. -export([protocol_name/1, type_name/1, connack_name/1]).
  22. -export([format/1]).
  23. %% @doc Protocol name of version
  24. -spec(protocol_name(mqtt_vsn()) -> binary()).
  25. protocol_name(Ver) when Ver =:= ?MQTT_PROTO_V31; Ver =:= ?MQTT_PROTO_V311 ->
  26. proplists:get_value(Ver, ?PROTOCOL_NAMES).
  27. %% @doc Name of MQTT packet type
  28. -spec(type_name(mqtt_packet_type()) -> atom()).
  29. type_name(Type) when Type > ?RESERVED andalso Type =< ?DISCONNECT ->
  30. lists:nth(Type, ?TYPE_NAMES).
  31. %% @doc Connack Name
  32. -spec(connack_name(mqtt_connack()) -> atom()).
  33. connack_name(?CONNACK_ACCEPT) -> 'CONNACK_ACCEPT';
  34. connack_name(?CONNACK_PROTO_VER) -> 'CONNACK_PROTO_VER';
  35. connack_name(?CONNACK_INVALID_ID) -> 'CONNACK_INVALID_ID';
  36. connack_name(?CONNACK_SERVER) -> 'CONNACK_SERVER';
  37. connack_name(?CONNACK_CREDENTIALS) -> 'CONNACK_CREDENTIALS';
  38. connack_name(?CONNACK_AUTH) -> 'CONNACK_AUTH'.
  39. %% @doc Format packet
  40. -spec(format(mqtt_packet()) -> iolist()).
  41. format(#mqtt_packet{header = Header, variable = Variable, payload = Payload}) ->
  42. format_header(Header, format_variable(Variable, Payload)).
  43. format_header(#mqtt_packet_header{type = Type,
  44. dup = Dup,
  45. qos = QoS,
  46. retain = Retain}, S) ->
  47. S1 = if
  48. S == undefined -> <<>>;
  49. true -> [", ", S]
  50. end,
  51. io_lib:format("~s(Q~p, R~p, D~p~s)", [type_name(Type), QoS, i(Retain), i(Dup), S1]).
  52. format_variable(undefined, _) ->
  53. undefined;
  54. format_variable(Variable, undefined) ->
  55. format_variable(Variable);
  56. format_variable(Variable, Payload) ->
  57. io_lib:format("~s, Payload=~p", [format_variable(Variable), Payload]).
  58. format_variable(#mqtt_packet_connect{
  59. proto_ver = ProtoVer,
  60. proto_name = ProtoName,
  61. will_retain = WillRetain,
  62. will_qos = WillQoS,
  63. will_flag = WillFlag,
  64. clean_sess = CleanSess,
  65. keep_alive = KeepAlive,
  66. client_id = ClientId,
  67. will_topic = WillTopic,
  68. will_msg = WillMsg,
  69. username = Username,
  70. password = Password}) ->
  71. Format = "ClientId=~s, ProtoName=~s, ProtoVsn=~p, CleanSess=~s, KeepAlive=~p, Username=~s, Password=~s",
  72. Args = [ClientId, ProtoName, ProtoVer, CleanSess, KeepAlive, Username, format_password(Password)],
  73. {Format1, Args1} = if
  74. WillFlag -> { Format ++ ", Will(Q~p, R~p, Topic=~s, Msg=~s)",
  75. Args ++ [WillQoS, i(WillRetain), WillTopic, WillMsg] };
  76. true -> {Format, Args}
  77. end,
  78. io_lib:format(Format1, Args1);
  79. format_variable(#mqtt_packet_connack{ack_flags = AckFlags,
  80. return_code = ReturnCode}) ->
  81. io_lib:format("AckFlags=~p, RetainCode=~p", [AckFlags, ReturnCode]);
  82. format_variable(#mqtt_packet_publish{topic_name = TopicName,
  83. packet_id = PacketId}) ->
  84. io_lib:format("Topic=~s, PacketId=~p", [TopicName, PacketId]);
  85. format_variable(#mqtt_packet_puback{packet_id = PacketId}) ->
  86. io_lib:format("PacketId=~p", [PacketId]);
  87. format_variable(#mqtt_packet_subscribe{packet_id = PacketId,
  88. topic_table = TopicTable}) ->
  89. io_lib:format("PacketId=~p, TopicTable=~p", [PacketId, TopicTable]);
  90. format_variable(#mqtt_packet_unsubscribe{packet_id = PacketId,
  91. topics = Topics}) ->
  92. io_lib:format("PacketId=~p, Topics=~p", [PacketId, Topics]);
  93. format_variable(#mqtt_packet_suback{packet_id = PacketId,
  94. qos_table = QosTable}) ->
  95. io_lib:format("PacketId=~p, QosTable=~p", [PacketId, QosTable]);
  96. format_variable(#mqtt_packet_unsuback{packet_id = PacketId}) ->
  97. io_lib:format("PacketId=~p", [PacketId]);
  98. format_variable(PacketId) when is_integer(PacketId) ->
  99. io_lib:format("PacketId=~p", [PacketId]);
  100. format_variable(undefined) -> undefined.
  101. format_password(undefined) -> undefined;
  102. format_password(_Password) -> '******'.
  103. i(true) -> 1;
  104. i(false) -> 0;
  105. i(I) when is_integer(I) -> I.