@zwave-js/cc 14.1.0 → 14.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/build/cjs/cc/AlarmSensorCC.js.map +2 -2
  2. package/build/cjs/cc/AssociationCC.d.ts +2 -0
  3. package/build/cjs/cc/AssociationCC.js +5 -0
  4. package/build/cjs/cc/AssociationCC.js.map +2 -2
  5. package/build/cjs/cc/AssociationGroupInfoCC.js.map +2 -2
  6. package/build/cjs/cc/BarrierOperatorCC.js.map +2 -2
  7. package/build/cjs/cc/BasicCC.js.map +2 -2
  8. package/build/cjs/cc/BatteryCC.js.map +2 -2
  9. package/build/cjs/cc/BinarySensorCC.js.map +2 -2
  10. package/build/cjs/cc/BinarySwitchCC.js.map +2 -2
  11. package/build/cjs/cc/CRC16CC.d.ts +4 -0
  12. package/build/cjs/cc/CRC16CC.js +23 -0
  13. package/build/cjs/cc/CRC16CC.js.map +2 -2
  14. package/build/cjs/cc/CentralSceneCC.js.map +2 -2
  15. package/build/cjs/cc/ClimateControlScheduleCC.js.map +2 -2
  16. package/build/cjs/cc/ClockCC.js.map +2 -2
  17. package/build/cjs/cc/ColorSwitchCC.js.map +2 -2
  18. package/build/cjs/cc/ConfigurationCC.d.ts +4 -0
  19. package/build/cjs/cc/ConfigurationCC.js +10 -0
  20. package/build/cjs/cc/ConfigurationCC.js.map +2 -2
  21. package/build/cjs/cc/DoorLockCC.js.map +2 -2
  22. package/build/cjs/cc/DoorLockLoggingCC.js.map +2 -2
  23. package/build/cjs/cc/EnergyProductionCC.js.map +2 -2
  24. package/build/cjs/cc/EntryControlCC.js.map +2 -2
  25. package/build/cjs/cc/FirmwareUpdateMetaDataCC.js.map +2 -2
  26. package/build/cjs/cc/HumidityControlModeCC.js.map +2 -2
  27. package/build/cjs/cc/HumidityControlSetpointCC.js.map +2 -2
  28. package/build/cjs/cc/InclusionControllerCC.js.map +2 -2
  29. package/build/cjs/cc/IndicatorCC.js.map +2 -2
  30. package/build/cjs/cc/IrrigationCC.js.map +2 -2
  31. package/build/cjs/cc/LanguageCC.js.map +2 -2
  32. package/build/cjs/cc/LockCC.js.map +2 -2
  33. package/build/cjs/cc/ManufacturerProprietaryCC.js.map +2 -2
  34. package/build/cjs/cc/ManufacturerSpecificCC.js.map +2 -2
  35. package/build/cjs/cc/MeterCC.js.map +2 -2
  36. package/build/cjs/cc/MultiChannelAssociationCC.d.ts +2 -0
  37. package/build/cjs/cc/MultiChannelAssociationCC.js +6 -0
  38. package/build/cjs/cc/MultiChannelAssociationCC.js.map +2 -2
  39. package/build/cjs/cc/MultiChannelCC.d.ts +10 -0
  40. package/build/cjs/cc/MultiChannelCC.js +65 -0
  41. package/build/cjs/cc/MultiChannelCC.js.map +2 -2
  42. package/build/cjs/cc/MultiCommandCC.d.ts +4 -0
  43. package/build/cjs/cc/MultiCommandCC.js +34 -1
  44. package/build/cjs/cc/MultiCommandCC.js.map +2 -2
  45. package/build/cjs/cc/MultilevelSensorCC.js.map +2 -2
  46. package/build/cjs/cc/MultilevelSwitchCC.js.map +2 -2
  47. package/build/cjs/cc/NodeNamingCC.js.map +2 -2
  48. package/build/cjs/cc/NotificationCC.js.map +2 -2
  49. package/build/cjs/cc/PowerlevelCC.js.map +2 -2
  50. package/build/cjs/cc/ProtectionCC.js.map +2 -2
  51. package/build/cjs/cc/SceneActivationCC.js.map +2 -2
  52. package/build/cjs/cc/SceneActuatorConfigurationCC.js.map +2 -2
  53. package/build/cjs/cc/SceneControllerConfigurationCC.js.map +2 -2
  54. package/build/cjs/cc/ScheduleEntryLockCC.js.map +2 -2
  55. package/build/cjs/cc/Security2CC.d.ts +4 -0
  56. package/build/cjs/cc/Security2CC.js +215 -0
  57. package/build/cjs/cc/Security2CC.js.map +2 -2
  58. package/build/cjs/cc/SecurityCC.d.ts +6 -0
  59. package/build/cjs/cc/SecurityCC.js +53 -0
  60. package/build/cjs/cc/SecurityCC.js.map +2 -2
  61. package/build/cjs/cc/SoundSwitchCC.js.map +2 -2
  62. package/build/cjs/cc/SupervisionCC.d.ts +4 -0
  63. package/build/cjs/cc/SupervisionCC.js +25 -0
  64. package/build/cjs/cc/SupervisionCC.js.map +2 -2
  65. package/build/cjs/cc/ThermostatFanModeCC.js.map +2 -2
  66. package/build/cjs/cc/ThermostatModeCC.js.map +2 -2
  67. package/build/cjs/cc/ThermostatSetbackCC.js.map +2 -2
  68. package/build/cjs/cc/ThermostatSetpointCC.js.map +2 -2
  69. package/build/cjs/cc/TimeCC.js.map +2 -2
  70. package/build/cjs/cc/TimeParametersCC.js.map +2 -2
  71. package/build/cjs/cc/TransportServiceCC.d.ts +5 -0
  72. package/build/cjs/cc/TransportServiceCC.js +13 -0
  73. package/build/cjs/cc/TransportServiceCC.js.map +2 -2
  74. package/build/cjs/cc/UserCodeCC.js.map +2 -2
  75. package/build/cjs/cc/VersionCC.js.map +2 -2
  76. package/build/cjs/cc/WakeUpCC.js.map +2 -2
  77. package/build/cjs/cc/WindowCoveringCC.js.map +2 -2
  78. package/build/cjs/cc/ZWavePlusCC.js.map +2 -2
  79. package/build/cjs/cc/ZWaveProtocolCC.js.map +2 -2
  80. package/build/cjs/cc/manufacturerProprietary/Decorators.js +6 -5
  81. package/build/cjs/cc/manufacturerProprietary/Decorators.js.map +2 -2
  82. package/build/cjs/cc/manufacturerProprietary/FibaroCC.js.map +2 -2
  83. package/build/cjs/lib/CommandClass.d.ts +15 -1
  84. package/build/cjs/lib/CommandClass.js +56 -1
  85. package/build/cjs/lib/CommandClass.js.map +2 -2
  86. package/build/cjs/lib/CommandClassDecorators.js +7 -6
  87. package/build/cjs/lib/CommandClassDecorators.js.map +2 -2
  88. package/build/cjs/lib/Security2/Extension.js +2 -2
  89. package/build/cjs/lib/Security2/Extension.js.map +2 -2
  90. package/build/esm/cc/AlarmSensorCC.d.ts.map +1 -1
  91. package/build/esm/cc/AlarmSensorCC.js +1 -0
  92. package/build/esm/cc/AlarmSensorCC.js.map +1 -1
  93. package/build/esm/cc/AssociationCC.d.ts +2 -0
  94. package/build/esm/cc/AssociationCC.d.ts.map +1 -1
  95. package/build/esm/cc/AssociationCC.js +14 -0
  96. package/build/esm/cc/AssociationCC.js.map +1 -1
  97. package/build/esm/cc/AssociationGroupInfoCC.d.ts.map +1 -1
  98. package/build/esm/cc/AssociationGroupInfoCC.js +6 -0
  99. package/build/esm/cc/AssociationGroupInfoCC.js.map +1 -1
  100. package/build/esm/cc/BarrierOperatorCC.d.ts.map +1 -1
  101. package/build/esm/cc/BarrierOperatorCC.js +3 -0
  102. package/build/esm/cc/BarrierOperatorCC.js.map +1 -1
  103. package/build/esm/cc/BasicCC.d.ts.map +1 -1
  104. package/build/esm/cc/BasicCC.js +2 -0
  105. package/build/esm/cc/BasicCC.js.map +1 -1
  106. package/build/esm/cc/BatteryCC.d.ts.map +1 -1
  107. package/build/esm/cc/BatteryCC.js +1 -0
  108. package/build/esm/cc/BatteryCC.js.map +1 -1
  109. package/build/esm/cc/BinarySensorCC.d.ts.map +1 -1
  110. package/build/esm/cc/BinarySensorCC.js +3 -0
  111. package/build/esm/cc/BinarySensorCC.js.map +1 -1
  112. package/build/esm/cc/BinarySwitchCC.d.ts.map +1 -1
  113. package/build/esm/cc/BinarySwitchCC.js +2 -0
  114. package/build/esm/cc/BinarySwitchCC.js.map +1 -1
  115. package/build/esm/cc/CRC16CC.d.ts +4 -0
  116. package/build/esm/cc/CRC16CC.d.ts.map +1 -1
  117. package/build/esm/cc/CRC16CC.js +30 -0
  118. package/build/esm/cc/CRC16CC.js.map +1 -1
  119. package/build/esm/cc/CentralSceneCC.d.ts.map +1 -1
  120. package/build/esm/cc/CentralSceneCC.js +1 -0
  121. package/build/esm/cc/CentralSceneCC.js.map +1 -1
  122. package/build/esm/cc/ClimateControlScheduleCC.d.ts.map +1 -1
  123. package/build/esm/cc/ClimateControlScheduleCC.js +3 -0
  124. package/build/esm/cc/ClimateControlScheduleCC.js.map +1 -1
  125. package/build/esm/cc/ClockCC.d.ts.map +1 -1
  126. package/build/esm/cc/ClockCC.js +1 -0
  127. package/build/esm/cc/ClockCC.js.map +1 -1
  128. package/build/esm/cc/ColorSwitchCC.d.ts.map +1 -1
  129. package/build/esm/cc/ColorSwitchCC.js +6 -0
  130. package/build/esm/cc/ColorSwitchCC.js.map +1 -1
  131. package/build/esm/cc/ConfigurationCC.d.ts +4 -0
  132. package/build/esm/cc/ConfigurationCC.d.ts.map +1 -1
  133. package/build/esm/cc/ConfigurationCC.js +27 -0
  134. package/build/esm/cc/ConfigurationCC.js.map +1 -1
  135. package/build/esm/cc/DoorLockCC.d.ts.map +1 -1
  136. package/build/esm/cc/DoorLockCC.js +2 -0
  137. package/build/esm/cc/DoorLockCC.js.map +1 -1
  138. package/build/esm/cc/DoorLockLoggingCC.d.ts.map +1 -1
  139. package/build/esm/cc/DoorLockLoggingCC.js +1 -0
  140. package/build/esm/cc/DoorLockLoggingCC.js.map +1 -1
  141. package/build/esm/cc/EnergyProductionCC.d.ts.map +1 -1
  142. package/build/esm/cc/EnergyProductionCC.js +2 -0
  143. package/build/esm/cc/EnergyProductionCC.js.map +1 -1
  144. package/build/esm/cc/EntryControlCC.d.ts.map +1 -1
  145. package/build/esm/cc/EntryControlCC.js +1 -0
  146. package/build/esm/cc/EntryControlCC.js.map +1 -1
  147. package/build/esm/cc/FirmwareUpdateMetaDataCC.d.ts.map +1 -1
  148. package/build/esm/cc/FirmwareUpdateMetaDataCC.js +5 -0
  149. package/build/esm/cc/FirmwareUpdateMetaDataCC.js.map +1 -1
  150. package/build/esm/cc/HumidityControlModeCC.d.ts.map +1 -1
  151. package/build/esm/cc/HumidityControlModeCC.js +1 -0
  152. package/build/esm/cc/HumidityControlModeCC.js.map +1 -1
  153. package/build/esm/cc/HumidityControlSetpointCC.d.ts.map +1 -1
  154. package/build/esm/cc/HumidityControlSetpointCC.js +4 -0
  155. package/build/esm/cc/HumidityControlSetpointCC.js.map +1 -1
  156. package/build/esm/cc/InclusionControllerCC.d.ts.map +1 -1
  157. package/build/esm/cc/InclusionControllerCC.js +2 -0
  158. package/build/esm/cc/InclusionControllerCC.js.map +1 -1
  159. package/build/esm/cc/IndicatorCC.d.ts.map +1 -1
  160. package/build/esm/cc/IndicatorCC.js +7 -0
  161. package/build/esm/cc/IndicatorCC.js.map +1 -1
  162. package/build/esm/cc/IrrigationCC.d.ts.map +1 -1
  163. package/build/esm/cc/IrrigationCC.js +9 -0
  164. package/build/esm/cc/IrrigationCC.js.map +1 -1
  165. package/build/esm/cc/LanguageCC.d.ts.map +1 -1
  166. package/build/esm/cc/LanguageCC.js +1 -0
  167. package/build/esm/cc/LanguageCC.js.map +1 -1
  168. package/build/esm/cc/LockCC.d.ts.map +1 -1
  169. package/build/esm/cc/LockCC.js +1 -0
  170. package/build/esm/cc/LockCC.js.map +1 -1
  171. package/build/esm/cc/ManufacturerProprietaryCC.d.ts.map +1 -1
  172. package/build/esm/cc/ManufacturerProprietaryCC.js +2 -0
  173. package/build/esm/cc/ManufacturerProprietaryCC.js.map +1 -1
  174. package/build/esm/cc/ManufacturerSpecificCC.d.ts.map +1 -1
  175. package/build/esm/cc/ManufacturerSpecificCC.js +2 -0
  176. package/build/esm/cc/ManufacturerSpecificCC.js.map +1 -1
  177. package/build/esm/cc/MeterCC.d.ts.map +1 -1
  178. package/build/esm/cc/MeterCC.js +4 -0
  179. package/build/esm/cc/MeterCC.js.map +1 -1
  180. package/build/esm/cc/MultiChannelAssociationCC.d.ts +2 -0
  181. package/build/esm/cc/MultiChannelAssociationCC.d.ts.map +1 -1
  182. package/build/esm/cc/MultiChannelAssociationCC.js +17 -0
  183. package/build/esm/cc/MultiChannelAssociationCC.js.map +1 -1
  184. package/build/esm/cc/MultiChannelCC.d.ts +10 -0
  185. package/build/esm/cc/MultiChannelCC.d.ts.map +1 -1
  186. package/build/esm/cc/MultiChannelCC.js +94 -0
  187. package/build/esm/cc/MultiChannelCC.js.map +1 -1
  188. package/build/esm/cc/MultiCommandCC.d.ts +4 -0
  189. package/build/esm/cc/MultiCommandCC.d.ts.map +1 -1
  190. package/build/esm/cc/MultiCommandCC.js +35 -1
  191. package/build/esm/cc/MultiCommandCC.js.map +1 -1
  192. package/build/esm/cc/MultilevelSensorCC.d.ts.map +1 -1
  193. package/build/esm/cc/MultilevelSensorCC.js +5 -0
  194. package/build/esm/cc/MultilevelSensorCC.js.map +1 -1
  195. package/build/esm/cc/MultilevelSwitchCC.d.ts.map +1 -1
  196. package/build/esm/cc/MultilevelSwitchCC.js +4 -0
  197. package/build/esm/cc/MultilevelSwitchCC.js.map +1 -1
  198. package/build/esm/cc/NodeNamingCC.d.ts.map +1 -1
  199. package/build/esm/cc/NodeNamingCC.js +2 -0
  200. package/build/esm/cc/NodeNamingCC.js.map +1 -1
  201. package/build/esm/cc/NotificationCC.d.ts.map +1 -1
  202. package/build/esm/cc/NotificationCC.js +9 -0
  203. package/build/esm/cc/NotificationCC.js.map +1 -1
  204. package/build/esm/cc/PowerlevelCC.d.ts.map +1 -1
  205. package/build/esm/cc/PowerlevelCC.js +4 -0
  206. package/build/esm/cc/PowerlevelCC.js.map +1 -1
  207. package/build/esm/cc/ProtectionCC.d.ts.map +1 -1
  208. package/build/esm/cc/ProtectionCC.js +3 -0
  209. package/build/esm/cc/ProtectionCC.js.map +1 -1
  210. package/build/esm/cc/SceneActivationCC.d.ts.map +1 -1
  211. package/build/esm/cc/SceneActivationCC.js +1 -0
  212. package/build/esm/cc/SceneActivationCC.js.map +1 -1
  213. package/build/esm/cc/SceneActuatorConfigurationCC.d.ts.map +1 -1
  214. package/build/esm/cc/SceneActuatorConfigurationCC.js +2 -0
  215. package/build/esm/cc/SceneActuatorConfigurationCC.js.map +1 -1
  216. package/build/esm/cc/SceneControllerConfigurationCC.d.ts.map +1 -1
  217. package/build/esm/cc/SceneControllerConfigurationCC.js +2 -0
  218. package/build/esm/cc/SceneControllerConfigurationCC.js.map +1 -1
  219. package/build/esm/cc/ScheduleEntryLockCC.d.ts.map +1 -1
  220. package/build/esm/cc/ScheduleEntryLockCC.js +14 -0
  221. package/build/esm/cc/ScheduleEntryLockCC.js.map +1 -1
  222. package/build/esm/cc/Security2CC.d.ts +4 -0
  223. package/build/esm/cc/Security2CC.d.ts.map +1 -1
  224. package/build/esm/cc/Security2CC.js +301 -0
  225. package/build/esm/cc/Security2CC.js.map +1 -1
  226. package/build/esm/cc/SecurityCC.d.ts +6 -0
  227. package/build/esm/cc/SecurityCC.d.ts.map +1 -1
  228. package/build/esm/cc/SecurityCC.js +73 -0
  229. package/build/esm/cc/SecurityCC.js.map +1 -1
  230. package/build/esm/cc/SoundSwitchCC.d.ts.map +1 -1
  231. package/build/esm/cc/SoundSwitchCC.js +7 -0
  232. package/build/esm/cc/SoundSwitchCC.js.map +1 -1
  233. package/build/esm/cc/SupervisionCC.d.ts +4 -0
  234. package/build/esm/cc/SupervisionCC.d.ts.map +1 -1
  235. package/build/esm/cc/SupervisionCC.js +30 -0
  236. package/build/esm/cc/SupervisionCC.js.map +1 -1
  237. package/build/esm/cc/ThermostatFanModeCC.d.ts.map +1 -1
  238. package/build/esm/cc/ThermostatFanModeCC.js +1 -0
  239. package/build/esm/cc/ThermostatFanModeCC.js.map +1 -1
  240. package/build/esm/cc/ThermostatModeCC.d.ts.map +1 -1
  241. package/build/esm/cc/ThermostatModeCC.js +3 -0
  242. package/build/esm/cc/ThermostatModeCC.js.map +1 -1
  243. package/build/esm/cc/ThermostatSetbackCC.d.ts.map +1 -1
  244. package/build/esm/cc/ThermostatSetbackCC.js +2 -0
  245. package/build/esm/cc/ThermostatSetbackCC.js.map +1 -1
  246. package/build/esm/cc/ThermostatSetpointCC.d.ts.map +1 -1
  247. package/build/esm/cc/ThermostatSetpointCC.js +6 -0
  248. package/build/esm/cc/ThermostatSetpointCC.js.map +1 -1
  249. package/build/esm/cc/TimeCC.d.ts.map +1 -1
  250. package/build/esm/cc/TimeCC.js +4 -0
  251. package/build/esm/cc/TimeCC.js.map +1 -1
  252. package/build/esm/cc/TimeParametersCC.d.ts.map +1 -1
  253. package/build/esm/cc/TimeParametersCC.js +1 -0
  254. package/build/esm/cc/TimeParametersCC.js.map +1 -1
  255. package/build/esm/cc/TransportServiceCC.d.ts +5 -0
  256. package/build/esm/cc/TransportServiceCC.d.ts.map +1 -1
  257. package/build/esm/cc/TransportServiceCC.js +24 -0
  258. package/build/esm/cc/TransportServiceCC.js.map +1 -1
  259. package/build/esm/cc/UserCodeCC.d.ts.map +1 -1
  260. package/build/esm/cc/UserCodeCC.js +12 -0
  261. package/build/esm/cc/UserCodeCC.js.map +1 -1
  262. package/build/esm/cc/VersionCC.d.ts.map +1 -1
  263. package/build/esm/cc/VersionCC.js +4 -0
  264. package/build/esm/cc/VersionCC.js.map +1 -1
  265. package/build/esm/cc/WakeUpCC.d.ts.map +1 -1
  266. package/build/esm/cc/WakeUpCC.js +1 -0
  267. package/build/esm/cc/WakeUpCC.js.map +1 -1
  268. package/build/esm/cc/WindowCoveringCC.d.ts.map +1 -1
  269. package/build/esm/cc/WindowCoveringCC.js +5 -0
  270. package/build/esm/cc/WindowCoveringCC.js.map +1 -1
  271. package/build/esm/cc/ZWavePlusCC.d.ts.map +1 -1
  272. package/build/esm/cc/ZWavePlusCC.js +1 -0
  273. package/build/esm/cc/ZWavePlusCC.js.map +1 -1
  274. package/build/esm/cc/ZWaveProtocolCC.d.ts.map +1 -1
  275. package/build/esm/cc/ZWaveProtocolCC.js +27 -0
  276. package/build/esm/cc/ZWaveProtocolCC.js.map +1 -1
  277. package/build/esm/cc/manufacturerProprietary/Decorators.d.ts.map +1 -1
  278. package/build/esm/cc/manufacturerProprietary/Decorators.js +2 -1
  279. package/build/esm/cc/manufacturerProprietary/Decorators.js.map +1 -1
  280. package/build/esm/cc/manufacturerProprietary/FibaroCC.d.ts.map +1 -1
  281. package/build/esm/cc/manufacturerProprietary/FibaroCC.js +3 -0
  282. package/build/esm/cc/manufacturerProprietary/FibaroCC.js.map +1 -1
  283. package/build/esm/lib/CommandClass.d.ts +15 -1
  284. package/build/esm/lib/CommandClass.d.ts.map +1 -1
  285. package/build/esm/lib/CommandClass.js +94 -1
  286. package/build/esm/lib/CommandClass.js.map +1 -1
  287. package/build/esm/lib/CommandClassDecorators.d.ts.map +1 -1
  288. package/build/esm/lib/CommandClassDecorators.js +2 -1
  289. package/build/esm/lib/CommandClassDecorators.js.map +1 -1
  290. package/build/esm/lib/Security2/Extension.js +1 -1
  291. package/build/esm/lib/Security2/Extension.js.map +1 -1
  292. package/package.json +4 -4
