@zwave-js/cc 9.3.1-0-pr-4662-79458fb

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 (297) hide show
  1. package/build/cc/AlarmSensorCC.d.ts +54 -0
  2. package/build/cc/AlarmSensorCC.d.ts.map +1 -0
  3. package/build/cc/AlarmSensorCC.js +378 -0
  4. package/build/cc/AlarmSensorCC.js.map +1 -0
  5. package/build/cc/AssociationCC.d.ts +123 -0
  6. package/build/cc/AssociationCC.d.ts.map +1 -0
  7. package/build/cc/AssociationCC.js +615 -0
  8. package/build/cc/AssociationCC.js.map +1 -0
  9. package/build/cc/AssociationGroupInfoCC.d.ts +97 -0
  10. package/build/cc/AssociationGroupInfoCC.d.ts.map +1 -0
  11. package/build/cc/AssociationGroupInfoCC.js +530 -0
  12. package/build/cc/AssociationGroupInfoCC.js.map +1 -0
  13. package/build/cc/BarrierOperatorCC.d.ts +75 -0
  14. package/build/cc/BarrierOperatorCC.d.ts.map +1 -0
  15. package/build/cc/BarrierOperatorCC.js +492 -0
  16. package/build/cc/BarrierOperatorCC.js.map +1 -0
  17. package/build/cc/BasicCC.d.ts +51 -0
  18. package/build/cc/BasicCC.d.ts.map +1 -0
  19. package/build/cc/BasicCC.js +344 -0
  20. package/build/cc/BasicCC.js.map +1 -0
  21. package/build/cc/BatteryCC.d.ts +56 -0
  22. package/build/cc/BatteryCC.d.ts.map +1 -0
  23. package/build/cc/BatteryCC.js +417 -0
  24. package/build/cc/BatteryCC.js.map +1 -0
  25. package/build/cc/BinarySensorCC.d.ts +52 -0
  26. package/build/cc/BinarySensorCC.d.ts.map +1 -0
  27. package/build/cc/BinarySensorCC.js +321 -0
  28. package/build/cc/BinarySensorCC.js.map +1 -0
  29. package/build/cc/BinarySwitchCC.d.ts +55 -0
  30. package/build/cc/BinarySwitchCC.d.ts.map +1 -0
  31. package/build/cc/BinarySwitchCC.js +327 -0
  32. package/build/cc/BinarySwitchCC.js.map +1 -0
  33. package/build/cc/CRC16CC.d.ts +28 -0
  34. package/build/cc/CRC16CC.d.ts.map +1 -0
  35. package/build/cc/CRC16CC.js +109 -0
  36. package/build/cc/CRC16CC.js.map +1 -0
  37. package/build/cc/CentralSceneCC.d.ts +69 -0
  38. package/build/cc/CentralSceneCC.d.ts.map +1 -0
  39. package/build/cc/CentralSceneCC.js +443 -0
  40. package/build/cc/CentralSceneCC.js.map +1 -0
  41. package/build/cc/ClimateControlScheduleCC.d.ts +78 -0
  42. package/build/cc/ClimateControlScheduleCC.d.ts.map +1 -0
  43. package/build/cc/ClimateControlScheduleCC.js +417 -0
  44. package/build/cc/ClimateControlScheduleCC.js.map +1 -0
  45. package/build/cc/ClockCC.d.ts +40 -0
  46. package/build/cc/ClockCC.d.ts.map +1 -0
  47. package/build/cc/ClockCC.js +185 -0
  48. package/build/cc/ClockCC.js.map +1 -0
  49. package/build/cc/ColorSwitchCC.d.ts +98 -0
  50. package/build/cc/ColorSwitchCC.d.ts.map +1 -0
  51. package/build/cc/ColorSwitchCC.js +1045 -0
  52. package/build/cc/ColorSwitchCC.js.map +1 -0
  53. package/build/cc/ConfigurationCC.d.ts +315 -0
  54. package/build/cc/ConfigurationCC.d.ts.map +1 -0
  55. package/build/cc/ConfigurationCC.js +2257 -0
  56. package/build/cc/ConfigurationCC.js.map +1 -0
  57. package/build/cc/DeviceResetLocallyCC.d.ts +9 -0
  58. package/build/cc/DeviceResetLocallyCC.d.ts.map +1 -0
  59. package/build/cc/DeviceResetLocallyCC.js +28 -0
  60. package/build/cc/DeviceResetLocallyCC.js.map +1 -0
  61. package/build/cc/DoorLockCC.d.ts +116 -0
  62. package/build/cc/DoorLockCC.d.ts.map +1 -0
  63. package/build/cc/DoorLockCC.js +1112 -0
  64. package/build/cc/DoorLockCC.js.map +1 -0
  65. package/build/cc/DoorLockLoggingCC.d.ts +41 -0
  66. package/build/cc/DoorLockLoggingCC.d.ts.map +1 -0
  67. package/build/cc/DoorLockLoggingCC.js +288 -0
  68. package/build/cc/DoorLockLoggingCC.js.map +1 -0
  69. package/build/cc/EntryControlCC.d.ts +71 -0
  70. package/build/cc/EntryControlCC.d.ts.map +1 -0
  71. package/build/cc/EntryControlCC.js +492 -0
  72. package/build/cc/EntryControlCC.js.map +1 -0
  73. package/build/cc/FirmwareUpdateMetaDataCC.d.ts +148 -0
  74. package/build/cc/FirmwareUpdateMetaDataCC.d.ts.map +1 -0
  75. package/build/cc/FirmwareUpdateMetaDataCC.js +727 -0
  76. package/build/cc/FirmwareUpdateMetaDataCC.js.map +1 -0
  77. package/build/cc/HailCC.d.ts +6 -0
  78. package/build/cc/HailCC.d.ts.map +1 -0
  79. package/build/cc/HailCC.js +23 -0
  80. package/build/cc/HailCC.js.map +1 -0
  81. package/build/cc/HumidityControlModeCC.d.ts +47 -0
  82. package/build/cc/HumidityControlModeCC.d.ts.map +1 -0
  83. package/build/cc/HumidityControlModeCC.js +288 -0
  84. package/build/cc/HumidityControlModeCC.js.map +1 -0
  85. package/build/cc/HumidityControlOperatingStateCC.d.ts +24 -0
  86. package/build/cc/HumidityControlOperatingStateCC.d.ts.map +1 -0
  87. package/build/cc/HumidityControlOperatingStateCC.js +129 -0
  88. package/build/cc/HumidityControlOperatingStateCC.js.map +1 -0
  89. package/build/cc/HumidityControlSetpointCC.d.ts +103 -0
  90. package/build/cc/HumidityControlSetpointCC.d.ts.map +1 -0
  91. package/build/cc/HumidityControlSetpointCC.js +626 -0
  92. package/build/cc/HumidityControlSetpointCC.js.map +1 -0
  93. package/build/cc/IndicatorCC.d.ts +88 -0
  94. package/build/cc/IndicatorCC.d.ts.map +1 -0
  95. package/build/cc/IndicatorCC.js +758 -0
  96. package/build/cc/IndicatorCC.js.map +1 -0
  97. package/build/cc/IrrigationCC.d.ts +278 -0
  98. package/build/cc/IrrigationCC.d.ts.map +1 -0
  99. package/build/cc/IrrigationCC.js +2062 -0
  100. package/build/cc/IrrigationCC.js.map +1 -0
  101. package/build/cc/LanguageCC.d.ts +41 -0
  102. package/build/cc/LanguageCC.d.ts.map +1 -0
  103. package/build/cc/LanguageCC.js +220 -0
  104. package/build/cc/LanguageCC.js.map +1 -0
  105. package/build/cc/LockCC.d.ts +41 -0
  106. package/build/cc/LockCC.d.ts.map +1 -0
  107. package/build/cc/LockCC.js +185 -0
  108. package/build/cc/LockCC.js.map +1 -0
  109. package/build/cc/ManufacturerProprietaryCC.d.ts +31 -0
  110. package/build/cc/ManufacturerProprietaryCC.d.ts.map +1 -0
  111. package/build/cc/ManufacturerProprietaryCC.js +275 -0
  112. package/build/cc/ManufacturerProprietaryCC.js.map +1 -0
  113. package/build/cc/ManufacturerSpecificCC.d.ts +59 -0
  114. package/build/cc/ManufacturerSpecificCC.d.ts.map +1 -0
  115. package/build/cc/ManufacturerSpecificCC.js +285 -0
  116. package/build/cc/ManufacturerSpecificCC.js.map +1 -0
  117. package/build/cc/MeterCC.d.ts +100 -0
  118. package/build/cc/MeterCC.d.ts.map +1 -0
  119. package/build/cc/MeterCC.js +820 -0
  120. package/build/cc/MeterCC.js.map +1 -0
  121. package/build/cc/MultiChannelAssociationCC.d.ts +127 -0
  122. package/build/cc/MultiChannelAssociationCC.d.ts.map +1 -0
  123. package/build/cc/MultiChannelAssociationCC.js +883 -0
  124. package/build/cc/MultiChannelAssociationCC.js.map +1 -0
  125. package/build/cc/MultiChannelCC.d.ts +164 -0
  126. package/build/cc/MultiChannelCC.d.ts.map +1 -0
  127. package/build/cc/MultiChannelCC.js +1004 -0
  128. package/build/cc/MultiChannelCC.js.map +1 -0
  129. package/build/cc/MultiCommandCC.d.ts +28 -0
  130. package/build/cc/MultiCommandCC.d.ts.map +1 -0
  131. package/build/cc/MultiCommandCC.js +137 -0
  132. package/build/cc/MultiCommandCC.js.map +1 -0
  133. package/build/cc/MultilevelSensorCC.d.ts +83 -0
  134. package/build/cc/MultilevelSensorCC.d.ts.map +1 -0
  135. package/build/cc/MultilevelSensorCC.js +633 -0
  136. package/build/cc/MultilevelSensorCC.js.map +1 -0
  137. package/build/cc/MultilevelSwitchCC.d.ts +86 -0
  138. package/build/cc/MultilevelSwitchCC.d.ts.map +1 -0
  139. package/build/cc/MultilevelSwitchCC.js +774 -0
  140. package/build/cc/MultilevelSwitchCC.js.map +1 -0
  141. package/build/cc/NoOperationCC.d.ts +17 -0
  142. package/build/cc/NoOperationCC.d.ts.map +1 -0
  143. package/build/cc/NoOperationCC.js +50 -0
  144. package/build/cc/NoOperationCC.js.map +1 -0
  145. package/build/cc/NodeNamingCC.d.ts +57 -0
  146. package/build/cc/NodeNamingCC.d.ts.map +1 -0
  147. package/build/cc/NodeNamingCC.js +313 -0
  148. package/build/cc/NodeNamingCC.js.map +1 -0
  149. package/build/cc/NotificationCC.d.ts +127 -0
  150. package/build/cc/NotificationCC.d.ts.map +1 -0
  151. package/build/cc/NotificationCC.js +1193 -0
  152. package/build/cc/NotificationCC.js.map +1 -0
  153. package/build/cc/PowerlevelCC.d.ts +63 -0
  154. package/build/cc/PowerlevelCC.d.ts.map +1 -0
  155. package/build/cc/PowerlevelCC.js +262 -0
  156. package/build/cc/PowerlevelCC.js.map +1 -0
  157. package/build/cc/ProtectionCC.d.ts +94 -0
  158. package/build/cc/ProtectionCC.d.ts.map +1 -0
  159. package/build/cc/ProtectionCC.js +630 -0
  160. package/build/cc/ProtectionCC.js.map +1 -0
  161. package/build/cc/SceneActivationCC.d.ts +34 -0
  162. package/build/cc/SceneActivationCC.d.ts.map +1 -0
  163. package/build/cc/SceneActivationCC.js +170 -0
  164. package/build/cc/SceneActivationCC.js.map +1 -0
  165. package/build/cc/SceneActuatorConfigurationCC.d.ts +52 -0
  166. package/build/cc/SceneActuatorConfigurationCC.d.ts.map +1 -0
  167. package/build/cc/SceneActuatorConfigurationCC.js +368 -0
  168. package/build/cc/SceneActuatorConfigurationCC.js.map +1 -0
  169. package/build/cc/SceneControllerConfigurationCC.d.ts +61 -0
  170. package/build/cc/SceneControllerConfigurationCC.d.ts.map +1 -0
  171. package/build/cc/SceneControllerConfigurationCC.js +444 -0
  172. package/build/cc/SceneControllerConfigurationCC.js.map +1 -0
  173. package/build/cc/Security2CC.d.ts +213 -0
  174. package/build/cc/Security2CC.d.ts.map +1 -0
  175. package/build/cc/Security2CC.js +1124 -0
  176. package/build/cc/Security2CC.js.map +1 -0
  177. package/build/cc/SecurityCC.d.ts +109 -0
  178. package/build/cc/SecurityCC.d.ts.map +1 -0
  179. package/build/cc/SecurityCC.js +609 -0
  180. package/build/cc/SecurityCC.js.map +1 -0
  181. package/build/cc/SoundSwitchCC.d.ts +87 -0
  182. package/build/cc/SoundSwitchCC.d.ts.map +1 -0
  183. package/build/cc/SoundSwitchCC.js +548 -0
  184. package/build/cc/SoundSwitchCC.js.map +1 -0
  185. package/build/cc/SupervisionCC.d.ts +63 -0
  186. package/build/cc/SupervisionCC.d.ts.map +1 -0
  187. package/build/cc/SupervisionCC.js +239 -0
  188. package/build/cc/SupervisionCC.js.map +1 -0
  189. package/build/cc/ThermostatFanModeCC.d.ts +53 -0
  190. package/build/cc/ThermostatFanModeCC.d.ts.map +1 -0
  191. package/build/cc/ThermostatFanModeCC.js +359 -0
  192. package/build/cc/ThermostatFanModeCC.js.map +1 -0
  193. package/build/cc/ThermostatFanStateCC.d.ts +24 -0
  194. package/build/cc/ThermostatFanStateCC.d.ts.map +1 -0
  195. package/build/cc/ThermostatFanStateCC.js +131 -0
  196. package/build/cc/ThermostatFanStateCC.js.map +1 -0
  197. package/build/cc/ThermostatModeCC.d.ts +58 -0
  198. package/build/cc/ThermostatModeCC.d.ts.map +1 -0
  199. package/build/cc/ThermostatModeCC.js +370 -0
  200. package/build/cc/ThermostatModeCC.js.map +1 -0
  201. package/build/cc/ThermostatOperatingStateCC.d.ts +24 -0
  202. package/build/cc/ThermostatOperatingStateCC.d.ts.map +1 -0
  203. package/build/cc/ThermostatOperatingStateCC.js +127 -0
  204. package/build/cc/ThermostatOperatingStateCC.js.map +1 -0
  205. package/build/cc/ThermostatSetbackCC.d.ts +42 -0
  206. package/build/cc/ThermostatSetbackCC.d.ts.map +1 -0
  207. package/build/cc/ThermostatSetbackCC.js +237 -0
  208. package/build/cc/ThermostatSetbackCC.js.map +1 -0
  209. package/build/cc/ThermostatSetpointCC.d.ts +98 -0
  210. package/build/cc/ThermostatSetpointCC.d.ts.map +1 -0
  211. package/build/cc/ThermostatSetpointCC.js +707 -0
  212. package/build/cc/ThermostatSetpointCC.js.map +1 -0
  213. package/build/cc/TimeCC.d.ts +78 -0
  214. package/build/cc/TimeCC.d.ts.map +1 -0
  215. package/build/cc/TimeCC.js +373 -0
  216. package/build/cc/TimeCC.js.map +1 -0
  217. package/build/cc/TimeParametersCC.d.ts +40 -0
  218. package/build/cc/TimeParametersCC.d.ts.map +1 -0
  219. package/build/cc/TimeParametersCC.js +275 -0
  220. package/build/cc/TimeParametersCC.js.map +1 -0
  221. package/build/cc/TransportServiceCC.d.ts +101 -0
  222. package/build/cc/TransportServiceCC.d.ts.map +1 -0
  223. package/build/cc/TransportServiceCC.js +404 -0
  224. package/build/cc/TransportServiceCC.js.map +1 -0
  225. package/build/cc/UserCodeCC.d.ts +219 -0
  226. package/build/cc/UserCodeCC.d.ts.map +1 -0
  227. package/build/cc/UserCodeCC.js +1526 -0
  228. package/build/cc/UserCodeCC.js.map +1 -0
  229. package/build/cc/VersionCC.d.ts +91 -0
  230. package/build/cc/VersionCC.d.ts.map +1 -0
  231. package/build/cc/VersionCC.js +654 -0
  232. package/build/cc/VersionCC.js.map +1 -0
  233. package/build/cc/WakeUpCC.d.ts +67 -0
  234. package/build/cc/WakeUpCC.d.ts.map +1 -0
  235. package/build/cc/WakeUpCC.js +425 -0
  236. package/build/cc/WakeUpCC.js.map +1 -0
  237. package/build/cc/ZWavePlusCC.d.ts +40 -0
  238. package/build/cc/ZWavePlusCC.d.ts.map +1 -0
  239. package/build/cc/ZWavePlusCC.js +269 -0
  240. package/build/cc/ZWavePlusCC.js.map +1 -0
  241. package/build/cc/index.d.ts +64 -0
  242. package/build/cc/index.d.ts.map +1 -0
  243. package/build/cc/index.js +496 -0
  244. package/build/cc/index.js.map +1 -0
  245. package/build/cc/manufacturerProprietary/FibaroCC.d.ts +62 -0
  246. package/build/cc/manufacturerProprietary/FibaroCC.d.ts.map +1 -0
  247. package/build/cc/manufacturerProprietary/FibaroCC.js +247 -0
  248. package/build/cc/manufacturerProprietary/FibaroCC.js.map +1 -0
  249. package/build/index.d.ts +11 -0
  250. package/build/index.d.ts.map +1 -0
  251. package/build/index.js +48 -0
  252. package/build/index.js.map +1 -0
  253. package/build/index_safe.d.ts +4 -0
  254. package/build/index_safe.d.ts.map +1 -0
  255. package/build/index_safe.js +30 -0
  256. package/build/index_safe.js.map +1 -0
  257. package/build/lib/API.d.ts +176 -0
  258. package/build/lib/API.d.ts.map +1 -0
  259. package/build/lib/API.js +325 -0
  260. package/build/lib/API.js.map +1 -0
  261. package/build/lib/CommandClass.d.ts +341 -0
  262. package/build/lib/CommandClass.d.ts.map +1 -0
  263. package/build/lib/CommandClass.js +1088 -0
  264. package/build/lib/CommandClass.js.map +1 -0
  265. package/build/lib/EncapsulatingCommandClass.d.ts +35 -0
  266. package/build/lib/EncapsulatingCommandClass.d.ts.map +1 -0
  267. package/build/lib/EncapsulatingCommandClass.js +53 -0
  268. package/build/lib/EncapsulatingCommandClass.js.map +1 -0
  269. package/build/lib/ICommandClassContainer.d.ts +9 -0
  270. package/build/lib/ICommandClassContainer.d.ts.map +1 -0
  271. package/build/lib/ICommandClassContainer.js +12 -0
  272. package/build/lib/ICommandClassContainer.js.map +1 -0
  273. package/build/lib/NotificationEventPayload.d.ts +11 -0
  274. package/build/lib/NotificationEventPayload.d.ts.map +1 -0
  275. package/build/lib/NotificationEventPayload.js +11 -0
  276. package/build/lib/NotificationEventPayload.js.map +1 -0
  277. package/build/lib/Security2/Extension.d.ts +87 -0
  278. package/build/lib/Security2/Extension.d.ts.map +1 -0
  279. package/build/lib/Security2/Extension.js +235 -0
  280. package/build/lib/Security2/Extension.js.map +1 -0
  281. package/build/lib/Security2/shared.d.ts +31 -0
  282. package/build/lib/Security2/shared.d.ts.map +1 -0
  283. package/build/lib/Security2/shared.js +37 -0
  284. package/build/lib/Security2/shared.js.map +1 -0
  285. package/build/lib/_Types.d.ts +1446 -0
  286. package/build/lib/_Types.d.ts.map +1 -0
  287. package/build/lib/_Types.js +1334 -0
  288. package/build/lib/_Types.js.map +1 -0
  289. package/build/lib/serializers.d.ts +24 -0
  290. package/build/lib/serializers.d.ts.map +1 -0
  291. package/build/lib/serializers.js +66 -0
  292. package/build/lib/serializers.js.map +1 -0
  293. package/build/lib/utils.d.ts +13 -0
  294. package/build/lib/utils.d.ts.map +1 -0
  295. package/build/lib/utils.js +675 -0
  296. package/build/lib/utils.js.map +1 -0
  297. package/package.json +77 -0
