emqx_mqtt.hrl 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2017-2024 EMQ Technologies Co., Ltd. All Rights Reserved.
  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. -ifndef(EMQX_MQTT_HRL).
  17. -define(EMQX_MQTT_HRL, true).
  18. -define(UINT_MAX, 16#FFFFFFFF).
  19. %%--------------------------------------------------------------------
  20. %% MQTT SockOpts
  21. %%--------------------------------------------------------------------
  22. -define(MQTT_SOCKOPTS, [
  23. binary,
  24. {packet, raw},
  25. {reuseaddr, true},
  26. {backlog, 512},
  27. {nodelay, true}
  28. ]).
  29. %%--------------------------------------------------------------------
  30. %% MQTT Protocol Version and Names
  31. %%--------------------------------------------------------------------
  32. -define(MQTT_SN_PROTO_V1, 1).
  33. -define(MQTT_PROTO_V3, 3).
  34. -define(MQTT_PROTO_V4, 4).
  35. -define(MQTT_PROTO_V5, 5).
  36. -define(PROTOCOL_NAMES, [
  37. %% XXX:Compatible with emqx-sn plug-in
  38. {?MQTT_SN_PROTO_V1, <<"MQTT-SN">>},
  39. {?MQTT_PROTO_V3, <<"MQIsdp">>},
  40. {?MQTT_PROTO_V4, <<"MQTT">>},
  41. {?MQTT_PROTO_V5, <<"MQTT">>}
  42. ]).
  43. %%--------------------------------------------------------------------
  44. %% MQTT Topic and TopitFilter byte length
  45. %%--------------------------------------------------------------------
  46. %% MQTT-3.1.1 and MQTT-5.0 [MQTT-4.7.3-3]
  47. -define(MAX_TOPIC_LEN, 65535).
  48. %%--------------------------------------------------------------------
  49. %% MQTT Share-Sub Internal
  50. %%--------------------------------------------------------------------
  51. -record(share, {group :: emqx_types:group(), topic :: emqx_types:topic()}).
  52. %% guards
  53. -define(IS_TOPIC(T),
  54. (is_binary(T) orelse is_record(T, share))
  55. ).
  56. %%--------------------------------------------------------------------
  57. %% MQTT QoS Levels
  58. %%--------------------------------------------------------------------
  59. %% At most once
  60. -define(QOS_0, 0).
  61. %% At least once
  62. -define(QOS_1, 1).
  63. %% Exactly once
  64. -define(QOS_2, 2).
  65. -define(IS_QOS(I), (I >= ?QOS_0 andalso I =< ?QOS_2)).
  66. -define(QOS_I(Name), begin
  67. (case Name of
  68. ?QOS_0 -> ?QOS_0;
  69. qos0 -> ?QOS_0;
  70. at_most_once -> ?QOS_0;
  71. ?QOS_1 -> ?QOS_1;
  72. qos1 -> ?QOS_1;
  73. at_least_once -> ?QOS_1;
  74. ?QOS_2 -> ?QOS_2;
  75. qos2 -> ?QOS_2;
  76. exactly_once -> ?QOS_2
  77. end)
  78. end).
  79. -define(IS_QOS_NAME(I),
  80. (I =:= qos0 orelse I =:= at_most_once orelse
  81. I =:= qos1 orelse I =:= at_least_once orelse
  82. I =:= qos2 orelse I =:= exactly_once)
  83. ).
  84. %%--------------------------------------------------------------------
  85. %% Maximum ClientId Length.
  86. %%--------------------------------------------------------------------
  87. -define(MAX_CLIENTID_LEN, 65535).
  88. %%--------------------------------------------------------------------
  89. %% MQTT Control Packet Types
  90. %%--------------------------------------------------------------------
  91. %% Reserved
  92. -define(RESERVED, 0).
  93. %% Client request to connect to Server
  94. -define(CONNECT, 1).
  95. %% Server to Client: Connect acknowledgment
  96. -define(CONNACK, 2).
  97. %% Publish message
  98. -define(PUBLISH, 3).
  99. %% Publish acknowledgment
  100. -define(PUBACK, 4).
  101. %% Publish received (assured delivery part 1)
  102. -define(PUBREC, 5).
  103. %% Publish release (assured delivery part 2)
  104. -define(PUBREL, 6).
  105. %% Publish complete (assured delivery part 3)
  106. -define(PUBCOMP, 7).
  107. %% Client subscribe request
  108. -define(SUBSCRIBE, 8).
  109. %% Server Subscribe acknowledgment
  110. -define(SUBACK, 9).
  111. %% Unsubscribe request
  112. -define(UNSUBSCRIBE, 10).
  113. %% Unsubscribe acknowledgment
  114. -define(UNSUBACK, 11).
  115. %% PING request
  116. -define(PINGREQ, 12).
  117. %% PING response
  118. -define(PINGRESP, 13).
  119. %% Client or Server is disconnecting
  120. -define(DISCONNECT, 14).
  121. %% Authentication exchange
  122. -define(AUTH, 15).
  123. %%--------------------------------------------------------------------
  124. %% MQTT V3.1.1 Connect Return Codes
  125. %%--------------------------------------------------------------------
  126. %% Connection accepted
  127. -define(CONNACK_ACCEPT, 0).
  128. %% Unacceptable protocol version
  129. -define(CONNACK_PROTO_VER, 1).
  130. %% Client Identifier is correct UTF-8 but not allowed by the Server
  131. -define(CONNACK_INVALID_ID, 2).
  132. %% Server unavailable
  133. -define(CONNACK_SERVER, 3).
  134. %% Username or password is malformed
  135. -define(CONNACK_CREDENTIALS, 4).
  136. %% Client is not authorized to connect
  137. -define(CONNACK_AUTH, 5).
  138. %%--------------------------------------------------------------------
  139. %% MQTT V5.0 Reason Codes
  140. %%--------------------------------------------------------------------
  141. -define(RC_SUCCESS, 16#00).
  142. -define(RC_NORMAL_DISCONNECTION, 16#00).
  143. -define(RC_GRANTED_QOS_0, 16#00).
  144. -define(RC_GRANTED_QOS_1, 16#01).
  145. -define(RC_GRANTED_QOS_2, 16#02).
  146. -define(RC_DISCONNECT_WITH_WILL_MESSAGE, 16#04).
  147. -define(RC_NO_MATCHING_SUBSCRIBERS, 16#10).
  148. -define(RC_NO_SUBSCRIPTION_EXISTED, 16#11).
  149. -define(RC_CONTINUE_AUTHENTICATION, 16#18).
  150. -define(RC_RE_AUTHENTICATE, 16#19).
  151. -define(RC_UNSPECIFIED_ERROR, 16#80).
  152. -define(RC_MALFORMED_PACKET, 16#81).
  153. -define(RC_PROTOCOL_ERROR, 16#82).
  154. -define(RC_IMPLEMENTATION_SPECIFIC_ERROR, 16#83).
  155. -define(RC_UNSUPPORTED_PROTOCOL_VERSION, 16#84).
  156. -define(RC_CLIENT_IDENTIFIER_NOT_VALID, 16#85).
  157. -define(RC_BAD_USER_NAME_OR_PASSWORD, 16#86).
  158. -define(RC_NOT_AUTHORIZED, 16#87).
  159. -define(RC_SERVER_UNAVAILABLE, 16#88).
  160. -define(RC_SERVER_BUSY, 16#89).
  161. -define(RC_BANNED, 16#8A).
  162. -define(RC_SERVER_SHUTTING_DOWN, 16#8B).
  163. -define(RC_BAD_AUTHENTICATION_METHOD, 16#8C).
  164. -define(RC_KEEP_ALIVE_TIMEOUT, 16#8D).
  165. -define(RC_SESSION_TAKEN_OVER, 16#8E).
  166. -define(RC_TOPIC_FILTER_INVALID, 16#8F).
  167. -define(RC_TOPIC_NAME_INVALID, 16#90).
  168. -define(RC_PACKET_IDENTIFIER_IN_USE, 16#91).
  169. -define(RC_PACKET_IDENTIFIER_NOT_FOUND, 16#92).
  170. -define(RC_RECEIVE_MAXIMUM_EXCEEDED, 16#93).
  171. -define(RC_TOPIC_ALIAS_INVALID, 16#94).
  172. -define(RC_PACKET_TOO_LARGE, 16#95).
  173. -define(RC_MESSAGE_RATE_TOO_HIGH, 16#96).
  174. -define(RC_QUOTA_EXCEEDED, 16#97).
  175. -define(RC_ADMINISTRATIVE_ACTION, 16#98).
  176. -define(RC_PAYLOAD_FORMAT_INVALID, 16#99).
  177. -define(RC_RETAIN_NOT_SUPPORTED, 16#9A).
  178. -define(RC_QOS_NOT_SUPPORTED, 16#9B).
  179. -define(RC_USE_ANOTHER_SERVER, 16#9C).
  180. -define(RC_SERVER_MOVED, 16#9D).
  181. -define(RC_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED, 16#9E).
  182. -define(RC_CONNECTION_RATE_EXCEEDED, 16#9F).
  183. -define(RC_MAXIMUM_CONNECT_TIME, 16#A0).
  184. -define(RC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED, 16#A1).
  185. -define(RC_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED, 16#A2).
  186. %%--------------------------------------------------------------------
  187. %% Maximum MQTT Packet ID and Length
  188. %%--------------------------------------------------------------------
  189. -define(MAX_PACKET_ID, 16#FFFF).
  190. -define(MAX_PACKET_SIZE, 16#FFFFFFF).
  191. -define(MAX_TOPIC_AlIAS, 16#FFFF).
  192. -define(RECEIVE_MAXIMUM_LIMIT, ?MAX_PACKET_ID).
  193. %%--------------------------------------------------------------------
  194. %% MQTT Frame Mask
  195. %%--------------------------------------------------------------------
  196. -define(HIGHBIT, 2#10000000).
  197. -define(LOWBITS, 2#01111111).
  198. %%--------------------------------------------------------------------
  199. %% MQTT Packet Fixed Header
  200. %%--------------------------------------------------------------------
  201. -record(mqtt_packet_header, {
  202. type = ?RESERVED,
  203. dup = false,
  204. qos = ?QOS_0,
  205. retain = false
  206. }).
  207. %%--------------------------------------------------------------------
  208. %% MQTT Packets
  209. %%--------------------------------------------------------------------
  210. %% Retain Handling
  211. -define(DEFAULT_SUBOPTS, #{
  212. rh => 0,
  213. %% Retain as Publish
  214. rap => 0,
  215. %% No Local
  216. nl => 0,
  217. %% QoS
  218. qos => 0
  219. }).
  220. -record(mqtt_packet_connect, {
  221. proto_name = <<"MQTT">>,
  222. proto_ver = ?MQTT_PROTO_V4,
  223. is_bridge = false,
  224. clean_start = true,
  225. will_flag = false,
  226. will_qos = ?QOS_0,
  227. will_retain = false,
  228. keepalive = 0,
  229. properties = #{},
  230. clientid = <<>>,
  231. will_props = #{},
  232. will_topic = undefined,
  233. will_payload = undefined,
  234. username = undefined,
  235. password = undefined
  236. }).
  237. -record(mqtt_packet_connack, {
  238. ack_flags,
  239. reason_code,
  240. properties = #{}
  241. }).
  242. -record(mqtt_packet_publish, {
  243. topic_name,
  244. packet_id,
  245. properties = #{}
  246. }).
  247. -record(mqtt_packet_puback, {
  248. packet_id,
  249. reason_code,
  250. properties = #{}
  251. }).
  252. -record(mqtt_packet_subscribe, {
  253. packet_id,
  254. properties = #{},
  255. topic_filters
  256. }).
  257. -record(mqtt_packet_suback, {
  258. packet_id,
  259. properties = #{},
  260. reason_codes
  261. }).
  262. -record(mqtt_packet_unsubscribe, {
  263. packet_id,
  264. properties = #{},
  265. topic_filters
  266. }).
  267. -record(mqtt_packet_unsuback, {
  268. packet_id,
  269. properties = #{},
  270. reason_codes
  271. }).
  272. -record(mqtt_packet_disconnect, {
  273. reason_code,
  274. properties = #{}
  275. }).
  276. -record(mqtt_packet_auth, {
  277. reason_code,
  278. properties = #{}
  279. }).
  280. %%--------------------------------------------------------------------
  281. %% MQTT Control Packet
  282. %%--------------------------------------------------------------------
  283. -record(mqtt_packet, {
  284. header :: #mqtt_packet_header{},
  285. variable ::
  286. #mqtt_packet_connect{}
  287. | #mqtt_packet_connack{}
  288. | #mqtt_packet_publish{}
  289. | #mqtt_packet_puback{}
  290. | #mqtt_packet_subscribe{}
  291. | #mqtt_packet_suback{}
  292. | #mqtt_packet_unsubscribe{}
  293. | #mqtt_packet_unsuback{}
  294. | #mqtt_packet_disconnect{}
  295. | #mqtt_packet_auth{}
  296. | pos_integer()
  297. | undefined,
  298. payload :: binary() | undefined
  299. }).
  300. %%--------------------------------------------------------------------
  301. %% MQTT Message Internal
  302. %%--------------------------------------------------------------------
  303. -record(mqtt_msg, {
  304. qos = ?QOS_0,
  305. retain = false,
  306. dup = false,
  307. packet_id,
  308. topic,
  309. props,
  310. payload
  311. }).
  312. %%--------------------------------------------------------------------
  313. %% MQTT Packet Match
  314. %%--------------------------------------------------------------------
  315. -define(CONNECT_PACKET(), #mqtt_packet{header = #mqtt_packet_header{type = ?CONNECT}}).
  316. -define(CONNECT_PACKET(Var), #mqtt_packet{
  317. header = #mqtt_packet_header{type = ?CONNECT},
  318. variable = Var
  319. }).
  320. -define(CONNACK_PACKET(ReasonCode), #mqtt_packet{
  321. header = #mqtt_packet_header{type = ?CONNACK},
  322. variable = #mqtt_packet_connack{
  323. ack_flags = 0,
  324. reason_code = ReasonCode
  325. }
  326. }).
  327. -define(CONNACK_PACKET(ReasonCode, SessPresent), #mqtt_packet{
  328. header = #mqtt_packet_header{type = ?CONNACK},
  329. variable = #mqtt_packet_connack{
  330. ack_flags = SessPresent,
  331. reason_code = ReasonCode
  332. }
  333. }).
  334. -define(CONNACK_PACKET(ReasonCode, SessPresent, Properties), #mqtt_packet{
  335. header = #mqtt_packet_header{type = ?CONNACK},
  336. variable = #mqtt_packet_connack{
  337. ack_flags = SessPresent,
  338. reason_code = ReasonCode,
  339. properties = Properties
  340. }
  341. }).
  342. -define(AUTH_PACKET(), #mqtt_packet{
  343. header = #mqtt_packet_header{type = ?AUTH},
  344. variable = #mqtt_packet_auth{reason_code = 0}
  345. }).
  346. -define(AUTH_PACKET(ReasonCode), #mqtt_packet{
  347. header = #mqtt_packet_header{type = ?AUTH},
  348. variable = #mqtt_packet_auth{reason_code = ReasonCode}
  349. }).
  350. -define(AUTH_PACKET(ReasonCode, Properties), #mqtt_packet{
  351. header = #mqtt_packet_header{type = ?AUTH},
  352. variable = #mqtt_packet_auth{
  353. reason_code = ReasonCode,
  354. properties = Properties
  355. }
  356. }).
  357. -define(PUBLISH_PACKET(QoS), #mqtt_packet{header = #mqtt_packet_header{type = ?PUBLISH, qos = QoS}}).
  358. -define(PUBLISH_PACKET(QoS, PacketId), #mqtt_packet{
  359. header = #mqtt_packet_header{
  360. type = ?PUBLISH,
  361. qos = QoS
  362. },
  363. variable = #mqtt_packet_publish{packet_id = PacketId}
  364. }).
  365. -define(PUBLISH_PACKET(QoS, Topic, PacketId), #mqtt_packet{
  366. header = #mqtt_packet_header{
  367. type = ?PUBLISH,
  368. qos = QoS
  369. },
  370. variable = #mqtt_packet_publish{
  371. topic_name = Topic,
  372. packet_id = PacketId
  373. }
  374. }).
  375. -define(PUBLISH_PACKET(QoS, Topic, PacketId, Payload), #mqtt_packet{
  376. header = #mqtt_packet_header{
  377. type = ?PUBLISH,
  378. qos = QoS
  379. },
  380. variable = #mqtt_packet_publish{
  381. topic_name = Topic,
  382. packet_id = PacketId
  383. },
  384. payload = Payload
  385. }).
  386. -define(PUBLISH_PACKET(QoS, Topic, PacketId, Properties, Payload), #mqtt_packet{
  387. header = #mqtt_packet_header{
  388. type = ?PUBLISH,
  389. qos = QoS
  390. },
  391. variable = #mqtt_packet_publish{
  392. topic_name = Topic,
  393. packet_id = PacketId,
  394. properties = Properties
  395. },
  396. payload = Payload
  397. }).
  398. -define(PUBACK_PACKET(PacketId), #mqtt_packet{
  399. header = #mqtt_packet_header{type = ?PUBACK},
  400. variable = #mqtt_packet_puback{
  401. packet_id = PacketId,
  402. reason_code = 0
  403. }
  404. }).
  405. -define(PUBACK_PACKET(PacketId, ReasonCode), #mqtt_packet{
  406. header = #mqtt_packet_header{type = ?PUBACK},
  407. variable = #mqtt_packet_puback{
  408. packet_id = PacketId,
  409. reason_code = ReasonCode
  410. }
  411. }).
  412. -define(PUBACK_PACKET(PacketId, ReasonCode, Properties), #mqtt_packet{
  413. header = #mqtt_packet_header{type = ?PUBACK},
  414. variable = #mqtt_packet_puback{
  415. packet_id = PacketId,
  416. reason_code = ReasonCode,
  417. properties = Properties
  418. }
  419. }).
  420. -define(PUBREC_PACKET(PacketId), #mqtt_packet{
  421. header = #mqtt_packet_header{type = ?PUBREC},
  422. variable = #mqtt_packet_puback{
  423. packet_id = PacketId,
  424. reason_code = 0
  425. }
  426. }).
  427. -define(PUBREC_PACKET(PacketId, ReasonCode), #mqtt_packet{
  428. header = #mqtt_packet_header{type = ?PUBREC},
  429. variable = #mqtt_packet_puback{
  430. packet_id = PacketId,
  431. reason_code = ReasonCode
  432. }
  433. }).
  434. -define(PUBREC_PACKET(PacketId, ReasonCode, Properties), #mqtt_packet{
  435. header = #mqtt_packet_header{type = ?PUBREC},
  436. variable = #mqtt_packet_puback{
  437. packet_id = PacketId,
  438. reason_code = ReasonCode,
  439. properties = Properties
  440. }
  441. }).
  442. -define(PUBREL_PACKET(PacketId), #mqtt_packet{
  443. header = #mqtt_packet_header{
  444. type = ?PUBREL,
  445. qos = ?QOS_1
  446. },
  447. variable = #mqtt_packet_puback{
  448. packet_id = PacketId,
  449. reason_code = 0
  450. }
  451. }).
  452. -define(PUBREL_PACKET(PacketId, ReasonCode), #mqtt_packet{
  453. header = #mqtt_packet_header{
  454. type = ?PUBREL,
  455. qos = ?QOS_1
  456. },
  457. variable = #mqtt_packet_puback{
  458. packet_id = PacketId,
  459. reason_code = ReasonCode
  460. }
  461. }).
  462. -define(PUBREL_PACKET(PacketId, ReasonCode, Properties), #mqtt_packet{
  463. header = #mqtt_packet_header{
  464. type = ?PUBREL,
  465. qos = ?QOS_1
  466. },
  467. variable = #mqtt_packet_puback{
  468. packet_id = PacketId,
  469. reason_code = ReasonCode,
  470. properties = Properties
  471. }
  472. }).
  473. -define(PUBCOMP_PACKET(PacketId), #mqtt_packet{
  474. header = #mqtt_packet_header{type = ?PUBCOMP},
  475. variable = #mqtt_packet_puback{
  476. packet_id = PacketId,
  477. reason_code = 0
  478. }
  479. }).
  480. -define(PUBCOMP_PACKET(PacketId, ReasonCode), #mqtt_packet{
  481. header = #mqtt_packet_header{type = ?PUBCOMP},
  482. variable = #mqtt_packet_puback{
  483. packet_id = PacketId,
  484. reason_code = ReasonCode
  485. }
  486. }).
  487. -define(PUBCOMP_PACKET(PacketId, ReasonCode, Properties), #mqtt_packet{
  488. header = #mqtt_packet_header{type = ?PUBCOMP},
  489. variable = #mqtt_packet_puback{
  490. packet_id = PacketId,
  491. reason_code = ReasonCode,
  492. properties = Properties
  493. }
  494. }).
  495. -define(SUBSCRIBE_PACKET(PacketId, TopicFilters), #mqtt_packet{
  496. header = #mqtt_packet_header{
  497. type = ?SUBSCRIBE,
  498. qos = ?QOS_1
  499. },
  500. variable = #mqtt_packet_subscribe{
  501. packet_id = PacketId,
  502. topic_filters = TopicFilters
  503. }
  504. }).
  505. -define(SUBSCRIBE_PACKET(PacketId, Properties, TopicFilters), #mqtt_packet{
  506. header = #mqtt_packet_header{
  507. type = ?SUBSCRIBE,
  508. qos = ?QOS_1
  509. },
  510. variable = #mqtt_packet_subscribe{
  511. packet_id = PacketId,
  512. properties = Properties,
  513. topic_filters = TopicFilters
  514. }
  515. }).
  516. -define(SUBACK_PACKET(PacketId, ReasonCodes), #mqtt_packet{
  517. header = #mqtt_packet_header{type = ?SUBACK},
  518. variable = #mqtt_packet_suback{
  519. packet_id = PacketId,
  520. reason_codes = ReasonCodes
  521. }
  522. }).
  523. -define(SUBACK_PACKET(PacketId, Properties, ReasonCodes), #mqtt_packet{
  524. header = #mqtt_packet_header{type = ?SUBACK},
  525. variable = #mqtt_packet_suback{
  526. packet_id = PacketId,
  527. properties = Properties,
  528. reason_codes = ReasonCodes
  529. }
  530. }).
  531. -define(UNSUBSCRIBE_PACKET(PacketId, TopicFilters), #mqtt_packet{
  532. header = #mqtt_packet_header{
  533. type = ?UNSUBSCRIBE,
  534. qos = ?QOS_1
  535. },
  536. variable = #mqtt_packet_unsubscribe{
  537. packet_id = PacketId,
  538. topic_filters = TopicFilters
  539. }
  540. }).
  541. -define(UNSUBSCRIBE_PACKET(PacketId, Properties, TopicFilters), #mqtt_packet{
  542. header = #mqtt_packet_header{
  543. type = ?UNSUBSCRIBE,
  544. qos = ?QOS_1
  545. },
  546. variable = #mqtt_packet_unsubscribe{
  547. packet_id = PacketId,
  548. properties = Properties,
  549. topic_filters = TopicFilters
  550. }
  551. }).
  552. -define(UNSUBACK_PACKET(PacketId), #mqtt_packet{
  553. header = #mqtt_packet_header{type = ?UNSUBACK},
  554. variable = #mqtt_packet_unsuback{packet_id = PacketId}
  555. }).
  556. -define(UNSUBACK_PACKET(PacketId, ReasonCodes), #mqtt_packet{
  557. header = #mqtt_packet_header{type = ?UNSUBACK},
  558. variable = #mqtt_packet_unsuback{
  559. packet_id = PacketId,
  560. reason_codes = ReasonCodes
  561. }
  562. }).
  563. -define(UNSUBACK_PACKET(PacketId, Properties, ReasonCodes), #mqtt_packet{
  564. header = #mqtt_packet_header{type = ?UNSUBACK},
  565. variable = #mqtt_packet_unsuback{
  566. packet_id = PacketId,
  567. properties = Properties,
  568. reason_codes = ReasonCodes
  569. }
  570. }).
  571. -define(DISCONNECT_PACKET(), #mqtt_packet{
  572. header = #mqtt_packet_header{type = ?DISCONNECT},
  573. variable = #mqtt_packet_disconnect{reason_code = 0}
  574. }).
  575. -define(DISCONNECT_PACKET(ReasonCode), #mqtt_packet{
  576. header = #mqtt_packet_header{type = ?DISCONNECT},
  577. variable = #mqtt_packet_disconnect{reason_code = ReasonCode}
  578. }).
  579. -define(DISCONNECT_PACKET(ReasonCode, Properties), #mqtt_packet{
  580. header = #mqtt_packet_header{type = ?DISCONNECT},
  581. variable = #mqtt_packet_disconnect{
  582. reason_code = ReasonCode,
  583. properties = Properties
  584. }
  585. }).
  586. -define(PACKET(Type), #mqtt_packet{header = #mqtt_packet_header{type = Type}}).
  587. -define(SHARE, "$share").
  588. -define(QUEUE, "$queue").
  589. -define(REDISPATCH_TO(GROUP, TOPIC), {GROUP, TOPIC}).
  590. -define(SHARE_EMPTY_FILTER, share_subscription_topic_cannot_be_empty).
  591. -define(SHARE_EMPTY_GROUP, share_subscription_group_name_cannot_be_empty).
  592. -define(SHARE_RECURSIVELY, '$share_cannot_be_used_as_real_topic_filter').
  593. -define(SHARE_NAME_INVALID_CHAR, share_subscription_group_name_cannot_include_wildcard).
  594. -define(FRAME_PARSE_ERROR, frame_parse_error).
  595. -define(FRAME_SERIALIZE_ERROR, frame_serialize_error).
  596. -define(THROW_FRAME_ERROR(Reason), erlang:throw({?FRAME_PARSE_ERROR, Reason})).
  597. -define(THROW_SERIALIZE_ERROR(Reason), erlang:throw({?FRAME_SERIALIZE_ERROR, Reason})).
  598. -define(MAX_PAYLOAD_FORMAT_SIZE, 1024).
  599. -define(TRUNCATED_PAYLOAD_SIZE, 100).
  600. -define(MAX_PAYLOAD_FORMAT_LIMIT(Bin), (byte_size(Bin) =< ?MAX_PAYLOAD_FORMAT_SIZE)).
  601. -endif.