@@ -922,6 +922,7 @@ let Security2CCMessageEncapsulation = (() => {
922
922
  throw new ZWaveError("Multicast Security S2 encapsulation requires the MGRP extension", ZWaveErrorCodes.Security2CC_MissingExtension);
923
923
  }
924
924
  }
925
+ /** @deprecated Use {@link fromAsync} instead */
925
926
  static from(raw, ctx) {
926
927
  const securityManager = assertSecurityRX(ctx);
927
928
  validatePayload(raw.payload.length >= 2);
@@ -1131,6 +1132,7 @@ let Security2CCMessageEncapsulation = (() => {
1131
1132
  // make sure this contains a complete CC command that's worth splitting
1132
1133
  validatePayload(decryptedCCBytes.length >= 2);
1133
1134
  // and deserialize the CC
1135
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1134
1136
  encapsulated = CommandClass.parse(decryptedCCBytes, ctx);
1135
1137
  }
1136
1138
  const ret = new Security2CCMessageEncapsulation({
@@ -1148,6 +1150,232 @@ let Security2CCMessageEncapsulation = (() => {
1148
1150
  ret.plaintext = decryptedCCBytes;
1149
1151
  return ret;
1150
1152
  }
1153
+ static async fromAsync(raw, ctx) {
1154
+ const securityManager = assertSecurityRX(ctx);
1155
+ validatePayload(raw.payload.length >= 2);
1156
+ // Check the sequence number to avoid duplicates
1157
+ const sequenceNumber = raw.payload[0];
1158
+ // Ensure the node has a security class
1159
+ validatePayload.withReason("No security class granted")(ctx.getHighestSecurityClass(ctx.sourceNodeId) !== SecurityClass.None);
1160
+ const hasExtensions = !!(raw.payload[1] & 0b1);
1161
+ const hasEncryptedExtensions = !!(raw.payload[1] & 0b10);
1162
+ let offset = 2;
1163
+ const extensions = [];
1164
+ let mustDiscardCommand = false;
1165
+ const parseExtensions = (buffer, wasEncrypted) => {
1166
+ while (true) {
1167
+ if (buffer.length < offset + 2) {
1168
+ // An S2 extension was expected, but the buffer is too short
1169
+ mustDiscardCommand = true;
1170
+ return;
1171
+ }
1172
+ // The length field could be too large, which would cause part of the actual ciphertext
1173
+ // to be ignored. Try to avoid this for known extensions by checking the actual and expected length.
1174
+ const { actual: actualLength, expected: expectedLength } = Security2Extension
1175
+ .getExtensionLength(buffer.subarray(offset));
1176
+ // Parse the extension using the expected length if possible
1177
+ const extensionLength = expectedLength ?? actualLength;
1178
+ if (extensionLength < 2) {
1179
+ // An S2 extension was expected, but the length is too short
1180
+ mustDiscardCommand = true;
1181
+ return;
1182
+ }
1183
+ else if (extensionLength
1184
+ > buffer.length
1185
+ - offset
1186
+ - (wasEncrypted
1187
+ ? 0
1188
+ : SECURITY_S2_AUTH_TAG_LENGTH)) {
1189
+ // The supposed length is longer than the space the extensions may occupy
1190
+ mustDiscardCommand = true;
1191
+ return;
1192
+ }
1193
+ const extensionData = buffer.subarray(offset, offset + extensionLength);
1194
+ offset += extensionLength;
1195
+ const ext = Security2Extension.parse(extensionData);
1196
+ switch (validateS2Extension(ext, wasEncrypted)) {
1197
+ case ValidateS2ExtensionResult.OK:
1198
+ if (expectedLength != undefined
1199
+ && actualLength !== expectedLength) {
1200
+ // The extension length field does not match, ignore the extension
1201
+ }
1202
+ else {
1203
+ extensions.push(ext);
1204
+ }
1205
+ break;
1206
+ case ValidateS2ExtensionResult.DiscardExtension:
1207
+ // Do nothing
1208
+ break;
1209
+ case ValidateS2ExtensionResult.DiscardCommand:
1210
+ mustDiscardCommand = true;
1211
+ break;
1212
+ }
1213
+ // Check if that was the last extension
1214
+ if (!ext.moreToFollow)
1215
+ break;
1216
+ }
1217
+ };
1218
+ if (hasExtensions)
1219
+ parseExtensions(raw.payload, false);
1220
+ const mcctx = (() => {
1221
+ const multicastGroupId = getMulticastGroupId(extensions);
1222
+ if (ctx.frameType === "multicast" || ctx.frameType === "broadcast") {
1223
+ if (multicastGroupId == undefined) {
1224
+ validatePayload.fail("Multicast frames without MGRP extension");
1225
+ }
1226
+ return {
1227
+ isMulticast: true,
1228
+ groupId: multicastGroupId,
1229
+ };
1230
+ }
1231
+ else {
1232
+ return { isMulticast: false, groupId: multicastGroupId };
1233
+ }
1234
+ })();
1235
+ // If a command is to be discarded before decryption,
1236
+ // we still need to increment the SPAN or MPAN state
1237
+ if (mustDiscardCommand) {
1238
+ if (mcctx.isMulticast) {
1239
+ securityManager.nextPeerMPAN(ctx.sourceNodeId, mcctx.groupId);
1240
+ }
1241
+ else {
1242
+ securityManager.nextNonce(ctx.sourceNodeId);
1243
+ }
1244
+ validatePayload.fail("Invalid S2 extension");
1245
+ }
1246
+ let prevSequenceNumber;
1247
+ let mpanState;
1248
+ if (mcctx.isMulticast) {
1249
+ mpanState = securityManager.getPeerMPAN(ctx.sourceNodeId, mcctx.groupId);
1250
+ }
1251
+ else {
1252
+ // Don't accept duplicate Singlecast commands
1253
+ prevSequenceNumber = validateSequenceNumber(securityManager, ctx.sourceNodeId, sequenceNumber);
1254
+ // When a node receives a singlecast message after a multicast group was marked out of sync,
1255
+ // it must forget about the group.
1256
+ if (mcctx.groupId == undefined) {
1257
+ securityManager.resetOutOfSyncMPANs(ctx.sourceNodeId);
1258
+ }
1259
+ }
1260
+ const unencryptedPayload = raw.payload.subarray(0, offset);
1261
+ const ciphertext = raw.payload.subarray(offset, -SECURITY_S2_AUTH_TAG_LENGTH);
1262
+ const authTag = raw.payload.subarray(-SECURITY_S2_AUTH_TAG_LENGTH);
1263
+ const messageLength = 2 /* CommandClass.computeEncapsulationOverhead() */
1264
+ + raw.payload.length;
1265
+ const authData = getAuthenticationData(ctx.sourceNodeId, getDestinationIDRX(ctx, extensions), ctx.homeId, messageLength, unencryptedPayload);
1266
+ let decrypt;
1267
+ if (mcctx.isMulticast) {
1268
+ // For incoming multicast commands, make sure we have an MPAN
1269
+ if (mpanState?.type !== MPANState.MPAN) {
1270
+ // If we don't, mark the MPAN as out of sync, so we can respond accordingly on the singlecast followup
1271
+ securityManager.storePeerMPAN(ctx.sourceNodeId, mcctx.groupId, { type: MPANState.OutOfSync });
1272
+ failNoMPAN();
1273
+ }
1274
+ decrypt = () => decryptMulticast(ctx.sourceNodeId, securityManager, mcctx.groupId, ciphertext, authData, authTag);
1275
+ }
1276
+ else {
1277
+ // Decrypt payload and verify integrity
1278
+ const spanState = securityManager.getSPANState(ctx.sourceNodeId);
1279
+ // If we are not able to establish an SPAN yet, fail the decryption
1280
+ if (spanState.type === SPANState.None) {
1281
+ failNoSPAN();
1282
+ }
1283
+ else if (spanState.type === SPANState.RemoteEI) {
1284
+ // TODO: The specs are not clear how to handle this case
1285
+ // For now, do the same as if we didn't have any EI
1286
+ failNoSPAN();
1287
+ }
1288
+ decrypt = () => decryptSinglecast(ctx, securityManager, ctx.sourceNodeId, sequenceNumber, prevSequenceNumber, ciphertext, authData, authTag, spanState, extensions);
1289
+ }
1290
+ let plaintext;
1291
+ let authOK = false;
1292
+ let key;
1293
+ let iv;
1294
+ let decryptionSecurityClass;
1295
+ // If the Receiver is unable to authenticate the singlecast message with the current SPAN,
1296
+ // the Receiver SHOULD try decrypting the message with one or more of the following SPAN values,
1297
+ // stopping when decryption is successful or the maximum number of iterations is reached.
1298
+ // If the Receiver is unable to decrypt the S2 MC frame with the current MPAN, the Receiver MAY try
1299
+ // decrypting the frame with one or more of the subsequent MPAN values, stopping when decryption is
1300
+ // successful or the maximum number of iterations is reached.
1301
+ const decryptAttempts = mcctx.isMulticast
1302
+ ? MAX_DECRYPT_ATTEMPTS_MULTICAST
1303
+ : mcctx.groupId != undefined
1304
+ ? MAX_DECRYPT_ATTEMPTS_SC_FOLLOWUP
1305
+ : MAX_DECRYPT_ATTEMPTS_SINGLECAST;
1306
+ for (let i = 0; i < decryptAttempts; i++) {
1307
+ ({
1308
+ plaintext,
1309
+ authOK,
1310
+ key,
1311
+ iv,
1312
+ securityClass: decryptionSecurityClass,
1313
+ } = decrypt());
1314
+ if (!!authOK && !!plaintext)
1315
+ break;
1316
+ // No need to try further SPANs if we just got the sender's EI
1317
+ if (!!getSenderEI(extensions))
1318
+ break;
1319
+ }
1320
+ // If authentication fails, do so with an error code that instructs the
1321
+ // applHost to tell the node we have no nonce
1322
+ if (!authOK || !plaintext) {
1323
+ if (mcctx.isMulticast) {
1324
+ // Mark the MPAN as out of sync
1325
+ securityManager.storePeerMPAN(ctx.sourceNodeId, mcctx.groupId, { type: MPANState.OutOfSync });
1326
+ validatePayload.fail(ZWaveErrorCodes.Security2CC_CannotDecodeMulticast);
1327
+ }
1328
+ else {
1329
+ validatePayload.fail(ZWaveErrorCodes.Security2CC_CannotDecode);
1330
+ }
1331
+ }
1332
+ else if (!mcctx.isMulticast && mcctx.groupId != undefined) {
1333
+ // After reception of a singlecast followup, the MPAN state must be increased
1334
+ securityManager.tryIncrementPeerMPAN(ctx.sourceNodeId, mcctx.groupId);
1335
+ }
1336
+ // Remember which security class was used to decrypt this message, so we can discard it later
1337
+ const securityClass = decryptionSecurityClass;
1338
+ offset = 0;
1339
+ if (hasEncryptedExtensions)
1340
+ parseExtensions(plaintext, true);
1341
+ // Before we can continue, check if the command must be discarded
1342
+ if (mustDiscardCommand) {
1343
+ validatePayload.fail("Invalid extension");
1344
+ }
1345
+ // If the MPAN extension was received, store the MPAN
1346
+ if (!mcctx.isMulticast) {
1347
+ const mpanExtension = extensions.find((e) => e instanceof MPANExtension);
1348
+ if (mpanExtension) {
1349
+ securityManager.storePeerMPAN(ctx.sourceNodeId, mpanExtension.groupId, {
1350
+ type: MPANState.MPAN,
1351
+ currentMPAN: mpanExtension.innerMPANState,
1352
+ });
1353
+ }
1354
+ }
1355
+ // Not every S2 message includes an encapsulated CC
1356
+ const decryptedCCBytes = plaintext.subarray(offset);
1357
+ let encapsulated;
1358
+ if (decryptedCCBytes.length > 0) {
1359
+ // make sure this contains a complete CC command that's worth splitting
1360
+ validatePayload(decryptedCCBytes.length >= 2);
1361
+ // and deserialize the CC
1362
+ encapsulated = await CommandClass.parseAsync(decryptedCCBytes, ctx);
1363
+ }
1364
+ const ret = new Security2CCMessageEncapsulation({
1365
+ nodeId: ctx.sourceNodeId,
1366
+ sequenceNumber,
1367
+ securityClass,
1368
+ extensions,
1369
+ encapsulated,
1370
+ });
1371
+ // Remember for debugging purposes
1372
+ ret.key = key;
1373
+ ret.iv = iv;
1374
+ ret.authData = authData;
1375
+ ret.authTag = authTag;
1376
+ ret.plaintext = decryptedCCBytes;
1377
+ return ret;
1378
+ }
1151
1379
  securityClass;
1152
1380
  // Only used for testing/debugging purposes
1153
1381
  key;
@@ -1227,6 +1455,7 @@ let Security2CCMessageEncapsulation = (() => {
1227
1455
  }
1228
1456
  }
1229
1457
  }
1458
+ /** @deprecated Use {@link serializeAsync} instead */
1230
1459
  serialize(ctx) {
1231
1460
  const securityManager = assertSecurityTX(ctx, this.nodeId);
1232
1461
  this.ensureSequenceNumber(securityManager);
@@ -1242,6 +1471,7 @@ let Security2CCMessageEncapsulation = (() => {
1242
1471
  ]),
1243
1472
  ...unencryptedExtensions.map((e, index) => e.serialize(index < unencryptedExtensions.length - 1)),
1244
1473
  ]);
1474
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1245
1475
  const serializedCC = this.encapsulated?.serialize(ctx)
1246
1476
  ?? new Bytes();
1247
1477
  const plaintextPayload = Bytes.concat([
@@ -1285,8 +1515,69 @@ let Security2CCMessageEncapsulation = (() => {
1285
1515
  ciphertextPayload,
1286
1516
  authTag,
1287
1517
  ]);
1518
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1288
1519
  return super.serialize(ctx);
1289
1520
  }
1521
+ async serializeAsync(ctx) {
1522
+ const securityManager = assertSecurityTX(ctx, this.nodeId);
1523
+ this.ensureSequenceNumber(securityManager);
1524
+ // Include Sender EI in the command if we only have the receiver's EI
1525
+ this.maybeAddSPANExtension(ctx, securityManager);
1526
+ const unencryptedExtensions = this.extensions.filter((e) => !e.isEncrypted());
1527
+ const encryptedExtensions = this.extensions.filter((e) => e.isEncrypted());
1528
+ const unencryptedPayload = Bytes.concat([
1529
+ Bytes.from([
1530
+ this.sequenceNumber,
1531
+ (encryptedExtensions.length > 0 ? 0b10 : 0)
1532
+ | (unencryptedExtensions.length > 0 ? 1 : 0),
1533
+ ]),
1534
+ ...unencryptedExtensions.map((e, index) => e.serialize(index < unencryptedExtensions.length - 1)),
1535
+ ]);
1536
+ const serializedCC = (await this.encapsulated?.serializeAsync(ctx))
1537
+ ?? new Bytes();
1538
+ const plaintextPayload = Bytes.concat([
1539
+ ...encryptedExtensions.map((e, index) => e.serialize(index < encryptedExtensions.length - 1)),
1540
+ serializedCC,
1541
+ ]);
1542
+ // Generate the authentication data for CCM encryption
1543
+ const destinationTag = getDestinationIDTX.call(this);
1544
+ const messageLength = this.computeEncapsulationOverhead()
1545
+ + serializedCC.length;
1546
+ const authData = getAuthenticationData(ctx.ownNodeId, destinationTag, ctx.homeId, messageLength, unencryptedPayload);
1547
+ let key;
1548
+ let iv;
1549
+ if (this.isSinglecast()) {
1550
+ // Singlecast:
1551
+ // Generate a nonce for encryption, and remember it to attempt decryption
1552
+ // of potential in-flight messages from the target node.
1553
+ iv = securityManager.nextNonce(this.nodeId, true);
1554
+ const { keyCCM } =
1555
+ // Prefer the overridden security class if it was given
1556
+ this.securityClass != undefined
1557
+ ? securityManager.getKeysForSecurityClass(this.securityClass)
1558
+ : securityManager.getKeysForNode(this.nodeId);
1559
+ key = keyCCM;
1560
+ }
1561
+ else {
1562
+ // Multicast:
1563
+ const keyAndIV = securityManager.getMulticastKeyAndIV(destinationTag);
1564
+ key = keyAndIV.key;
1565
+ iv = keyAndIV.iv;
1566
+ }
1567
+ const { ciphertext: ciphertextPayload, authTag } = encryptAES128CCM(key, iv, plaintextPayload, authData, SECURITY_S2_AUTH_TAG_LENGTH);
1568
+ // Remember key and IV for debugging purposes
1569
+ this.key = key;
1570
+ this.iv = iv;
1571
+ this.authData = authData;
1572
+ this.authTag = authTag;
1573
+ this.ciphertext = ciphertextPayload;
1574
+ this.payload = Bytes.concat([
1575
+ unencryptedPayload,
1576
+ ciphertextPayload,
1577
+ authTag,
1578
+ ]);
1579
+ return super.serializeAsync(ctx);
1580
+ }
1290
1581
  computeEncapsulationOverhead() {
1291
1582
  // Security S2 adds:
1292
1583
  // * 1 byte sequence number
@@ -1422,6 +1713,7 @@ let Security2CCNonceReport = (() => {
1422
1713
  if (this.SOS) {
1423
1714
  this.payload = Bytes.concat([this.payload, this.receiverEI]);
1424
1715
  }
1716
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1425
1717
  return super.serialize(ctx);
1426
1718
  }
1427
1719
  toLogEntry(ctx) {
@@ -1484,6 +1776,7 @@ let Security2CCNonceGet = (() => {
1484
1776
  const securityManager = assertSecurityTX(ctx, this.nodeId);
1485
1777
  this.ensureSequenceNumber(securityManager);
1486
1778
  this.payload = Bytes.from([this.sequenceNumber]);
1779
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1487
1780
  return super.serialize(ctx);
1488
1781
  }
1489
1782
  toLogEntry(ctx) {
@@ -1560,6 +1853,7 @@ let Security2CCKEXReport = (() => {
1560
1853
  encodeBitMask(this.supportedECDHProfiles, 7, ECDHProfiles.Curve25519),
1561
1854
  encodeBitMask(this.requestedKeys, SecurityClass.S0_Legacy, SecurityClass.S2_Unauthenticated),
1562
1855
  ]);
1856
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1563
1857
  return super.serialize(ctx);
1564
1858
  }
1565
1859
  toLogEntry(ctx) {
@@ -1687,6 +1981,7 @@ let Security2CCKEXSet = (() => {
1687
1981
  encodeBitMask([this.selectedECDHProfile], 7, ECDHProfiles.Curve25519),
1688
1982
  encodeBitMask(this.grantedKeys, SecurityClass.S0_Legacy, SecurityClass.S2_Unauthenticated),
1689
1983
  ]);
1984
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1690
1985
  return super.serialize(ctx);
1691
1986
  }
1692
1987
  toLogEntry(ctx) {
@@ -1737,6 +2032,7 @@ let Security2CCKEXFail = (() => {
1737
2032
  failType;
1738
2033
  serialize(ctx) {
1739
2034
  this.payload = Bytes.from([this.failType]);
2035
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1740
2036
  return super.serialize(ctx);
1741
2037
  }
1742
2038
  toLogEntry(ctx) {
@@ -1786,6 +2082,7 @@ let Security2CCPublicKeyReport = (() => {
1786
2082
  Bytes.from([this.includingNode ? 1 : 0]),
1787
2083
  this.publicKey,
1788
2084
  ]);
2085
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1789
2086
  return super.serialize(ctx);
1790
2087
  }
1791
2088
  toLogEntry(ctx) {
@@ -1838,6 +2135,7 @@ let Security2CCNetworkKeyReport = (() => {
1838
2135
  securityClassToBitMask(this.grantedKey),
1839
2136
  this.networkKey,
1840
2137
  ]);
2138
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1841
2139
  return super.serialize(ctx);
1842
2140
  }
1843
2141
  toLogEntry(ctx) {
@@ -1884,6 +2182,7 @@ let Security2CCNetworkKeyGet = (() => {
1884
2182
  requestedKey;
1885
2183
  serialize(ctx) {
1886
2184
  this.payload = securityClassToBitMask(this.requestedKey);
2185
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1887
2186
  return super.serialize(ctx);
1888
2187
  }
1889
2188
  toLogEntry(ctx) {
@@ -1953,6 +2252,7 @@ let Security2CCTransferEnd = (() => {
1953
2252
  this.payload = Bytes.from([
1954
2253
  (this.keyVerified ? 0b10 : 0) + (this.keyRequestComplete ? 0b1 : 0),
1955
2254
  ]);
2255
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
1956
2256
  return super.serialize(ctx);
1957
2257
  }
1958
2258
  toLogEntry(ctx) {
@@ -2002,6 +2302,7 @@ let Security2CCCommandsSupportedReport = (() => {
2002
2302
  supportedCCs;
2003
2303
  serialize(ctx) {
2004
2304
  this.payload = encodeCCList(this.supportedCCs, []);
2305
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
2005
2306
  return super.serialize(ctx);
2006
2307
  }
2007
2308
  toLogEntry(ctx) {