@@ -0,0 +1,1124 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var Security2CC_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.Security2CCCommandsSupportedGet = exports.Security2CCCommandsSupportedReport = exports.Security2CCTransferEnd = exports.Security2CCNetworkKeyVerify = exports.Security2CCNetworkKeyGet = exports.Security2CCNetworkKeyReport = exports.Security2CCPublicKeyReport = exports.Security2CCKEXFail = exports.Security2CCKEXSet = exports.Security2CCKEXGet = exports.Security2CCKEXReport = exports.Security2CCNonceGet = exports.Security2CCNonceReport = exports.Security2CCMessageEncapsulation = exports.Security2CC = exports.Security2CCAPI = void 0;
11
+ const core_1 = require("@zwave-js/core");
12
+ const serial_1 = require("@zwave-js/serial");
13
+ const safe_1 = require("@zwave-js/shared/safe");
14
+ const API_1 = require("../lib/API");
15
+ const CommandClass_1 = require("../lib/CommandClass");
16
+ const Extension_1 = require("../lib/Security2/Extension");
17
+ const shared_1 = require("../lib/Security2/shared");
18
+ const _Types_1 = require("../lib/_Types");
19
+ const MultiChannelCC_1 = require("./MultiChannelCC");
20
+ function securityClassToBitMask(key) {
21
+ return (0, core_1.encodeBitMask)([key], core_1.SecurityClass.S0_Legacy, core_1.SecurityClass.S2_Unauthenticated);
22
+ }
23
+ function bitMaskToSecurityClass(buffer, offset) {
24
+ const keys = (0, core_1.parseBitMask)(buffer.slice(offset, offset + 1), core_1.SecurityClass.S2_Unauthenticated);
25
+ (0, core_1.validatePayload)(keys.length === 1);
26
+ return keys[0];
27
+ }
28
+ function getAuthenticationData(sendingNodeId, destination, homeId, commandLength, unencryptedPayload) {
29
+ const ret = Buffer.allocUnsafe(8 + unencryptedPayload.length);
30
+ ret[0] = sendingNodeId;
31
+ ret[1] = destination;
32
+ ret.writeUInt32BE(homeId, 2);
33
+ ret.writeUInt16BE(commandLength, 6);
34
+ // This includes the sequence number and all unencrypted extensions
35
+ unencryptedPayload.copy(ret, 8, 0);
36
+ return ret;
37
+ }
38
+ /** Validates that a sequence number is not a duplicate and updates the SPAN table if it is accepted */
39
+ function validateSequenceNumber(sequenceNumber) {
40
+ const peerNodeID = this.nodeId;
41
+ core_1.validatePayload.withReason("Duplicate command")(!this.host.securityManager2.isDuplicateSinglecast(peerNodeID, sequenceNumber));
42
+ // Not a duplicate, store it
43
+ this.host.securityManager2.storeSequenceNumber(peerNodeID, sequenceNumber);
44
+ }
45
+ function assertSecurity(options) {
46
+ const verb = (0, serial_1.gotDeserializationOptions)(options) ? "decoded" : "sent";
47
+ if (!this.host.ownNodeId) {
48
+ throw new core_1.ZWaveError(`Secure commands (S2) can only be ${verb} when the controller's node id is known!`, core_1.ZWaveErrorCodes.Driver_NotReady);
49
+ }
50
+ else if (!this.host.securityManager2) {
51
+ throw new core_1.ZWaveError(`Secure commands (S2) can only be ${verb} when the network keys for the applHost are set!`, core_1.ZWaveErrorCodes.Driver_NoSecurity);
52
+ }
53
+ }
54
+ const DECRYPT_ATTEMPTS = 5;
55
+ // @noValidateArgs - Encapsulation CCs are used internally and too frequently that we
56
+ // want to pay the cost of validating each call
57
+ let Security2CCAPI = class Security2CCAPI extends API_1.CCAPI {
58
+ supportsCommand(_cmd) {
59
+ // All commands are mandatory
60
+ return true;
61
+ }
62
+ /**
63
+ * Sends a nonce to the node, either in response to a NonceGet request or a message that failed to decrypt. The message is sent without any retransmission etc.
64
+ * The return value indicates whether a nonce was successfully sent
65
+ */
66
+ async sendNonce() {
67
+ this.assertSupportsCommand(_Types_1.Security2Command, _Types_1.Security2Command.NonceReport);
68
+ this.assertPhysicalEndpoint(this.endpoint);
69
+ if (!this.applHost.securityManager2) {
70
+ throw new core_1.ZWaveError(`Nonces can only be sent if secure communication is set up!`, core_1.ZWaveErrorCodes.Driver_NoSecurity);
71
+ }
72
+ const receiverEI = this.applHost.securityManager2.generateNonce(this.endpoint.nodeId);
73
+ const cc = new Security2CCNonceReport(this.applHost, {
74
+ nodeId: this.endpoint.nodeId,
75
+ endpoint: this.endpoint.index,
76
+ SOS: true,
77
+ MOS: false,
78
+ receiverEI,
79
+ });
80
+ try {
81
+ await this.applHost.sendCommand(cc, {
82
+ ...this.commandOptions,
83
+ // Seems we need these options or some nodes won't accept the nonce
84
+ transmitOptions: core_1.TransmitOptions.ACK | core_1.TransmitOptions.AutoRoute,
85
+ // Only try sending a nonce once
86
+ maxSendAttempts: 1,
87
+ // Nonce requests must be handled immediately
88
+ priority: core_1.MessagePriority.Nonce,
89
+ // We don't want failures causing us to treat the node as asleep or dead
90
+ changeNodeStatusOnMissingACK: false,
91
+ // And we need to react to
92
+ });
93
+ }
94
+ catch (e) {
95
+ if ((0, core_1.isTransmissionError)(e)) {
96
+ // The nonce could not be sent, invalidate it
97
+ this.applHost.securityManager2.deleteNonce(this.endpoint.nodeId);
98
+ return false;
99
+ }
100
+ else {
101
+ // Pass other errors through
102
+ throw e;
103
+ }
104
+ }
105
+ return true;
106
+ }
107
+ /**
108
+ * Queries the securely supported commands for the current security class
109
+ * @param securityClass Can be used to overwrite the security class to use. If this doesn't match the current one, new nonces will need to be exchanged.
110
+ */
111
+ async getSupportedCommands(securityClass) {
112
+ this.assertSupportsCommand(_Types_1.Security2Command, _Types_1.Security2Command.CommandsSupportedGet);
113
+ let cc = new Security2CCCommandsSupportedGet(this.applHost, {
114
+ nodeId: this.endpoint.nodeId,
115
+ endpoint: this.endpoint.index,
116
+ });
117
+ // Security2CCCommandsSupportedGet is special because we cannot reply on the applHost to do the automatic
118
+ // encapsulation because it would use a different security class. Therefore the entire possible stack
119
+ // of encapsulation needs to be done here
120
+ if (MultiChannelCC_1.MultiChannelCC.requiresEncapsulation(cc)) {
121
+ cc = MultiChannelCC_1.MultiChannelCC.encapsulate(this.applHost, cc);
122
+ }
123
+ cc = Security2CC.encapsulate(this.applHost, cc, securityClass);
124
+ const response = await this.applHost.sendCommand(cc, {
125
+ ...this.commandOptions,
126
+ autoEncapsulate: false,
127
+ });
128
+ return response === null || response === void 0 ? void 0 : response.supportedCCs;
129
+ }
130
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
131
+ async getKeyExchangeParameters() {
132
+ this.assertSupportsCommand(_Types_1.Security2Command, _Types_1.Security2Command.KEXGet);
133
+ const cc = new Security2CCKEXGet(this.applHost, {
134
+ nodeId: this.endpoint.nodeId,
135
+ endpoint: this.endpoint.index,
136
+ });
137
+ const response = await this.applHost.sendCommand(cc, this.commandOptions);
138
+ if (response) {
139
+ return (0, safe_1.pick)(response, [
140
+ "requestCSA",
141
+ "echo",
142
+ "supportedKEXSchemes",
143
+ "supportedECDHProfiles",
144
+ "requestedKeys",
145
+ ]);
146
+ }
147
+ }
148
+ /** Grants the joining node the given keys */
149
+ async grantKeys(params) {
150
+ this.assertSupportsCommand(_Types_1.Security2Command, _Types_1.Security2Command.KEXSet);
151
+ const cc = new Security2CCKEXSet(this.applHost, {
152
+ nodeId: this.endpoint.nodeId,
153
+ endpoint: this.endpoint.index,
154
+ ...params,
155
+ echo: false,
156
+ });
157
+ await this.applHost.sendCommand(cc, this.commandOptions);
158
+ }
159
+ /** Confirms the keys that were granted to a node */
160
+ async confirmGrantedKeys(params) {
161
+ this.assertSupportsCommand(_Types_1.Security2Command, _Types_1.Security2Command.KEXReport);
162
+ const cc = new Security2CCKEXReport(this.applHost, {
163
+ nodeId: this.endpoint.nodeId,
164
+ endpoint: this.endpoint.index,
165
+ ...params,
166
+ echo: true,
167
+ });
168
+ await this.applHost.sendCommand(cc, this.commandOptions);
169
+ }
170
+ /** Notifies the other node that the ongoing key exchange was aborted */
171
+ async abortKeyExchange(failType) {
172
+ this.assertSupportsCommand(_Types_1.Security2Command, _Types_1.Security2Command.KEXFail);
173
+ const cc = new Security2CCKEXFail(this.applHost, {
174
+ nodeId: this.endpoint.nodeId,
175
+ endpoint: this.endpoint.index,
176
+ failType,
177
+ });
178
+ await this.applHost.sendCommand(cc, this.commandOptions);
179
+ }
180
+ async sendPublicKey(publicKey) {
181
+ this.assertSupportsCommand(_Types_1.Security2Command, _Types_1.Security2Command.PublicKeyReport);
182
+ const cc = new Security2CCPublicKeyReport(this.applHost, {
183
+ nodeId: this.endpoint.nodeId,
184
+ endpoint: this.endpoint.index,
185
+ includingNode: true,
186
+ publicKey,
187
+ });
188
+ await this.applHost.sendCommand(cc, this.commandOptions);
189
+ }
190
+ async sendNetworkKey(securityClass, networkKey) {
191
+ this.assertSupportsCommand(_Types_1.Security2Command, _Types_1.Security2Command.NetworkKeyReport);
192
+ const cc = new Security2CCNetworkKeyReport(this.applHost, {
193
+ nodeId: this.endpoint.nodeId,
194
+ endpoint: this.endpoint.index,
195
+ grantedKey: securityClass,
196
+ networkKey,
197
+ });
198
+ await this.applHost.sendCommand(cc, this.commandOptions);
199
+ }
200
+ async confirmKeyVerification() {
201
+ this.assertSupportsCommand(_Types_1.Security2Command, _Types_1.Security2Command.TransferEnd);
202
+ const cc = new Security2CCTransferEnd(this.applHost, {
203
+ nodeId: this.endpoint.nodeId,
204
+ endpoint: this.endpoint.index,
205
+ keyVerified: true,
206
+ keyRequestComplete: false,
207
+ });
208
+ await this.applHost.sendCommand(cc, {
209
+ ...this.commandOptions,
210
+ // Don't wait for an ACK from the node
211
+ transmitOptions: core_1.TransmitOptions.DEFAULT & ~core_1.TransmitOptions.ACK,
212
+ });
213
+ }
214
+ };
215
+ Security2CCAPI = __decorate([
216
+ (0, CommandClass_1.API)(core_1.CommandClasses["Security 2"])
217
+ ], Security2CCAPI);
218
+ exports.Security2CCAPI = Security2CCAPI;
219
+ let Security2CC = Security2CC_1 = class Security2CC extends CommandClass_1.CommandClass {
220
+ async interview(applHost) {
221
+ var _a;
222
+ const node = this.getNode(applHost);
223
+ const endpoint = this.getEndpoint(applHost);
224
+ const api = API_1.CCAPI.create(core_1.CommandClasses["Security 2"], applHost, endpoint).withOptions({
225
+ priority: core_1.MessagePriority.NodeQuery,
226
+ });
227
+ // Only on the highest security class the reponse includes the supported commands
228
+ const secClass = node.getHighestSecurityClass();
229
+ let hasReceivedSecureCommands = false;
230
+ let possibleSecurityClasses;
231
+ if ((0, core_1.securityClassIsS2)(secClass)) {
232
+ // The highest security class is known to be S2, only query that one
233
+ possibleSecurityClasses = [secClass];
234
+ }
235
+ else if (endpoint.index === 0) {
236
+ // If the highest security class isn't known, query all possible security classes
237
+ // but only on the root device
238
+ possibleSecurityClasses = [
239
+ core_1.SecurityClass.S2_Unauthenticated,
240
+ core_1.SecurityClass.S2_Authenticated,
241
+ core_1.SecurityClass.S2_AccessControl,
242
+ ];
243
+ }
244
+ else {
245
+ // For endpoint interviews, the security class MUST be known
246
+ applHost.controllerLog.logNode(node.id, {
247
+ endpoint: endpoint.index,
248
+ message: `Cannot query securely supported commands for endpoint because the node's security class isn't known...`,
249
+ level: "error",
250
+ });
251
+ return;
252
+ }
253
+ for (const secClass of possibleSecurityClasses) {
254
+ // We might not know all assigned security classes yet, so we work our way up from low to high and try to request the supported commands.
255
+ // This way, each command is encrypted with the security class we're currently testing.
256
+ // If the node does not respond, it wasn't assigned the security class.
257
+ // If it responds with a non-empty list, we know this is the highest class it supports.
258
+ // If the list is empty, the security class is still supported.
259
+ // If we already know the class is not supported, skip it
260
+ if (node.hasSecurityClass(secClass) === false)
261
+ continue;
262
+ // If no key is configured for this security class, skip it
263
+ if (!((_a = this.host.securityManager2) === null || _a === void 0 ? void 0 : _a.hasKeysForSecurityClass(secClass))) {
264
+ applHost.controllerLog.logNode(node.id, {
265
+ endpoint: endpoint.index,
266
+ message: `Cannot query securely supported commands (${(0, safe_1.getEnumMemberName)(core_1.SecurityClass, secClass)}) - network key is not configured...`,
267
+ level: "warn",
268
+ });
269
+ continue;
270
+ }
271
+ applHost.controllerLog.logNode(node.id, {
272
+ endpoint: endpoint.index,
273
+ message: `Querying securely supported commands (${(0, safe_1.getEnumMemberName)(core_1.SecurityClass, secClass)})...`,
274
+ direction: "outbound",
275
+ });
276
+ // Query the supported commands but avoid remembering the wrong security class in case of a failure
277
+ let supportedCCs;
278
+ try {
279
+ supportedCCs = await api.getSupportedCommands(secClass);
280
+ }
281
+ catch (e) {
282
+ if ((0, core_1.isZWaveError)(e) &&
283
+ e.code === core_1.ZWaveErrorCodes.Security2CC_CannotDecode) {
284
+ // This has to be expected when we're using a non-granted security class
285
+ supportedCCs = undefined;
286
+ }
287
+ else {
288
+ throw e;
289
+ }
290
+ }
291
+ if (supportedCCs == undefined) {
292
+ if (endpoint.index === 0) {
293
+ // No supported commands found, mark the security class as not granted
294
+ node.setSecurityClass(secClass, false);
295
+ applHost.controllerLog.logNode(node.id, {
296
+ message: `The node was NOT granted the security class ${(0, safe_1.getEnumMemberName)(core_1.SecurityClass, secClass)}`,
297
+ direction: "inbound",
298
+ });
299
+ }
300
+ continue;
301
+ }
302
+ if (endpoint.index === 0) {
303
+ // Mark the security class as granted
304
+ node.setSecurityClass(secClass, true);
305
+ applHost.controllerLog.logNode(node.id, {
306
+ message: `The node was granted the security class ${(0, safe_1.getEnumMemberName)(core_1.SecurityClass, secClass)}`,
307
+ direction: "inbound",
308
+ });
309
+ }
310
+ if (!hasReceivedSecureCommands && supportedCCs.length > 0) {
311
+ hasReceivedSecureCommands = true;
312
+ const logLines = [
313
+ `received secure commands (${(0, safe_1.getEnumMemberName)(core_1.SecurityClass, secClass)})`,
314
+ "supported CCs:",
315
+ ];
316
+ for (const cc of supportedCCs) {
317
+ logLines.push(`· ${(0, core_1.getCCName)(cc)}`);
318
+ }
319
+ applHost.controllerLog.logNode(node.id, {
320
+ endpoint: endpoint.index,
321
+ message: logLines.join("\n"),
322
+ direction: "inbound",
323
+ });
324
+ // Remember which commands are supported securely
325
+ for (const cc of supportedCCs) {
326
+ endpoint.addCC(cc, {
327
+ isSupported: true,
328
+ secure: true,
329
+ });
330
+ }
331
+ }
332
+ }
333
+ // Remember that the interview is complete
334
+ this.setInterviewComplete(applHost, true);
335
+ }
336
+ /** Tests if a command should be sent secure and thus requires encapsulation */
337
+ static requiresEncapsulation(cc) {
338
+ // Everything that's not an S2 CC needs to be encapsulated if the CC is secure
339
+ if (!cc.secure)
340
+ return false;
341
+ if (!(cc instanceof Security2CC_1))
342
+ return true;
343
+ // These S2 commands need additional encapsulation
344
+ switch (cc.ccCommand) {
345
+ case _Types_1.Security2Command.CommandsSupportedGet:
346
+ case _Types_1.Security2Command.CommandsSupportedReport:
347
+ case _Types_1.Security2Command.NetworkKeyGet:
348
+ case _Types_1.Security2Command.NetworkKeyReport:
349
+ case _Types_1.Security2Command.NetworkKeyVerify:
350
+ case _Types_1.Security2Command.TransferEnd:
351
+ return true;
352
+ case _Types_1.Security2Command.KEXSet:
353
+ case _Types_1.Security2Command.KEXReport:
354
+ // KEXSet/Report need to be encrypted for the confirmation only
355
+ return cc.echo;
356
+ case _Types_1.Security2Command.KEXFail: {
357
+ switch (cc.failType) {
358
+ case shared_1.KEXFailType.Decrypt:
359
+ case shared_1.KEXFailType.WrongSecurityLevel:
360
+ case shared_1.KEXFailType.KeyNotGranted:
361
+ case shared_1.KEXFailType.NoVerify:
362
+ return true;
363
+ default:
364
+ return false;
365
+ }
366
+ }
367
+ }
368
+ return false;
369
+ }
370
+ /** Encapsulates a command that should be sent encrypted */
371
+ static encapsulate(host, cc, securityClass) {
372
+ return new Security2CCMessageEncapsulation(host, {
373
+ nodeId: cc.nodeId,
374
+ encapsulated: cc,
375
+ securityClass,
376
+ });
377
+ }
378
+ };
379
+ Security2CC = Security2CC_1 = __decorate([
380
+ (0, CommandClass_1.commandClass)(core_1.CommandClasses["Security 2"]),
381
+ (0, CommandClass_1.implementedVersion)(1)
382
+ ], Security2CC);
383
+ exports.Security2CC = Security2CC;
384
+ // An S2 encapsulated command may result in a NonceReport to be sent by the node if it couldn't decrypt the message
385
+ function getCCResponseForMessageEncapsulation(sent) {
386
+ var _a;
387
+ if ((_a = sent.encapsulated) === null || _a === void 0 ? void 0 : _a.expectsCCResponse()) {
388
+ return [
389
+ Security2CCMessageEncapsulation,
390
+ Security2CCNonceReport,
391
+ ];
392
+ }
393
+ }
394
+ function testCCResponseForMessageEncapsulation(sent, received) {
395
+ if (received instanceof Security2CCMessageEncapsulation) {
396
+ return "checkEncapsulated";
397
+ }
398
+ else {
399
+ return received.SOS && !!received.receiverEI;
400
+ }
401
+ }
402
+ let Security2CCMessageEncapsulation = class Security2CCMessageEncapsulation extends Security2CC {
403
+ constructor(host, options) {
404
+ var _a;
405
+ super(host, options);
406
+ // Make sure that we can send/receive secure commands
407
+ assertSecurity.call(this, options);
408
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
409
+ (0, core_1.validatePayload)(this.payload.length >= 2);
410
+ // Check the sequence number to avoid duplicates
411
+ // TODO: distinguish between multicast and singlecast
412
+ this._sequenceNumber = this.payload[0];
413
+ // Don't accept duplicate commands
414
+ validateSequenceNumber.call(this, this._sequenceNumber);
415
+ // Ensure the node has a security class
416
+ const peerNodeID = this.nodeId;
417
+ // const node = this.getNode()!;
418
+ // validatePayload.withReason("The node is not included")(!!node);
419
+ const securityClass = this.host.getHighestSecurityClass(peerNodeID);
420
+ core_1.validatePayload.withReason("No security class granted")(securityClass !== core_1.SecurityClass.None);
421
+ const hasExtensions = !!(this.payload[1] & 0b1);
422
+ const hasEncryptedExtensions = !!(this.payload[1] & 0b10);
423
+ let offset = 2;
424
+ this.extensions = [];
425
+ const parseExtensions = (buffer) => {
426
+ while (true) {
427
+ // we need to read at least the length byte
428
+ (0, core_1.validatePayload)(buffer.length >= offset + 1);
429
+ const extensionLength = Extension_1.Security2Extension.getExtensionLength(buffer.slice(offset));
430
+ // Parse the extension
431
+ const ext = Extension_1.Security2Extension.from(buffer.slice(offset, offset + extensionLength));
432
+ this.extensions.push(ext);
433
+ offset += extensionLength;
434
+ // Check if that was the last extension
435
+ if (!ext.moreToFollow)
436
+ break;
437
+ }
438
+ };
439
+ if (hasExtensions)
440
+ parseExtensions(this.payload);
441
+ const unencryptedPayload = this.payload.slice(0, offset);
442
+ const ciphertext = this.payload.slice(offset, -core_1.SECURITY_S2_AUTH_TAG_LENGTH);
443
+ const authTag = this.payload.slice(-core_1.SECURITY_S2_AUTH_TAG_LENGTH);
444
+ const messageLength = super.computeEncapsulationOverhead() + this.payload.length;
445
+ const authData = getAuthenticationData(this.nodeId, this.getDestinationIDRX(), this.host.homeId, messageLength, unencryptedPayload);
446
+ // Decrypt payload and verify integrity
447
+ const spanState = this.host.securityManager2.getSPANState(peerNodeID);
448
+ const failNoSPAN = () => {
449
+ return core_1.validatePayload.fail(core_1.ZWaveErrorCodes.Security2CC_NoSPAN);
450
+ };
451
+ // If we are not able to establish an SPAN yet, fail the decryption
452
+ if (spanState.type === core_1.SPANState.None) {
453
+ return failNoSPAN();
454
+ }
455
+ else if (spanState.type === core_1.SPANState.RemoteEI) {
456
+ // TODO: The specs are not clear how to handle this case
457
+ // For now, do the same as if we didn't have any EI
458
+ return failNoSPAN();
459
+ }
460
+ const decrypt = () => {
461
+ const getNonceAndDecrypt = () => {
462
+ const iv = this.host.securityManager2.nextNonce(peerNodeID);
463
+ const { keyCCM: key } = this.host.securityManager2.getKeysForNode(peerNodeID);
464
+ return {
465
+ decryptionKey: key,
466
+ ...(0, core_1.decryptAES128CCM)(key, iv, ciphertext, authData, authTag),
467
+ };
468
+ };
469
+ if (spanState.type === core_1.SPANState.SPAN) {
470
+ // This can only happen if the security class is known
471
+ return getNonceAndDecrypt();
472
+ }
473
+ else if (spanState.type === core_1.SPANState.LocalEI) {
474
+ // We've sent the other our receiver's EI and received its sender's EI,
475
+ // meaning we can now establish an SPAN
476
+ const senderEI = this.getSenderEI();
477
+ if (!senderEI)
478
+ return failNoSPAN();
479
+ const receiverEI = spanState.receiverEI;
480
+ // How we do this depends on whether we know the security class of the other node
481
+ if (this.host.securityManager2.tempKeys.has(peerNodeID)) {
482
+ // We're currently bootstrapping the node, it might be using a temporary key
483
+ this.host.securityManager2.initializeTempSPAN(peerNodeID, senderEI, receiverEI);
484
+ const ret = getNonceAndDecrypt();
485
+ // Decryption with the temporary key worked
486
+ if (ret.authOK)
487
+ return ret;
488
+ // Reset the SPAN state and try with the recently granted security class
489
+ this.host.securityManager2.setSPANState(peerNodeID, spanState);
490
+ }
491
+ if (securityClass != undefined) {
492
+ this.host.securityManager2.initializeSPAN(peerNodeID, securityClass, senderEI, receiverEI);
493
+ return getNonceAndDecrypt();
494
+ }
495
+ else {
496
+ // Not knowing it can happen if we just took over an existing network
497
+ // Try multiple security classes
498
+ const possibleSecurityClasses = core_1.securityClassOrder
499
+ .filter((s) => (0, core_1.securityClassIsS2)(s))
500
+ .filter((s) => this.host.hasSecurityClass(peerNodeID, s) !== false);
501
+ for (const secClass of possibleSecurityClasses) {
502
+ // Initialize an SPAN with that security class
503
+ this.host.securityManager2.initializeSPAN(peerNodeID, secClass, senderEI, receiverEI);
504
+ const ret = getNonceAndDecrypt();
505
+ // It worked, return the result and remember the security class
506
+ if (ret.authOK) {
507
+ this.host.setSecurityClass(peerNodeID, secClass, true);
508
+ return ret;
509
+ }
510
+ // Reset the SPAN state and try with the next security class
511
+ this.host.securityManager2.setSPANState(peerNodeID, spanState);
512
+ }
513
+ }
514
+ }
515
+ // Nothing worked, fail the decryption
516
+ return { plaintext: Buffer.from([]), authOK: false };
517
+ };
518
+ let plaintext;
519
+ let authOK = false;
520
+ let decryptionKey;
521
+ // If the Receiver is unable to authenticate the singlecast message with the current SPAN,
522
+ // the Receiver SHOULD try decrypting the message with one or more of the following SPAN values,
523
+ // stopping when decryption is successful or the maximum number of iterations is reached.
524
+ for (let i = 0; i < DECRYPT_ATTEMPTS; i++) {
525
+ ({ plaintext, authOK, decryptionKey } = decrypt());
526
+ if (!!authOK && !!plaintext)
527
+ break;
528
+ }
529
+ // If authentication fails, do so with an error code that instructs the
530
+ // applHost to tell the node we have no nonce
531
+ if (!authOK || !plaintext) {
532
+ return core_1.validatePayload.fail(core_1.ZWaveErrorCodes.Security2CC_CannotDecode);
533
+ }
534
+ offset = 0;
535
+ if (hasEncryptedExtensions)
536
+ parseExtensions(plaintext);
537
+ // Not every S2 message includes an encapsulated CC
538
+ const decryptedCCBytes = plaintext.slice(offset);
539
+ if (decryptedCCBytes.length > 0) {
540
+ // make sure this contains a complete CC command that's worth splitting
541
+ (0, core_1.validatePayload)(decryptedCCBytes.length >= 2);
542
+ // and deserialize the CC
543
+ this.encapsulated = CommandClass_1.CommandClass.from(this.host, {
544
+ data: decryptedCCBytes,
545
+ fromEncapsulation: true,
546
+ encapCC: this,
547
+ });
548
+ }
549
+ this.decryptionKey = decryptionKey;
550
+ }
551
+ else {
552
+ this._securityClass = options.securityClass;
553
+ this.encapsulated = options.encapsulated;
554
+ options.encapsulated.encapsulatingCC = this;
555
+ this.extensions = (_a = options.extensions) !== null && _a !== void 0 ? _a : [];
556
+ if (typeof this.nodeId !== "number" &&
557
+ !this.extensions.some((e) => e instanceof Extension_1.MGRPExtension)) {
558
+ throw new core_1.ZWaveError("Multicast Security S2 encapsulation requires the MGRP extension", core_1.ZWaveErrorCodes.Security2CC_MissingExtension);
559
+ }
560
+ }
561
+ }
562
+ /**
563
+ * Return the sequence number of this command.
564
+ *
565
+ * **WARNING:** If the sequence number hasn't been set before, this will create a new one.
566
+ * When sending messages, this should only happen immediately before serializing.
567
+ */
568
+ get sequenceNumber() {
569
+ if (this._sequenceNumber == undefined) {
570
+ this._sequenceNumber =
571
+ this.host.securityManager2.nextSequenceNumber(this.nodeId);
572
+ }
573
+ return this._sequenceNumber;
574
+ }
575
+ unsetSequenceNumber() {
576
+ this._sequenceNumber = undefined;
577
+ }
578
+ getDestinationIDTX() {
579
+ const mgrpExtension = this.extensions.find((e) => e instanceof Extension_1.MGRPExtension);
580
+ if (mgrpExtension)
581
+ return mgrpExtension.groupId;
582
+ else if (typeof this.nodeId === "number")
583
+ return this.nodeId;
584
+ throw new core_1.ZWaveError("Multicast Security S2 encapsulation requires the MGRP extension", core_1.ZWaveErrorCodes.Security2CC_MissingExtension);
585
+ }
586
+ getDestinationIDRX() {
587
+ const mgrpExtension = this.extensions.find((e) => e instanceof Extension_1.MGRPExtension);
588
+ if (mgrpExtension)
589
+ return mgrpExtension.groupId;
590
+ return this.host.ownNodeId;
591
+ }
592
+ /** Returns the Sender's Entropy Input if this command contains an SPAN extension */
593
+ getSenderEI() {
594
+ const spanExtension = this.extensions.find((e) => e instanceof Extension_1.SPANExtension);
595
+ return spanExtension === null || spanExtension === void 0 ? void 0 : spanExtension.senderEI;
596
+ }
597
+ serialize() {
598
+ var _a, _b, _c;
599
+ // TODO: Support Multicast
600
+ const nodeId = this.nodeId;
601
+ // Include Sender EI in the command if we only have the receiver's EI
602
+ const spanState = this.host.securityManager2.getSPANState(nodeId);
603
+ if (spanState.type === core_1.SPANState.None ||
604
+ spanState.type === core_1.SPANState.LocalEI) {
605
+ // Can't do anything here if we don't have the receiver's EI
606
+ throw new core_1.ZWaveError(`Security S2 CC requires the receiver's nonce to be sent!`, core_1.ZWaveErrorCodes.Security2CC_NoSPAN);
607
+ }
608
+ else if (spanState.type === core_1.SPANState.RemoteEI) {
609
+ // We have the receiver's EI, generate our input and send it over
610
+ // With both, we can create an SPAN
611
+ const senderEI = this.host.securityManager2.generateNonce(undefined);
612
+ const receiverEI = spanState.receiverEI;
613
+ // While bootstrapping a node, the controller only sends commands encrypted
614
+ // with the temporary key
615
+ if (this.host.securityManager2.tempKeys.has(nodeId)) {
616
+ this.host.securityManager2.initializeTempSPAN(nodeId, senderEI, receiverEI);
617
+ }
618
+ else {
619
+ const securityClass = (_a = this._securityClass) !== null && _a !== void 0 ? _a : this.host.getHighestSecurityClass(nodeId);
620
+ if (securityClass == undefined) {
621
+ throw new core_1.ZWaveError("No security class defined for this command!", core_1.ZWaveErrorCodes.Security2CC_NoSPAN);
622
+ }
623
+ this.host.securityManager2.initializeSPAN(nodeId, securityClass, senderEI, receiverEI);
624
+ }
625
+ // Add or update the SPAN extension
626
+ let spanExtension = this.extensions.find((e) => e instanceof Extension_1.SPANExtension);
627
+ if (spanExtension) {
628
+ spanExtension.senderEI = senderEI;
629
+ }
630
+ else {
631
+ spanExtension = new Extension_1.SPANExtension({ senderEI });
632
+ this.extensions.push(spanExtension);
633
+ }
634
+ }
635
+ const unencryptedExtensions = this.extensions.filter((e) => !e.isEncrypted());
636
+ const encryptedExtensions = this.extensions.filter((e) => e.isEncrypted());
637
+ const unencryptedPayload = Buffer.concat([
638
+ Buffer.from([
639
+ this.sequenceNumber,
640
+ (encryptedExtensions.length > 0 ? 0b10 : 0) |
641
+ (unencryptedExtensions.length > 0 ? 1 : 0),
642
+ ]),
643
+ ...unencryptedExtensions.map((e, index) => e.serialize(index < unencryptedExtensions.length - 1)),
644
+ ]);
645
+ const serializedCC = (_c = (_b = this.encapsulated) === null || _b === void 0 ? void 0 : _b.serialize()) !== null && _c !== void 0 ? _c : Buffer.from([]);
646
+ const plaintextPayload = Buffer.concat([
647
+ ...encryptedExtensions.map((e, index) => e.serialize(index < encryptedExtensions.length - 1)),
648
+ serializedCC,
649
+ ]);
650
+ // Generate the authentication data for CCM encryption
651
+ const messageLength = this.computeEncapsulationOverhead() + serializedCC.length;
652
+ const authData = getAuthenticationData(this.host.ownNodeId, this.getDestinationIDTX(), this.host.homeId, messageLength, unencryptedPayload);
653
+ const iv = this.host.securityManager2.nextNonce(nodeId);
654
+ const { keyCCM: key } =
655
+ // Prefer the overridden security class if it was given
656
+ this._securityClass != undefined
657
+ ? this.host.securityManager2.getKeysForSecurityClass(this._securityClass)
658
+ : this.host.securityManager2.getKeysForNode(nodeId);
659
+ const { ciphertext: ciphertextPayload, authTag } = (0, core_1.encryptAES128CCM)(key, iv, plaintextPayload, authData, core_1.SECURITY_S2_AUTH_TAG_LENGTH);
660
+ this.payload = Buffer.concat([
661
+ unencryptedPayload,
662
+ ciphertextPayload,
663
+ authTag,
664
+ ]);
665
+ return super.serialize();
666
+ }
667
+ computeEncapsulationOverhead() {
668
+ // Security S2 adds:
669
+ // * 1 byte sequence number
670
+ // * 1 byte control
671
+ // * N bytes extensions
672
+ // * SECURITY_S2_AUTH_TAG_LENGTH bytes auth tag
673
+ const extensionBytes = this.extensions
674
+ .map((e) => e.computeLength())
675
+ .reduce((a, b) => a + b, 0);
676
+ return (super.computeEncapsulationOverhead() +
677
+ 2 +
678
+ core_1.SECURITY_S2_AUTH_TAG_LENGTH +
679
+ extensionBytes);
680
+ }
681
+ toLogEntry(applHost) {
682
+ const message = {
683
+ "sequence number": this.sequenceNumber,
684
+ };
685
+ if (this.extensions.length > 0) {
686
+ message.extensions = this.extensions
687
+ .map((e) => e.toLogEntry())
688
+ .join("");
689
+ }
690
+ return {
691
+ ...super.toLogEntry(applHost),
692
+ message,
693
+ };
694
+ }
695
+ };
696
+ Security2CCMessageEncapsulation = __decorate([
697
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.MessageEncapsulation),
698
+ (0, CommandClass_1.expectedCCResponse)(getCCResponseForMessageEncapsulation, testCCResponseForMessageEncapsulation)
699
+ ], Security2CCMessageEncapsulation);
700
+ exports.Security2CCMessageEncapsulation = Security2CCMessageEncapsulation;
701
+ let Security2CCNonceReport = class Security2CCNonceReport extends Security2CC {
702
+ constructor(host, options) {
703
+ super(host, options);
704
+ // Make sure that we can send/receive secure commands
705
+ assertSecurity.call(this, options);
706
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
707
+ (0, core_1.validatePayload)(this.payload.length >= 2);
708
+ this._sequenceNumber = this.payload[0];
709
+ // Don't accept duplicate commands
710
+ validateSequenceNumber.call(this, this._sequenceNumber);
711
+ this.MOS = !!(this.payload[1] & 0b10);
712
+ this.SOS = !!(this.payload[1] & 0b1);
713
+ (0, core_1.validatePayload)(this.MOS || this.SOS);
714
+ if (this.SOS) {
715
+ // If the SOS flag is set, the REI field MUST be included in the command
716
+ (0, core_1.validatePayload)(this.payload.length >= 18);
717
+ this.receiverEI = this.payload.slice(2, 18);
718
+ // In that case we also need to store it, so the next sent command
719
+ // can use it for encryption
720
+ this.host.securityManager2.storeRemoteEI(this.nodeId, this.receiverEI);
721
+ }
722
+ }
723
+ else {
724
+ this.SOS = options.SOS;
725
+ this.MOS = options.MOS;
726
+ if (options.SOS)
727
+ this.receiverEI = options.receiverEI;
728
+ }
729
+ }
730
+ /**
731
+ * Return the sequence number of this command.
732
+ *
733
+ * **WARNING:** If the sequence number hasn't been set before, this will create a new one.
734
+ * When sending messages, this should only happen immediately before serializing.
735
+ */
736
+ get sequenceNumber() {
737
+ if (this._sequenceNumber == undefined) {
738
+ this._sequenceNumber =
739
+ this.host.securityManager2.nextSequenceNumber(this.nodeId);
740
+ }
741
+ return this._sequenceNumber;
742
+ }
743
+ serialize() {
744
+ this.payload = Buffer.from([
745
+ this.sequenceNumber,
746
+ (this.MOS ? 0b10 : 0) + (this.SOS ? 0b1 : 0),
747
+ ]);
748
+ if (this.SOS) {
749
+ this.payload = Buffer.concat([this.payload, this.receiverEI]);
750
+ }
751
+ return super.serialize();
752
+ }
753
+ toLogEntry(applHost) {
754
+ const message = {
755
+ "sequence number": this.sequenceNumber,
756
+ SOS: this.SOS,
757
+ MOS: this.MOS,
758
+ };
759
+ if (this.receiverEI) {
760
+ message["receiver entropy"] = (0, safe_1.buffer2hex)(this.receiverEI);
761
+ }
762
+ return {
763
+ ...super.toLogEntry(applHost),
764
+ message,
765
+ };
766
+ }
767
+ };
768
+ Security2CCNonceReport = __decorate([
769
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.NonceReport)
770
+ ], Security2CCNonceReport);
771
+ exports.Security2CCNonceReport = Security2CCNonceReport;
772
+ let Security2CCNonceGet = class Security2CCNonceGet extends Security2CC {
773
+ constructor(host, options) {
774
+ super(host, options);
775
+ // Make sure that we can send/receive secure commands
776
+ assertSecurity.call(this, options);
777
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
778
+ (0, core_1.validatePayload)(this.payload.length >= 1);
779
+ this._sequenceNumber = this.payload[0];
780
+ // Don't accept duplicate commands
781
+ validateSequenceNumber.call(this, this._sequenceNumber);
782
+ }
783
+ else {
784
+ // No options here
785
+ }
786
+ }
787
+ /**
788
+ * Return the sequence number of this command.
789
+ *
790
+ * **WARNING:** If the sequence number hasn't been set before, this will create a new one.
791
+ * When sending messages, this should only happen immediately before serializing.
792
+ */
793
+ get sequenceNumber() {
794
+ if (this._sequenceNumber == undefined) {
795
+ this._sequenceNumber =
796
+ this.host.securityManager2.nextSequenceNumber(this.nodeId);
797
+ }
798
+ return this._sequenceNumber;
799
+ }
800
+ serialize() {
801
+ this.payload = Buffer.from([this.sequenceNumber]);
802
+ return super.serialize();
803
+ }
804
+ toLogEntry(applHost) {
805
+ return {
806
+ ...super.toLogEntry(applHost),
807
+ message: { "sequence number": this.sequenceNumber },
808
+ };
809
+ }
810
+ };
811
+ Security2CCNonceGet = __decorate([
812
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.NonceGet),
813
+ (0, CommandClass_1.expectedCCResponse)(Security2CCNonceReport)
814
+ ], Security2CCNonceGet);
815
+ exports.Security2CCNonceGet = Security2CCNonceGet;
816
+ let Security2CCKEXReport = class Security2CCKEXReport extends Security2CC {
817
+ constructor(host, options) {
818
+ super(host, options);
819
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
820
+ (0, core_1.validatePayload)(this.payload.length >= 4);
821
+ this.requestCSA = !!(this.payload[0] & 0b10);
822
+ this.echo = !!(this.payload[0] & 0b1);
823
+ // The bit mask starts at 0, but bit 0 is not used
824
+ this.supportedKEXSchemes = (0, core_1.parseBitMask)(this.payload.slice(1, 2), 0).filter((s) => s !== 0);
825
+ this.supportedECDHProfiles = (0, core_1.parseBitMask)(this.payload.slice(2, 3), shared_1.ECDHProfiles.Curve25519);
826
+ this.requestedKeys = (0, core_1.parseBitMask)(this.payload.slice(3, 4), core_1.SecurityClass.S2_Unauthenticated);
827
+ }
828
+ else {
829
+ this.requestCSA = options.requestCSA;
830
+ this.echo = options.echo;
831
+ this.supportedKEXSchemes = options.supportedKEXSchemes;
832
+ this.supportedECDHProfiles = options.supportedECDHProfiles;
833
+ this.requestedKeys = options.requestedKeys;
834
+ }
835
+ }
836
+ serialize() {
837
+ this.payload = Buffer.concat([
838
+ Buffer.from([(this.requestCSA ? 0b10 : 0) + (this.echo ? 0b1 : 0)]),
839
+ // The bit mask starts at 0, but bit 0 is not used
840
+ (0, core_1.encodeBitMask)(this.supportedKEXSchemes, 7, 0),
841
+ (0, core_1.encodeBitMask)(this.supportedECDHProfiles, 7, shared_1.ECDHProfiles.Curve25519),
842
+ (0, core_1.encodeBitMask)(this.requestedKeys, core_1.SecurityClass.S0_Legacy, core_1.SecurityClass.S2_Unauthenticated),
843
+ ]);
844
+ return super.serialize();
845
+ }
846
+ toLogEntry(applHost) {
847
+ return {
848
+ ...super.toLogEntry(applHost),
849
+ message: {
850
+ echo: this.echo,
851
+ "supported schemes": this.supportedKEXSchemes
852
+ .map((s) => `\n· ${(0, safe_1.getEnumMemberName)(shared_1.KEXSchemes, s)}`)
853
+ .join(""),
854
+ "supported ECDH profiles": this.supportedECDHProfiles
855
+ .map((s) => `\n· ${(0, safe_1.getEnumMemberName)(shared_1.ECDHProfiles, s)}`)
856
+ .join(""),
857
+ "CSA requested": this.requestCSA,
858
+ "requested security classes": this.requestedKeys
859
+ .map((s) => `\n· ${(0, safe_1.getEnumMemberName)(core_1.SecurityClass, s)}`)
860
+ .join(""),
861
+ },
862
+ };
863
+ }
864
+ };
865
+ Security2CCKEXReport = __decorate([
866
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.KEXReport)
867
+ ], Security2CCKEXReport);
868
+ exports.Security2CCKEXReport = Security2CCKEXReport;
869
+ let Security2CCKEXGet = class Security2CCKEXGet extends Security2CC {
870
+ };
871
+ Security2CCKEXGet = __decorate([
872
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.KEXGet),
873
+ (0, CommandClass_1.expectedCCResponse)(Security2CCKEXReport)
874
+ ], Security2CCKEXGet);
875
+ exports.Security2CCKEXGet = Security2CCKEXGet;
876
+ let Security2CCKEXSet = class Security2CCKEXSet extends Security2CC {
877
+ constructor(host, options) {
878
+ super(host, options);
879
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
880
+ (0, core_1.validatePayload)(this.payload.length >= 4);
881
+ this.permitCSA = !!(this.payload[0] & 0b10);
882
+ this.echo = !!(this.payload[0] & 0b1);
883
+ // The bit mask starts at 0, but bit 0 is not used
884
+ const selectedKEXSchemes = (0, core_1.parseBitMask)(this.payload.slice(1, 2), 0).filter((s) => s !== 0);
885
+ (0, core_1.validatePayload)(selectedKEXSchemes.length === 1);
886
+ this.selectedKEXScheme = selectedKEXSchemes[0];
887
+ const selectedECDHProfiles = (0, core_1.parseBitMask)(this.payload.slice(2, 3), shared_1.ECDHProfiles.Curve25519);
888
+ (0, core_1.validatePayload)(selectedECDHProfiles.length === 1);
889
+ this.selectedECDHProfile = selectedECDHProfiles[0];
890
+ this.grantedKeys = (0, core_1.parseBitMask)(this.payload.slice(3, 4), core_1.SecurityClass.S2_Unauthenticated);
891
+ }
892
+ else {
893
+ this.permitCSA = options.permitCSA;
894
+ this.echo = options.echo;
895
+ this.selectedKEXScheme = options.selectedKEXScheme;
896
+ this.selectedECDHProfile = options.selectedECDHProfile;
897
+ this.grantedKeys = options.grantedKeys;
898
+ }
899
+ }
900
+ serialize() {
901
+ this.payload = Buffer.concat([
902
+ Buffer.from([(this.permitCSA ? 0b10 : 0) + (this.echo ? 0b1 : 0)]),
903
+ // The bit mask starts at 0, but bit 0 is not used
904
+ (0, core_1.encodeBitMask)([this.selectedKEXScheme], 7, 0),
905
+ (0, core_1.encodeBitMask)([this.selectedECDHProfile], 7, shared_1.ECDHProfiles.Curve25519),
906
+ (0, core_1.encodeBitMask)(this.grantedKeys, core_1.SecurityClass.S0_Legacy, core_1.SecurityClass.S2_Unauthenticated),
907
+ ]);
908
+ return super.serialize();
909
+ }
910
+ toLogEntry(applHost) {
911
+ return {
912
+ ...super.toLogEntry(applHost),
913
+ message: {
914
+ echo: this.echo,
915
+ "selected scheme": (0, safe_1.getEnumMemberName)(shared_1.KEXSchemes, this.selectedKEXScheme),
916
+ "selected ECDH profile": (0, safe_1.getEnumMemberName)(shared_1.ECDHProfiles, this.selectedECDHProfile),
917
+ "CSA permitted": this.permitCSA,
918
+ "granted security classes": this.grantedKeys
919
+ .map((s) => `\n· ${(0, safe_1.getEnumMemberName)(core_1.SecurityClass, s)}`)
920
+ .join(""),
921
+ },
922
+ };
923
+ }
924
+ };
925
+ Security2CCKEXSet = __decorate([
926
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.KEXSet)
927
+ ], Security2CCKEXSet);
928
+ exports.Security2CCKEXSet = Security2CCKEXSet;
929
+ let Security2CCKEXFail = class Security2CCKEXFail extends Security2CC {
930
+ constructor(host, options) {
931
+ super(host, options);
932
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
933
+ (0, core_1.validatePayload)(this.payload.length >= 1);
934
+ this.failType = this.payload[0];
935
+ }
936
+ else {
937
+ this.failType = options.failType;
938
+ }
939
+ }
940
+ serialize() {
941
+ this.payload = Buffer.from([this.failType]);
942
+ return super.serialize();
943
+ }
944
+ toLogEntry(applHost) {
945
+ return {
946
+ ...super.toLogEntry(applHost),
947
+ message: { reason: (0, safe_1.getEnumMemberName)(shared_1.KEXFailType, this.failType) },
948
+ };
949
+ }
950
+ };
951
+ Security2CCKEXFail = __decorate([
952
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.KEXFail)
953
+ ], Security2CCKEXFail);
954
+ exports.Security2CCKEXFail = Security2CCKEXFail;
955
+ let Security2CCPublicKeyReport = class Security2CCPublicKeyReport extends Security2CC {
956
+ constructor(host, options) {
957
+ super(host, options);
958
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
959
+ (0, core_1.validatePayload)(this.payload.length >= 17);
960
+ this.includingNode = !!(this.payload[0] & 0b1);
961
+ this.publicKey = this.payload.slice(1);
962
+ }
963
+ else {
964
+ this.includingNode = options.includingNode;
965
+ this.publicKey = options.publicKey;
966
+ }
967
+ }
968
+ serialize() {
969
+ this.payload = Buffer.concat([
970
+ Buffer.from([this.includingNode ? 1 : 0]),
971
+ this.publicKey,
972
+ ]);
973
+ return super.serialize();
974
+ }
975
+ toLogEntry(applHost) {
976
+ return {
977
+ ...super.toLogEntry(applHost),
978
+ message: {
979
+ "is including node": this.includingNode,
980
+ "public key": (0, safe_1.buffer2hex)(this.publicKey),
981
+ },
982
+ };
983
+ }
984
+ };
985
+ Security2CCPublicKeyReport = __decorate([
986
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.PublicKeyReport)
987
+ ], Security2CCPublicKeyReport);
988
+ exports.Security2CCPublicKeyReport = Security2CCPublicKeyReport;
989
+ let Security2CCNetworkKeyReport = class Security2CCNetworkKeyReport extends Security2CC {
990
+ constructor(host, options) {
991
+ super(host, options);
992
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
993
+ // TODO: Deserialize payload
994
+ throw new core_1.ZWaveError(`${this.constructor.name}: deserialization not implemented`, core_1.ZWaveErrorCodes.Deserialization_NotImplemented);
995
+ }
996
+ else {
997
+ this.grantedKey = options.grantedKey;
998
+ this.networkKey = options.networkKey;
999
+ }
1000
+ }
1001
+ serialize() {
1002
+ this.payload = Buffer.concat([
1003
+ securityClassToBitMask(this.grantedKey),
1004
+ this.networkKey,
1005
+ ]);
1006
+ return super.serialize();
1007
+ }
1008
+ toLogEntry(applHost) {
1009
+ return {
1010
+ ...super.toLogEntry(applHost),
1011
+ message: {
1012
+ "security class": (0, safe_1.getEnumMemberName)(core_1.SecurityClass, this.grantedKey),
1013
+ // This shouldn't be logged, so users can safely post their logs online
1014
+ // "network key": buffer2hex(this.networkKey),
1015
+ },
1016
+ };
1017
+ }
1018
+ };
1019
+ Security2CCNetworkKeyReport = __decorate([
1020
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.NetworkKeyReport)
1021
+ ], Security2CCNetworkKeyReport);
1022
+ exports.Security2CCNetworkKeyReport = Security2CCNetworkKeyReport;
1023
+ let Security2CCNetworkKeyGet = class Security2CCNetworkKeyGet extends Security2CC {
1024
+ constructor(host, options) {
1025
+ super(host, options);
1026
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
1027
+ (0, core_1.validatePayload)(this.payload.length >= 1);
1028
+ this.requestedKey = bitMaskToSecurityClass(this.payload, 0);
1029
+ }
1030
+ else {
1031
+ this.requestedKey = options.requestedKey;
1032
+ }
1033
+ }
1034
+ serialize() {
1035
+ this.payload = securityClassToBitMask(this.requestedKey);
1036
+ return super.serialize();
1037
+ }
1038
+ toLogEntry(applHost) {
1039
+ return {
1040
+ ...super.toLogEntry(applHost),
1041
+ message: {
1042
+ "security class": (0, safe_1.getEnumMemberName)(core_1.SecurityClass, this.requestedKey),
1043
+ },
1044
+ };
1045
+ }
1046
+ };
1047
+ Security2CCNetworkKeyGet = __decorate([
1048
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.NetworkKeyGet),
1049
+ (0, CommandClass_1.expectedCCResponse)(Security2CCNetworkKeyReport)
1050
+ ], Security2CCNetworkKeyGet);
1051
+ exports.Security2CCNetworkKeyGet = Security2CCNetworkKeyGet;
1052
+ let Security2CCNetworkKeyVerify = class Security2CCNetworkKeyVerify extends Security2CC {
1053
+ };
1054
+ Security2CCNetworkKeyVerify = __decorate([
1055
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.NetworkKeyVerify)
1056
+ ], Security2CCNetworkKeyVerify);
1057
+ exports.Security2CCNetworkKeyVerify = Security2CCNetworkKeyVerify;
1058
+ let Security2CCTransferEnd = class Security2CCTransferEnd extends Security2CC {
1059
+ constructor(host, options) {
1060
+ super(host, options);
1061
+ if ((0, serial_1.gotDeserializationOptions)(options)) {
1062
+ (0, core_1.validatePayload)(this.payload.length >= 1);
1063
+ this.keyVerified = !!(this.payload[0] & 0b10);
1064
+ this.keyRequestComplete = !!(this.payload[0] & 0b1);
1065
+ }
1066
+ else {
1067
+ this.keyVerified = options.keyVerified;
1068
+ this.keyRequestComplete = options.keyRequestComplete;
1069
+ }
1070
+ }
1071
+ serialize() {
1072
+ this.payload = Buffer.from([
1073
+ (this.keyVerified ? 0b10 : 0) + (this.keyRequestComplete ? 0b1 : 0),
1074
+ ]);
1075
+ return super.serialize();
1076
+ }
1077
+ toLogEntry(applHost) {
1078
+ return {
1079
+ ...super.toLogEntry(applHost),
1080
+ message: {
1081
+ "key verified": this.keyVerified,
1082
+ "request complete": this.keyRequestComplete,
1083
+ },
1084
+ };
1085
+ }
1086
+ };
1087
+ Security2CCTransferEnd = __decorate([
1088
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.TransferEnd)
1089
+ ], Security2CCTransferEnd);
1090
+ exports.Security2CCTransferEnd = Security2CCTransferEnd;
1091
+ let Security2CCCommandsSupportedReport = class Security2CCCommandsSupportedReport extends Security2CC {
1092
+ constructor(host, options) {
1093
+ super(host, options);
1094
+ const CCs = (0, core_1.parseCCList)(this.payload);
1095
+ // SDS13783: A sending node MAY terminate the list of supported command classes with the
1096
+ // COMMAND_CLASS_MARK command class identifier.
1097
+ // A receiving node MUST stop parsing the list of supported command classes if it detects the
1098
+ // COMMAND_CLASS_MARK command class identifier in the Security 2 Commands Supported Report
1099
+ this.supportedCCs = CCs.supportedCCs;
1100
+ }
1101
+ toLogEntry(applHost) {
1102
+ return {
1103
+ ...super.toLogEntry(applHost),
1104
+ message: {
1105
+ supportedCCs: this.supportedCCs
1106
+ .map((cc) => (0, core_1.getCCName)(cc))
1107
+ .map((cc) => `\n· ${cc}`)
1108
+ .join(""),
1109
+ },
1110
+ };
1111
+ }
1112
+ };
1113
+ Security2CCCommandsSupportedReport = __decorate([
1114
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.CommandsSupportedReport)
1115
+ ], Security2CCCommandsSupportedReport);
1116
+ exports.Security2CCCommandsSupportedReport = Security2CCCommandsSupportedReport;
1117
+ let Security2CCCommandsSupportedGet = class Security2CCCommandsSupportedGet extends Security2CC {
1118
+ };
1119
+ Security2CCCommandsSupportedGet = __decorate([
1120
+ (0, CommandClass_1.CCCommand)(_Types_1.Security2Command.CommandsSupportedGet),
1121
+ (0, CommandClass_1.expectedCCResponse)(Security2CCCommandsSupportedReport)
1122
+ ], Security2CCCommandsSupportedGet);
1123
+ exports.Security2CCCommandsSupportedGet = Security2CCCommandsSupportedGet;
1124
+ //# sourceMappingURL=Security2CC.js.map