emqx_mqtt.hrl 19 KB

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