constants.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /* Protocol - protocol constants */
  2. const protocol = module.exports
  3. /* Command code => mnemonic */
  4. protocol.types = {
  5. 0: 'reserved',
  6. 1: 'connect',
  7. 2: 'connack',
  8. 3: 'publish',
  9. 4: 'puback',
  10. 5: 'pubrec',
  11. 6: 'pubrel',
  12. 7: 'pubcomp',
  13. 8: 'subscribe',
  14. 9: 'suback',
  15. 10: 'unsubscribe',
  16. 11: 'unsuback',
  17. 12: 'pingreq',
  18. 13: 'pingresp',
  19. 14: 'disconnect',
  20. 15: 'auth'
  21. }
  22. /* Mnemonic => Command code */
  23. protocol.codes = {}
  24. for (const k in protocol.types) {
  25. const v = protocol.types[k]
  26. protocol.codes[v] = k
  27. }
  28. /* Header */
  29. protocol.CMD_SHIFT = 4
  30. protocol.CMD_MASK = 0xF0
  31. protocol.DUP_MASK = 0x08
  32. protocol.QOS_MASK = 0x03
  33. protocol.QOS_SHIFT = 1
  34. protocol.RETAIN_MASK = 0x01
  35. /* Length */
  36. protocol.VARBYTEINT_MASK = 0x7F
  37. protocol.VARBYTEINT_FIN_MASK = 0x80
  38. protocol.VARBYTEINT_MAX = 268435455
  39. /* Connack */
  40. protocol.SESSIONPRESENT_MASK = 0x01
  41. protocol.SESSIONPRESENT_HEADER = Buffer.from([protocol.SESSIONPRESENT_MASK])
  42. protocol.CONNACK_HEADER = Buffer.from([protocol.codes.connack << protocol.CMD_SHIFT])
  43. /* Connect */
  44. protocol.USERNAME_MASK = 0x80
  45. protocol.PASSWORD_MASK = 0x40
  46. protocol.WILL_RETAIN_MASK = 0x20
  47. protocol.WILL_QOS_MASK = 0x18
  48. protocol.WILL_QOS_SHIFT = 3
  49. protocol.WILL_FLAG_MASK = 0x04
  50. protocol.CLEAN_SESSION_MASK = 0x02
  51. protocol.CONNECT_HEADER = Buffer.from([protocol.codes.connect << protocol.CMD_SHIFT])
  52. /* Properties */
  53. protocol.properties = {
  54. sessionExpiryInterval: 17,
  55. willDelayInterval: 24,
  56. receiveMaximum: 33,
  57. maximumPacketSize: 39,
  58. topicAliasMaximum: 34,
  59. requestResponseInformation: 25,
  60. requestProblemInformation: 23,
  61. userProperties: 38,
  62. authenticationMethod: 21,
  63. authenticationData: 22,
  64. payloadFormatIndicator: 1,
  65. messageExpiryInterval: 2,
  66. contentType: 3,
  67. responseTopic: 8,
  68. correlationData: 9,
  69. maximumQoS: 36,
  70. retainAvailable: 37,
  71. assignedClientIdentifier: 18,
  72. reasonString: 31,
  73. wildcardSubscriptionAvailable: 40,
  74. subscriptionIdentifiersAvailable: 41,
  75. sharedSubscriptionAvailable: 42,
  76. serverKeepAlive: 19,
  77. responseInformation: 26,
  78. serverReference: 28,
  79. topicAlias: 35,
  80. subscriptionIdentifier: 11
  81. }
  82. protocol.propertiesCodes = {}
  83. for (const prop in protocol.properties) {
  84. const id = protocol.properties[prop]
  85. protocol.propertiesCodes[id] = prop
  86. }
  87. protocol.propertiesTypes = {
  88. sessionExpiryInterval: 'int32',
  89. willDelayInterval: 'int32',
  90. receiveMaximum: 'int16',
  91. maximumPacketSize: 'int32',
  92. topicAliasMaximum: 'int16',
  93. requestResponseInformation: 'byte',
  94. requestProblemInformation: 'byte',
  95. userProperties: 'pair',
  96. authenticationMethod: 'string',
  97. authenticationData: 'binary',
  98. payloadFormatIndicator: 'byte',
  99. messageExpiryInterval: 'int32',
  100. contentType: 'string',
  101. responseTopic: 'string',
  102. correlationData: 'binary',
  103. maximumQoS: 'int8',
  104. retainAvailable: 'byte',
  105. assignedClientIdentifier: 'string',
  106. reasonString: 'string',
  107. wildcardSubscriptionAvailable: 'byte',
  108. subscriptionIdentifiersAvailable: 'byte',
  109. sharedSubscriptionAvailable: 'byte',
  110. serverKeepAlive: 'int16',
  111. responseInformation: 'string',
  112. serverReference: 'string',
  113. topicAlias: 'int16',
  114. subscriptionIdentifier: 'var'
  115. }
  116. function genHeader (type) {
  117. return [0, 1, 2].map(qos => {
  118. return [0, 1].map(dup => {
  119. return [0, 1].map(retain => {
  120. const buf = Buffer.alloc(1)
  121. buf.writeUInt8(
  122. protocol.codes[type] << protocol.CMD_SHIFT |
  123. (dup ? protocol.DUP_MASK : 0) |
  124. qos << protocol.QOS_SHIFT | retain, 0, true)
  125. return buf
  126. })
  127. })
  128. })
  129. }
  130. /* Publish */
  131. protocol.PUBLISH_HEADER = genHeader('publish')
  132. /* Subscribe */
  133. protocol.SUBSCRIBE_HEADER = genHeader('subscribe')
  134. protocol.SUBSCRIBE_OPTIONS_QOS_MASK = 0x03
  135. protocol.SUBSCRIBE_OPTIONS_NL_MASK = 0x01
  136. protocol.SUBSCRIBE_OPTIONS_NL_SHIFT = 2
  137. protocol.SUBSCRIBE_OPTIONS_RAP_MASK = 0x01
  138. protocol.SUBSCRIBE_OPTIONS_RAP_SHIFT = 3
  139. protocol.SUBSCRIBE_OPTIONS_RH_MASK = 0x03
  140. protocol.SUBSCRIBE_OPTIONS_RH_SHIFT = 4
  141. protocol.SUBSCRIBE_OPTIONS_RH = [0x00, 0x10, 0x20]
  142. protocol.SUBSCRIBE_OPTIONS_NL = 0x04
  143. protocol.SUBSCRIBE_OPTIONS_RAP = 0x08
  144. protocol.SUBSCRIBE_OPTIONS_QOS = [0x00, 0x01, 0x02]
  145. /* Unsubscribe */
  146. protocol.UNSUBSCRIBE_HEADER = genHeader('unsubscribe')
  147. /* Confirmations */
  148. protocol.ACKS = {
  149. unsuback: genHeader('unsuback'),
  150. puback: genHeader('puback'),
  151. pubcomp: genHeader('pubcomp'),
  152. pubrel: genHeader('pubrel'),
  153. pubrec: genHeader('pubrec')
  154. }
  155. protocol.SUBACK_HEADER = Buffer.from([protocol.codes.suback << protocol.CMD_SHIFT])
  156. /* Protocol versions */
  157. protocol.VERSION3 = Buffer.from([3])
  158. protocol.VERSION4 = Buffer.from([4])
  159. protocol.VERSION5 = Buffer.from([5])
  160. protocol.VERSION131 = Buffer.from([131])
  161. protocol.VERSION132 = Buffer.from([132])
  162. /* QoS */
  163. protocol.QOS = [0, 1, 2].map(qos => {
  164. return Buffer.from([qos])
  165. })
  166. /* Empty packets */
  167. protocol.EMPTY = {
  168. pingreq: Buffer.from([protocol.codes.pingreq << 4, 0]),
  169. pingresp: Buffer.from([protocol.codes.pingresp << 4, 0]),
  170. disconnect: Buffer.from([protocol.codes.disconnect << 4, 0])
  171. }