zigbee-herdsman-converters 20.44.0 → 21.0.0-pre.1

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 (349) hide show
  1. package/converters/fromZigbee.d.ts +4 -6
  2. package/converters/fromZigbee.d.ts.map +1 -1
  3. package/converters/fromZigbee.js +3 -32
  4. package/converters/fromZigbee.js.map +1 -1
  5. package/converters/toZigbee.d.ts +1 -49
  6. package/converters/toZigbee.d.ts.map +1 -1
  7. package/converters/toZigbee.js +38 -46
  8. package/converters/toZigbee.js.map +1 -1
  9. package/devices/adeo.d.ts.map +1 -1
  10. package/devices/adeo.js +1 -2
  11. package/devices/adeo.js.map +1 -1
  12. package/devices/adurosmart.d.ts.map +1 -1
  13. package/devices/adurosmart.js +1 -2
  14. package/devices/adurosmart.js.map +1 -1
  15. package/devices/aeotec.js +1 -1
  16. package/devices/aeotec.js.map +1 -1
  17. package/devices/airam.d.ts.map +1 -1
  18. package/devices/airam.js +1 -13
  19. package/devices/airam.js.map +1 -1
  20. package/devices/amina.d.ts.map +1 -1
  21. package/devices/amina.js +1 -2
  22. package/devices/amina.js.map +1 -1
  23. package/devices/aurora_lighting.d.ts.map +1 -1
  24. package/devices/aurora_lighting.js +2 -3
  25. package/devices/aurora_lighting.js.map +1 -1
  26. package/devices/bitron.d.ts.map +1 -1
  27. package/devices/bitron.js +1 -2
  28. package/devices/bitron.js.map +1 -1
  29. package/devices/bosch.d.ts.map +1 -1
  30. package/devices/bosch.js +10 -9
  31. package/devices/bosch.js.map +1 -1
  32. package/devices/bticino.d.ts.map +1 -1
  33. package/devices/bticino.js +2 -3
  34. package/devices/bticino.js.map +1 -1
  35. package/devices/busch_jaeger.d.ts.map +1 -1
  36. package/devices/busch_jaeger.js +1 -11
  37. package/devices/busch_jaeger.js.map +1 -1
  38. package/devices/chacon.js +1 -1
  39. package/devices/chacon.js.map +1 -1
  40. package/devices/ctm.d.ts.map +1 -1
  41. package/devices/ctm.js +5 -8
  42. package/devices/ctm.js.map +1 -1
  43. package/devices/custom_devices_diy.d.ts.map +1 -1
  44. package/devices/custom_devices_diy.js +6 -10
  45. package/devices/custom_devices_diy.js.map +1 -1
  46. package/devices/danalock.d.ts.map +1 -1
  47. package/devices/danalock.js +1 -2
  48. package/devices/danalock.js.map +1 -1
  49. package/devices/danfoss.d.ts.map +1 -1
  50. package/devices/danfoss.js +1 -2
  51. package/devices/danfoss.js.map +1 -1
  52. package/devices/datek.d.ts.map +1 -1
  53. package/devices/datek.js +2 -5
  54. package/devices/datek.js.map +1 -1
  55. package/devices/develco.d.ts.map +1 -1
  56. package/devices/develco.js +19 -20
  57. package/devices/develco.js.map +1 -1
  58. package/devices/diyruz.d.ts.map +1 -1
  59. package/devices/diyruz.js +1 -2
  60. package/devices/diyruz.js.map +1 -1
  61. package/devices/dresden_elektronik.d.ts.map +1 -1
  62. package/devices/dresden_elektronik.js +3 -27
  63. package/devices/dresden_elektronik.js.map +1 -1
  64. package/devices/ecodim.d.ts.map +1 -1
  65. package/devices/ecodim.js +1 -2
  66. package/devices/ecodim.js.map +1 -1
  67. package/devices/ecozy.d.ts.map +1 -1
  68. package/devices/ecozy.js +1 -2
  69. package/devices/ecozy.js.map +1 -1
  70. package/devices/eurotronic.d.ts.map +1 -1
  71. package/devices/eurotronic.js +1 -2
  72. package/devices/eurotronic.js.map +1 -1
  73. package/devices/fantem.d.ts.map +1 -1
  74. package/devices/fantem.js +0 -1
  75. package/devices/fantem.js.map +1 -1
  76. package/devices/frient.js +1 -1
  77. package/devices/frient.js.map +1 -1
  78. package/devices/futurehome.d.ts.map +1 -1
  79. package/devices/futurehome.js +1 -2
  80. package/devices/futurehome.js.map +1 -1
  81. package/devices/gledopto.d.ts.map +1 -1
  82. package/devices/gledopto.js +30 -31
  83. package/devices/gledopto.js.map +1 -1
  84. package/devices/gmmts.d.ts.map +1 -1
  85. package/devices/gmmts.js +1 -2
  86. package/devices/gmmts.js.map +1 -1
  87. package/devices/heiman.d.ts.map +1 -1
  88. package/devices/heiman.js +3 -4
  89. package/devices/heiman.js.map +1 -1
  90. package/devices/heimgard_technologies.d.ts.map +1 -1
  91. package/devices/heimgard_technologies.js +5 -6
  92. package/devices/heimgard_technologies.js.map +1 -1
  93. package/devices/icasa.d.ts.map +1 -1
  94. package/devices/icasa.js +2 -25
  95. package/devices/icasa.js.map +1 -1
  96. package/devices/ikea.d.ts.map +1 -1
  97. package/devices/ikea.js +37 -51
  98. package/devices/ikea.js.map +1 -1
  99. package/devices/iluminize.d.ts.map +1 -1
  100. package/devices/iluminize.js +1 -2
  101. package/devices/iluminize.js.map +1 -1
  102. package/devices/immax.d.ts.map +1 -1
  103. package/devices/immax.js +3 -4
  104. package/devices/immax.js.map +1 -1
  105. package/devices/index.d.ts +1 -0
  106. package/devices/index.d.ts.map +1 -1
  107. package/devices/innr.d.ts.map +1 -1
  108. package/devices/innr.js +34 -35
  109. package/devices/innr.js.map +1 -1
  110. package/devices/inovelli.d.ts.map +1 -1
  111. package/devices/inovelli.js +3 -11
  112. package/devices/inovelli.js.map +1 -1
  113. package/devices/insta.d.ts.map +1 -1
  114. package/devices/insta.js +3 -12
  115. package/devices/insta.js.map +1 -1
  116. package/devices/javis.js +1 -1
  117. package/devices/javis.js.map +1 -1
  118. package/devices/jethome.d.ts.map +1 -1
  119. package/devices/jethome.js +1 -2
  120. package/devices/jethome.js.map +1 -1
  121. package/devices/kmpcil.d.ts.map +1 -1
  122. package/devices/kmpcil.js +1 -10
  123. package/devices/kmpcil.js.map +1 -1
  124. package/devices/konke.d.ts.map +1 -1
  125. package/devices/konke.js +2 -3
  126. package/devices/konke.js.map +1 -1
  127. package/devices/leedarson.d.ts.map +1 -1
  128. package/devices/leedarson.js +3 -11
  129. package/devices/leedarson.js.map +1 -1
  130. package/devices/legrand.d.ts.map +1 -1
  131. package/devices/legrand.js +30 -32
  132. package/devices/legrand.js.map +1 -1
  133. package/devices/leviton.d.ts.map +1 -1
  134. package/devices/leviton.js +1 -2
  135. package/devices/leviton.js.map +1 -1
  136. package/devices/lidl.d.ts.map +1 -1
  137. package/devices/lidl.js +1 -2
  138. package/devices/lidl.js.map +1 -1
  139. package/devices/lixee.d.ts.map +1 -1
  140. package/devices/lixee.js +1 -2
  141. package/devices/lixee.js.map +1 -1
  142. package/devices/lumi.d.ts.map +1 -1
  143. package/devices/lumi.js +19 -82
  144. package/devices/lumi.js.map +1 -1
  145. package/devices/lupus.d.ts.map +1 -1
  146. package/devices/lupus.js +3 -4
  147. package/devices/lupus.js.map +1 -1
  148. package/devices/lutron.d.ts.map +1 -1
  149. package/devices/lutron.js +7 -5
  150. package/devices/lutron.js.map +1 -1
  151. package/devices/lytko.d.ts.map +1 -1
  152. package/devices/lytko.js +6 -7
  153. package/devices/lytko.js.map +1 -1
  154. package/devices/meazon.d.ts.map +1 -1
  155. package/devices/meazon.js +2 -3
  156. package/devices/meazon.js.map +1 -1
  157. package/devices/moes.js +2 -2
  158. package/devices/moes.js.map +1 -1
  159. package/devices/muller_licht.d.ts.map +1 -1
  160. package/devices/muller_licht.js +5 -6
  161. package/devices/muller_licht.js.map +1 -1
  162. package/devices/namron.d.ts.map +1 -1
  163. package/devices/namron.js +17 -18
  164. package/devices/namron.js.map +1 -1
  165. package/devices/net2grid.d.ts.map +1 -1
  166. package/devices/net2grid.js +1 -2
  167. package/devices/net2grid.js.map +1 -1
  168. package/devices/nodon.d.ts.map +1 -1
  169. package/devices/nodon.js +13 -14
  170. package/devices/nodon.js.map +1 -1
  171. package/devices/nue_3a.d.ts.map +1 -1
  172. package/devices/nue_3a.js +3 -4
  173. package/devices/nue_3a.js.map +1 -1
  174. package/devices/osram.d.ts.map +1 -1
  175. package/devices/osram.js +20 -27
  176. package/devices/osram.js.map +1 -1
  177. package/devices/owon.d.ts.map +1 -1
  178. package/devices/owon.js +2 -3
  179. package/devices/owon.js.map +1 -1
  180. package/devices/perenio.d.ts.map +1 -1
  181. package/devices/perenio.js +3 -4
  182. package/devices/perenio.js.map +1 -1
  183. package/devices/philips.d.ts.map +1 -1
  184. package/devices/philips.js +10 -16
  185. package/devices/philips.js.map +1 -1
  186. package/devices/pushok.d.ts.map +1 -1
  187. package/devices/pushok.js +13 -11
  188. package/devices/pushok.js.map +1 -1
  189. package/devices/salus_controls.d.ts.map +1 -1
  190. package/devices/salus_controls.js +9 -10
  191. package/devices/salus_controls.js.map +1 -1
  192. package/devices/saswell.js +1 -1
  193. package/devices/schneider_electric.d.ts.map +1 -1
  194. package/devices/schneider_electric.js +14 -17
  195. package/devices/schneider_electric.js.map +1 -1
  196. package/devices/securifi.d.ts.map +1 -1
  197. package/devices/securifi.js +1 -2
  198. package/devices/securifi.js.map +1 -1
  199. package/devices/sengled.d.ts.map +1 -1
  200. package/devices/sengled.js +46 -27
  201. package/devices/sengled.js.map +1 -1
  202. package/devices/shinasystem.d.ts.map +1 -1
  203. package/devices/shinasystem.js +22 -23
  204. package/devices/shinasystem.js.map +1 -1
  205. package/devices/sinope.d.ts.map +1 -1
  206. package/devices/sinope.js +17 -19
  207. package/devices/sinope.js.map +1 -1
  208. package/devices/smartthings.d.ts.map +1 -1
  209. package/devices/smartthings.js +3 -10
  210. package/devices/smartthings.js.map +1 -1
  211. package/devices/sonoff.d.ts.map +1 -1
  212. package/devices/sonoff.js +14 -11
  213. package/devices/sonoff.js.map +1 -1
  214. package/devices/stelpro.d.ts.map +1 -1
  215. package/devices/stelpro.js +4 -5
  216. package/devices/stelpro.js.map +1 -1
  217. package/devices/sunricher.d.ts.map +1 -1
  218. package/devices/sunricher.js +1 -14
  219. package/devices/sunricher.js.map +1 -1
  220. package/devices/swann.d.ts.map +1 -1
  221. package/devices/swann.js +1 -2
  222. package/devices/swann.js.map +1 -1
  223. package/devices/sylvania.d.ts.map +1 -1
  224. package/devices/sylvania.js +2 -11
  225. package/devices/sylvania.js.map +1 -1
  226. package/devices/terncy.d.ts.map +1 -1
  227. package/devices/terncy.js +5 -7
  228. package/devices/terncy.js.map +1 -1
  229. package/devices/third_reality.d.ts.map +1 -1
  230. package/devices/third_reality.js +18 -19
  231. package/devices/third_reality.js.map +1 -1
  232. package/devices/tplink.js +1 -1
  233. package/devices/tplink.js.map +1 -1
  234. package/devices/trust.d.ts.map +1 -1
  235. package/devices/trust.js +1 -2
  236. package/devices/trust.js.map +1 -1
  237. package/devices/tuya.d.ts.map +1 -1
  238. package/devices/tuya.js +61 -63
  239. package/devices/tuya.js.map +1 -1
  240. package/devices/ubisys.d.ts.map +1 -1
  241. package/devices/ubisys.js +8 -9
  242. package/devices/ubisys.js.map +1 -1
  243. package/devices/uhome.d.ts.map +1 -1
  244. package/devices/uhome.js +1 -2
  245. package/devices/uhome.js.map +1 -1
  246. package/devices/viessmann.d.ts.map +1 -1
  247. package/devices/viessmann.js +1 -2
  248. package/devices/viessmann.js.map +1 -1
  249. package/devices/weiser.d.ts.map +1 -1
  250. package/devices/weiser.js +0 -2
  251. package/devices/weiser.js.map +1 -1
  252. package/devices/wirenboard.d.ts.map +1 -1
  253. package/devices/wirenboard.js +3 -4
  254. package/devices/wirenboard.js.map +1 -1
  255. package/devices/xyzroe.d.ts.map +1 -1
  256. package/devices/xyzroe.js +1 -4
  257. package/devices/xyzroe.js.map +1 -1
  258. package/devices/zen.d.ts.map +1 -1
  259. package/devices/zen.js +2 -4
  260. package/devices/zen.js.map +1 -1
  261. package/devices/zigbeetlc.d.ts +1 -0
  262. package/devices/zigbeetlc.d.ts.map +1 -1
  263. package/devices/zigbeetlc.js +3 -3
  264. package/devices/zigbeetlc.js.map +1 -1
  265. package/index.d.ts +4 -3
  266. package/index.d.ts.map +1 -1
  267. package/index.js +15 -13
  268. package/index.js.map +1 -1
  269. package/lib/exposes.d.ts +2 -5
  270. package/lib/exposes.d.ts.map +1 -1
  271. package/lib/exposes.js +4 -9
  272. package/lib/exposes.js.map +1 -1
  273. package/lib/ikea.d.ts +1 -49
  274. package/lib/ikea.d.ts.map +1 -1
  275. package/lib/ikea.js +3 -72
  276. package/lib/ikea.js.map +1 -1
  277. package/lib/ledvance.d.ts.map +1 -1
  278. package/lib/ledvance.js +5 -3
  279. package/lib/ledvance.js.map +1 -1
  280. package/lib/legacy.d.ts +182 -915
  281. package/lib/legacy.d.ts.map +1 -1
  282. package/lib/legacy.js +177 -1924
  283. package/lib/legacy.js.map +1 -1
  284. package/lib/lumi.d.ts +0 -142
  285. package/lib/lumi.d.ts.map +1 -1
  286. package/lib/lumi.js +7 -293
  287. package/lib/lumi.js.map +1 -1
  288. package/lib/modernExtend.d.ts +3 -7
  289. package/lib/modernExtend.d.ts.map +1 -1
  290. package/lib/modernExtend.js +4 -73
  291. package/lib/modernExtend.js.map +1 -1
  292. package/lib/ota.d.ts +71 -0
  293. package/lib/ota.d.ts.map +1 -0
  294. package/lib/ota.js +663 -0
  295. package/lib/ota.js.map +1 -0
  296. package/lib/philips.d.ts.map +1 -1
  297. package/lib/philips.js +2 -3
  298. package/lib/philips.js.map +1 -1
  299. package/lib/types.d.ts +41 -30
  300. package/lib/types.d.ts.map +1 -1
  301. package/lib/utils.d.ts +0 -1
  302. package/lib/utils.d.ts.map +1 -1
  303. package/lib/utils.js +1 -7
  304. package/lib/utils.js.map +1 -1
  305. package/package.json +23 -9
  306. package/lib/ota/common.d.ts +0 -31
  307. package/lib/ota/common.d.ts.map +0 -1
  308. package/lib/ota/common.js +0 -630
  309. package/lib/ota/common.js.map +0 -1
  310. package/lib/ota/gmmts.d.ts +0 -8
  311. package/lib/ota/gmmts.d.ts.map +0 -1
  312. package/lib/ota/gmmts.js +0 -62
  313. package/lib/ota/gmmts.js.map +0 -1
  314. package/lib/ota/index.d.ts +0 -15
  315. package/lib/ota/index.d.ts.map +0 -1
  316. package/lib/ota/index.js +0 -48
  317. package/lib/ota/index.js.map +0 -1
  318. package/lib/ota/inovelli.d.ts +0 -8
  319. package/lib/ota/inovelli.d.ts.map +0 -1
  320. package/lib/ota/inovelli.js +0 -91
  321. package/lib/ota/inovelli.js.map +0 -1
  322. package/lib/ota/jethome.d.ts +0 -9
  323. package/lib/ota/jethome.d.ts.map +0 -1
  324. package/lib/ota/jethome.js +0 -92
  325. package/lib/ota/jethome.js.map +0 -1
  326. package/lib/ota/ledvance.d.ts +0 -11
  327. package/lib/ota/ledvance.d.ts.map +0 -1
  328. package/lib/ota/ledvance.js +0 -75
  329. package/lib/ota/ledvance.js.map +0 -1
  330. package/lib/ota/salus.d.ts +0 -11
  331. package/lib/ota/salus.d.ts.map +0 -1
  332. package/lib/ota/salus.js +0 -99
  333. package/lib/ota/salus.js.map +0 -1
  334. package/lib/ota/securifi.d.ts +0 -4
  335. package/lib/ota/securifi.d.ts.map +0 -1
  336. package/lib/ota/securifi.js +0 -48
  337. package/lib/ota/securifi.js.map +0 -1
  338. package/lib/ota/tradfri.d.ts +0 -13
  339. package/lib/ota/tradfri.d.ts.map +0 -1
  340. package/lib/ota/tradfri.js +0 -72
  341. package/lib/ota/tradfri.js.map +0 -1
  342. package/lib/ota/ubisys.d.ts +0 -20
  343. package/lib/ota/ubisys.d.ts.map +0 -1
  344. package/lib/ota/ubisys.js +0 -93
  345. package/lib/ota/ubisys.js.map +0 -1
  346. package/lib/ota/zigbeeOTA.d.ts +0 -12
  347. package/lib/ota/zigbeeOTA.d.ts.map +0 -1
  348. package/lib/ota/zigbeeOTA.js +0 -143
  349. package/lib/ota/zigbeeOTA.js.map +0 -1
package/lib/ota/common.js DELETED
@@ -1,630 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.UPGRADE_FILE_IDENTIFIER = void 0;
30
- exports.getAxios = getAxios;
31
- exports.setDataDir = setDataDir;
32
- exports.isValidUrl = isValidUrl;
33
- exports.readLocalFile = readLocalFile;
34
- exports.getFirmwareFile = getFirmwareFile;
35
- exports.processCustomCaBundle = processCustomCaBundle;
36
- exports.getOverrideIndexFile = getOverrideIndexFile;
37
- exports.parseImage = parseImage;
38
- exports.validateImageData = validateImageData;
39
- exports.isUpdateAvailable = isUpdateAvailable;
40
- exports.isNewImageAvailable = isNewImageAvailable;
41
- exports.updateToLatest = updateToLatest;
42
- exports.getNewImage = getNewImage;
43
- const assert_1 = __importDefault(require("assert"));
44
- const crypto_1 = __importDefault(require("crypto"));
45
- const fs_1 = require("fs");
46
- const https_1 = __importDefault(require("https"));
47
- const path_1 = __importDefault(require("path"));
48
- const tls_1 = __importDefault(require("tls"));
49
- const axios_1 = __importDefault(require("axios"));
50
- const buffer_crc32_1 = __importDefault(require("buffer-crc32"));
51
- const https_proxy_agent_1 = require("https-proxy-agent");
52
- const URI = __importStar(require("uri-js"));
53
- const zigbee_herdsman_1 = require("zigbee-herdsman");
54
- const logger_1 = require("../logger");
55
- const utils_1 = require("../utils");
56
- const NS = 'zhc:ota:common';
57
- let dataDir = null;
58
- const MAX_TIMEOUT = 2147483647; // +- 24 days
59
- const IMAGE_BLOCK_RESPONSE_DELAY = 250;
60
- exports.UPGRADE_FILE_IDENTIFIER = Buffer.from([0x1e, 0xf1, 0xee, 0x0b]);
61
- const VALID_SILABS_CRC = 0x2144df1c;
62
- const EBL_TAG_HEADER = 0x0;
63
- const EBL_TAG_ENC_HEADER = 0xfb05;
64
- const EBL_TAG_END = 0xfc04;
65
- const EBL_PADDING = 0xff;
66
- const EBL_IMAGE_SIGNATURE = 0xe350;
67
- const GBL_TAG_HEADER = 0xeb17a603;
68
- const GBL_TAG_END = 0xfc0404fc;
69
- // ----
70
- // Helper functions
71
- // ----
72
- function getAxios(caBundle = null) {
73
- let config = {};
74
- const httpsAgentOptions = {};
75
- if (caBundle !== null) {
76
- // We also include all system default CAs, as setting custom CAs fully replaces the default list
77
- httpsAgentOptions.ca = [...tls_1.default.rootCertificates, ...caBundle];
78
- }
79
- const proxy = process.env.HTTPS_PROXY;
80
- if (proxy) {
81
- config = {
82
- proxy: false,
83
- httpsAgent: new https_proxy_agent_1.HttpsProxyAgent(proxy, httpsAgentOptions),
84
- headers: {
85
- 'Accept-Encoding': '*',
86
- },
87
- };
88
- }
89
- else {
90
- config = {
91
- httpsAgent: new https_1.default.Agent(httpsAgentOptions),
92
- };
93
- }
94
- const axiosInstance = axios_1.default.create(config);
95
- axiosInstance.defaults.maxRedirects = 0; // Set to 0 to prevent automatic redirects
96
- // Add work with 302 redirects without hostname in Location header
97
- axiosInstance.interceptors.response.use((response) => response, (error) => {
98
- // get domain from basic url
99
- if (error.response && [301, 302].includes(error.response.status)) {
100
- let redirectUrl = error.response.headers.location;
101
- try {
102
- const parsedUrl = new URL(redirectUrl);
103
- if (!parsedUrl.protocol || !parsedUrl.host) {
104
- throw new Error(`Get Axios, no scheme or domain`);
105
- }
106
- }
107
- catch {
108
- // Prepend scheme and domain from the original request's base URL
109
- const baseURL = new URL(error.config.url);
110
- redirectUrl = `${baseURL.origin}${redirectUrl}`;
111
- }
112
- return axiosInstance.get(redirectUrl, { responseType: error.config.responseType || 'arraybuffer' });
113
- }
114
- });
115
- return axiosInstance;
116
- }
117
- function setDataDir(dir) {
118
- dataDir = dir;
119
- }
120
- function isValidUrl(url) {
121
- try {
122
- const parsed = URI.parse(url);
123
- return parsed.scheme === 'http' || parsed.scheme === 'https';
124
- }
125
- catch {
126
- return false;
127
- }
128
- }
129
- function readLocalFile(fileName) {
130
- // If the file name is not a full path, then treat it as a relative to the data directory
131
- if (!path_1.default.isAbsolute(fileName) && dataDir) {
132
- fileName = path_1.default.join(dataDir, fileName);
133
- }
134
- logger_1.logger.debug(`Getting local firmware file '${fileName}'`, NS);
135
- return (0, fs_1.readFileSync)(fileName);
136
- }
137
- async function getFirmwareFile(image) {
138
- const urlOrName = image.url;
139
- // First try to download firmware file with the URL provided
140
- if (isValidUrl(urlOrName)) {
141
- logger_1.logger.debug(`Downloading firmware image from '${urlOrName}'`, NS);
142
- return await getAxios().get(urlOrName, { responseType: 'arraybuffer' });
143
- }
144
- logger_1.logger.debug(`Try to read firmware image from local file '${urlOrName}'`, NS);
145
- return { data: readLocalFile(urlOrName) };
146
- }
147
- async function processCustomCaBundle(uri) {
148
- let rawCaBundle = '';
149
- if (isValidUrl(uri)) {
150
- rawCaBundle = (await axios_1.default.get(uri)).data;
151
- }
152
- else {
153
- if (!path_1.default.isAbsolute(uri) && dataDir) {
154
- uri = path_1.default.join(dataDir, uri);
155
- }
156
- rawCaBundle = (0, fs_1.readFileSync)(uri, { encoding: 'utf-8' });
157
- }
158
- // Parse the raw CA bundle into clean, separate CA certs
159
- const lines = rawCaBundle.split('\n');
160
- const caBundle = [];
161
- let inCert = false;
162
- let currentCert = '';
163
- for (const line of lines) {
164
- if (line === '-----BEGIN CERTIFICATE-----') {
165
- inCert = true;
166
- }
167
- if (inCert) {
168
- currentCert = currentCert + line + '\n';
169
- }
170
- if (line === '-----END CERTIFICATE-----') {
171
- inCert = false;
172
- caBundle.push(currentCert);
173
- currentCert = '';
174
- }
175
- }
176
- return caBundle;
177
- }
178
- async function getOverrideIndexFile(urlOrName) {
179
- if (isValidUrl(urlOrName)) {
180
- const { data: index } = await getAxios().get(urlOrName);
181
- if (!index) {
182
- throw new Error(`Error getting override index file from '${urlOrName}'`);
183
- }
184
- return index;
185
- }
186
- return JSON.parse((0, fs_1.readFileSync)(urlOrName, 'utf-8'));
187
- }
188
- // ----
189
- // OTA functions
190
- // ----
191
- function getOTAEndpoint(device) {
192
- return device.endpoints.find((e) => e.supportsOutputCluster('genOta'));
193
- }
194
- function parseSubElement(buffer, position) {
195
- const tagID = buffer.readUInt16LE(position);
196
- const length = buffer.readUInt32LE(position + 2);
197
- const data = buffer.subarray(position + 6, position + 6 + length);
198
- return { tagID, length, data };
199
- }
200
- function parseImage(buffer, suppressElementImageParseFailure = false) {
201
- const header = {
202
- otaUpgradeFileIdentifier: buffer.subarray(0, 4),
203
- otaHeaderVersion: buffer.readUInt16LE(4),
204
- otaHeaderLength: buffer.readUInt16LE(6),
205
- otaHeaderFieldControl: buffer.readUInt16LE(8),
206
- manufacturerCode: buffer.readUInt16LE(10),
207
- imageType: buffer.readUInt16LE(12),
208
- fileVersion: buffer.readUInt32LE(14),
209
- zigbeeStackVersion: buffer.readUInt16LE(18),
210
- otaHeaderString: buffer.toString('utf8', 20, 52),
211
- totalImageSize: buffer.readUInt32LE(52),
212
- };
213
- let headerPos = 56;
214
- let didSuppressElementImageParseFailure = false;
215
- if (header.otaHeaderFieldControl & 1) {
216
- header.securityCredentialVersion = buffer.readUInt8(headerPos);
217
- headerPos += 1;
218
- }
219
- if (header.otaHeaderFieldControl & 2) {
220
- header.upgradeFileDestination = buffer.subarray(headerPos, headerPos + 8);
221
- headerPos += 8;
222
- }
223
- if (header.otaHeaderFieldControl & 4) {
224
- header.minimumHardwareVersion = buffer.readUInt16LE(headerPos);
225
- headerPos += 2;
226
- header.maximumHardwareVersion = buffer.readUInt16LE(headerPos);
227
- headerPos += 2;
228
- }
229
- const raw = buffer.subarray(0, header.totalImageSize);
230
- (0, assert_1.default)(exports.UPGRADE_FILE_IDENTIFIER.equals(header.otaUpgradeFileIdentifier), `Not an OTA file`);
231
- let position = header.otaHeaderLength;
232
- const elements = [];
233
- try {
234
- while (position < header.totalImageSize) {
235
- const element = parseSubElement(buffer, position);
236
- elements.push(element);
237
- position += element.data.length + 6;
238
- }
239
- }
240
- catch (error) {
241
- if (!suppressElementImageParseFailure) {
242
- throw error;
243
- }
244
- didSuppressElementImageParseFailure = true;
245
- logger_1.logger.debug('Partially failed to parse the image, continuing anyway...', NS);
246
- }
247
- if (!didSuppressElementImageParseFailure) {
248
- (0, assert_1.default)(position === header.totalImageSize, `Size mismatch`);
249
- }
250
- return { header, elements, raw };
251
- }
252
- function validateImageData(image) {
253
- for (const element of image.elements) {
254
- const { data } = element;
255
- if (data.readUInt32BE(0) === GBL_TAG_HEADER) {
256
- validateSilabsGbl(data);
257
- }
258
- else {
259
- const tag = data.readUInt16BE(0);
260
- if ((tag === EBL_TAG_HEADER && data.readUInt16BE(6) === EBL_IMAGE_SIGNATURE) || tag === EBL_TAG_ENC_HEADER) {
261
- validateSilabsEbl(data);
262
- }
263
- }
264
- }
265
- }
266
- function validateSilabsEbl(data) {
267
- const dataLength = data.length;
268
- let position = 0;
269
- while (position + 4 <= dataLength) {
270
- const tag = data.readUInt16BE(position);
271
- const len = data.readUInt16BE(position + 2);
272
- position += 4 + len;
273
- if (tag !== EBL_TAG_END) {
274
- continue;
275
- }
276
- for (let position2 = position; position2 < dataLength; position2++) {
277
- (0, assert_1.default)(data.readUInt8(position2) === EBL_PADDING, `Image padding contains invalid bytes`);
278
- }
279
- const calculatedCrc32 = buffer_crc32_1.default.unsigned(data.subarray(0, position));
280
- (0, assert_1.default)(calculatedCrc32 === VALID_SILABS_CRC, `Image CRC-32 is invalid`);
281
- return;
282
- }
283
- throw new Error(`Image is truncated, not long enough to contain a valid tag`);
284
- }
285
- function validateSilabsGbl(data) {
286
- const dataLength = data.length;
287
- let position = 0;
288
- while (position + 8 <= dataLength) {
289
- const tag = data.readUInt32BE(position);
290
- const len = data.readUInt32LE(position + 4);
291
- position += 8 + len;
292
- if (tag !== GBL_TAG_END) {
293
- continue;
294
- }
295
- const calculatedCrc32 = buffer_crc32_1.default.unsigned(data.subarray(0, position));
296
- (0, assert_1.default)(calculatedCrc32 === VALID_SILABS_CRC, `Image CRC-32 is invalid`);
297
- return;
298
- }
299
- throw new Error(`Image is truncated, not long enough to contain a valid tag`);
300
- }
301
- function cancelWaiters(waiters) {
302
- waiters.imageBlockOrPageRequest?.cancel();
303
- waiters.upgradeEndRequest?.cancel();
304
- }
305
- async function sendQueryNextImageResponse(endpoint, image, requestTransactionSequenceNumber) {
306
- const payload = {
307
- status: zigbee_herdsman_1.Zcl.Status.SUCCESS,
308
- manufacturerCode: image.header.manufacturerCode,
309
- imageType: image.header.imageType,
310
- fileVersion: image.header.fileVersion,
311
- imageSize: image.header.totalImageSize,
312
- };
313
- try {
314
- await endpoint.commandResponse('genOta', 'queryNextImageResponse', payload, null, requestTransactionSequenceNumber);
315
- }
316
- catch (error) {
317
- logger_1.logger.debug(`Failed to send queryNextImageResponse: ${error}`, NS);
318
- }
319
- }
320
- async function imageNotify(endpoint) {
321
- await endpoint.commandResponse('genOta', 'imageNotify', { payloadType: 0, queryJitter: 100 }, { sendPolicy: 'immediate' });
322
- }
323
- async function requestOTA(endpoint) {
324
- // Some devices (e.g. Insta) take very long trying to discover the correct coordinator EP for OTA.
325
- const queryNextImageRequest = endpoint.waitForCommand('genOta', 'queryNextImageRequest', null, 60000);
326
- try {
327
- await imageNotify(endpoint);
328
- const response = await queryNextImageRequest.promise;
329
- return [response.header.transactionSequenceNumber, response.payload];
330
- }
331
- catch {
332
- queryNextImageRequest.cancel();
333
- throw new Error(`Device didn't respond to OTA request`);
334
- }
335
- }
336
- function getImageBlockResponsePayload(image, imageBlockRequest, pageOffset, pageSize) {
337
- let start = imageBlockRequest.payload.fileOffset + pageOffset;
338
- // When the data size is too big, OTA gets unstable, so default it to 50 bytes maximum.
339
- // - Insta devices, OTA only works for data sizes 40 and smaller (= manufacturerCode 4474).
340
- // - Legrand devices (newer firmware) require up to 64 bytes (= manufacturerCode 4129).
341
- let maximumDataSize = 50;
342
- if (imageBlockRequest.payload.manufacturerCode === zigbee_herdsman_1.Zcl.ManufacturerCode.INSTA_GMBH) {
343
- maximumDataSize = 40;
344
- }
345
- else if (imageBlockRequest.payload.manufacturerCode === zigbee_herdsman_1.Zcl.ManufacturerCode.LEGRAND_GROUP) {
346
- maximumDataSize = Infinity;
347
- }
348
- let dataSize = Math.min(maximumDataSize, imageBlockRequest.payload.maximumDataSize);
349
- // Hack for https://github.com/Koenkk/zigbee-OTA/issues/328 (Legrand OTA not working)
350
- if (imageBlockRequest.payload.manufacturerCode === zigbee_herdsman_1.Zcl.ManufacturerCode.LEGRAND_GROUP &&
351
- imageBlockRequest.payload.fileOffset === 50 &&
352
- imageBlockRequest.payload.maximumDataSize === 12) {
353
- logger_1.logger.info(`Detected Legrand firmware issue, attempting to reset the OTA stack`, NS);
354
- // The following vector seems to buffer overflow the device to reset the OTA stack!
355
- start = 78;
356
- dataSize = 64;
357
- }
358
- if (pageSize) {
359
- dataSize = Math.min(dataSize, pageSize - pageOffset);
360
- }
361
- let end = start + dataSize;
362
- if (end > image.raw.length) {
363
- end = image.raw.length;
364
- }
365
- logger_1.logger.debug(`Request offsets: fileOffset=${imageBlockRequest.payload.fileOffset} pageOffset=${pageOffset} ` +
366
- `maximumDataSize=${imageBlockRequest.payload.maximumDataSize}`, NS);
367
- logger_1.logger.debug(`Payload offsets: start=${start} end=${end} dataSize=${dataSize}`, NS);
368
- return {
369
- status: zigbee_herdsman_1.Zcl.Status.SUCCESS,
370
- manufacturerCode: imageBlockRequest.payload.manufacturerCode,
371
- imageType: imageBlockRequest.payload.imageType,
372
- fileVersion: imageBlockRequest.payload.fileVersion,
373
- fileOffset: start,
374
- dataSize: end - start,
375
- data: image.raw.subarray(start, end),
376
- };
377
- }
378
- function callOnProgress(startTime, lastUpdate, imageBlockRequest, image, onProgress) {
379
- const now = Date.now();
380
- // Call on progress every +- 30 seconds
381
- if (lastUpdate === null || now - lastUpdate > 30000) {
382
- const totalDuration = (now - startTime) / 1000; // in seconds
383
- const bytesPerSecond = imageBlockRequest.payload.fileOffset / totalDuration;
384
- const remaining = (image.header.totalImageSize - imageBlockRequest.payload.fileOffset) / bytesPerSecond;
385
- let percentage = imageBlockRequest.payload.fileOffset / image.header.totalImageSize;
386
- percentage = Math.round(percentage * 10000) / 100;
387
- logger_1.logger.debug(`Update at ${percentage}%, remaining ${remaining} seconds`, NS);
388
- onProgress(percentage, remaining === Infinity ? null : remaining);
389
- return now;
390
- }
391
- else {
392
- return lastUpdate;
393
- }
394
- }
395
- async function isUpdateAvailable(device, requestPayload, isNewImageAvailable = null, getImageMeta = null) {
396
- const logId = `'${device.ieeeAddr}' (${device.modelID})`;
397
- logger_1.logger.debug(`Checking if an update is available for ${logId}`, NS);
398
- if (requestPayload == null) {
399
- const endpoint = getOTAEndpoint(device);
400
- (0, assert_1.default)(endpoint != null, `Failed to find an endpoint which supports the OTA cluster for ${logId}`);
401
- logger_1.logger.debug(`Using endpoint '${endpoint.ID}'`, NS);
402
- const [, payload] = await requestOTA(endpoint);
403
- logger_1.logger.debug(`Got request '${JSON.stringify(payload)}'`, NS);
404
- requestPayload = payload;
405
- }
406
- const availableResult = await isNewImageAvailable(requestPayload, device, getImageMeta);
407
- logger_1.logger.debug(`Update available for ${logId}: ${availableResult.available < 0 ? 'YES' : 'NO'}`, NS);
408
- if (availableResult.available > 0) {
409
- logger_1.logger.warning(`Firmware on ${logId} is newer than latest firmware online.`, NS);
410
- }
411
- return { ...availableResult, available: availableResult.available < 0 };
412
- }
413
- async function isNewImageAvailable(current, device, getImageMeta) {
414
- const currentS = JSON.stringify(current);
415
- logger_1.logger.debug(`Is new image available for '${device.ieeeAddr}' (${device.modelID}), current '${currentS}'`, NS);
416
- const meta = await getImageMeta(current, device);
417
- // Soft-fail because no images in repo/URL for specified device
418
- if (!meta) {
419
- const metaS = `device '${device.modelID}', hardwareVersion '${device.hardwareVersion}', manufacturerName ${device.manufacturerName}`;
420
- logger_1.logger.debug(`Images currently unavailable for ${metaS}, ${currentS}'`, NS);
421
- return {
422
- available: 0,
423
- currentFileVersion: current.fileVersion,
424
- otaFileVersion: current.fileVersion,
425
- };
426
- }
427
- logger_1.logger.debug(`Is new image available for '${device.ieeeAddr}' (${device.modelID}), latest meta '${JSON.stringify(meta)}'`, NS);
428
- // Negative number means the new firmware is 'newer' than current one
429
- return {
430
- available: meta.force ? -1 : Math.sign(current.fileVersion - meta.fileVersion),
431
- currentFileVersion: current.fileVersion,
432
- otaFileVersion: meta.fileVersion,
433
- };
434
- }
435
- /**
436
- * @see https://zigbeealliance.org/wp-content/uploads/2021/10/07-5123-08-Zigbee-Cluster-Library.pdf 11.12
437
- */
438
- async function updateToLatest(device, onProgress, getNewImage, getImageMeta = null, downloadImage = null, suppressElementImageParseFailure = false) {
439
- const logId = `'${device.ieeeAddr}' (${device.modelID})`;
440
- logger_1.logger.debug(`Updating ${logId} to latest`, NS);
441
- const endpoint = getOTAEndpoint(device);
442
- (0, assert_1.default)(endpoint != null, `Failed to find an endpoint which supports the OTA cluster for ${logId}`);
443
- logger_1.logger.debug(`Using endpoint '${endpoint.ID}'`, NS);
444
- const [transNum, requestPayload] = await requestOTA(endpoint);
445
- logger_1.logger.debug(`Got request payload '${JSON.stringify(requestPayload)}'`, NS);
446
- const image = await getNewImage(requestPayload, device, getImageMeta, downloadImage, suppressElementImageParseFailure);
447
- logger_1.logger.debug(`Got new image for ${logId}`, NS);
448
- // reply to `queryNextImageRequest` in `requestOTA` now that we have the data for it,
449
- // should trigger image block/page request from device
450
- await sendQueryNextImageResponse(endpoint, image, transNum);
451
- const waiters = {};
452
- let lastBlockResponseTime = 0;
453
- let lastUpdate = null;
454
- const startTime = Date.now();
455
- let ended = false;
456
- const sendImageBlockResponse = async (imageBlockRequest, pageOffset, pageSize) => {
457
- // Reduce network congestion by throttling response if necessary
458
- {
459
- const blockResponseTime = Date.now();
460
- const delay = blockResponseTime - lastBlockResponseTime;
461
- if (delay < IMAGE_BLOCK_RESPONSE_DELAY) {
462
- await (0, utils_1.sleep)(IMAGE_BLOCK_RESPONSE_DELAY - delay);
463
- }
464
- lastBlockResponseTime = blockResponseTime;
465
- }
466
- try {
467
- const blockPayload = getImageBlockResponsePayload(image, imageBlockRequest, pageOffset, pageSize);
468
- await endpoint.commandResponse('genOta', 'imageBlockResponse', blockPayload, null, imageBlockRequest.header.transactionSequenceNumber);
469
- pageOffset += blockPayload.dataSize;
470
- }
471
- catch (error) {
472
- // Shit happens, device will probably do a new imageBlockRequest so don't care.
473
- logger_1.logger.debug(`Image block response failed: ${error}`, NS);
474
- }
475
- lastUpdate = callOnProgress(startTime, lastUpdate, imageBlockRequest, image, onProgress);
476
- return pageOffset;
477
- };
478
- const sendImage = async () => {
479
- let imageBlockOrPageRequestTimeoutMs = 150000;
480
- // increase the upgradeEndReq wait time to solve the problem of OTA timeout failure of Sonoff Devices
481
- // (https://github.com/Koenkk/zigbee-herdsman-converters/issues/6657)
482
- if (requestPayload.manufacturerCode === zigbee_herdsman_1.Zcl.ManufacturerCode.SHENZHEN_COOLKIT_TECHNOLOGY_CO_LTD && requestPayload.imageType == 8199) {
483
- imageBlockOrPageRequestTimeoutMs = 3600000;
484
- }
485
- // Bosch transmits the firmware updates in the background in their native implementation.
486
- // According to the app, this can take up to 2 days. Therefore, we assume to get at least
487
- // one package request per hour from the device here.
488
- if (requestPayload.manufacturerCode == zigbee_herdsman_1.Zcl.ManufacturerCode.ROBERT_BOSCH_GMBH) {
489
- imageBlockOrPageRequestTimeoutMs = 60 * 60 * 1000;
490
- }
491
- // Increase the timeout for Legrand devices, so that they will re-initiate and update themselves
492
- // Newer firmwares have ackward behaviours when it comes to the handling of the last bytes of OTA updates
493
- if (requestPayload.manufacturerCode === zigbee_herdsman_1.Zcl.ManufacturerCode.LEGRAND_GROUP) {
494
- imageBlockOrPageRequestTimeoutMs = 30 * 60 * 1000;
495
- }
496
- while (!ended) {
497
- const imageBlockRequest = endpoint.waitForCommand('genOta', 'imageBlockRequest', null, imageBlockOrPageRequestTimeoutMs);
498
- const imagePageRequest = endpoint.waitForCommand('genOta', 'imagePageRequest', null, imageBlockOrPageRequestTimeoutMs);
499
- waiters.imageBlockOrPageRequest = {
500
- promise: Promise.race([imageBlockRequest.promise, imagePageRequest.promise]),
501
- cancel: () => {
502
- imageBlockRequest.cancel();
503
- imagePageRequest.cancel();
504
- },
505
- };
506
- try {
507
- const result = await waiters.imageBlockOrPageRequest.promise;
508
- let pageOffset = 0;
509
- let pageSize = 0;
510
- if ('pageSize' in result.payload) {
511
- // imagePageRequest
512
- pageSize = result.payload.pageSize;
513
- const handleImagePageRequestBlocks = async (imagePageRequest) => {
514
- if (pageOffset < pageSize) {
515
- pageOffset = await sendImageBlockResponse(imagePageRequest, pageOffset, pageSize);
516
- await handleImagePageRequestBlocks(imagePageRequest);
517
- }
518
- };
519
- await handleImagePageRequestBlocks(result);
520
- }
521
- else {
522
- // imageBlockRequest
523
- pageOffset = await sendImageBlockResponse(result, pageOffset, pageSize);
524
- }
525
- }
526
- catch (error) {
527
- cancelWaiters(waiters);
528
- throw new Error(`Timeout. Device did not start/finish firmware download after being notified. (${error})`);
529
- }
530
- }
531
- };
532
- // will eventually time out in `sendImage` if this never resolves when it's supposed to
533
- waiters.upgradeEndRequest = endpoint.waitForCommand('genOta', 'upgradeEndRequest', null, MAX_TIMEOUT);
534
- logger_1.logger.debug(`Starting update`, NS);
535
- // `sendImage` is looping and never resolves, so will only stop before `upgradeEndRequest` resolves if it throws
536
- await Promise.race([sendImage(), waiters.upgradeEndRequest.promise]);
537
- cancelWaiters(waiters);
538
- ended = true;
539
- // already resolved when this is reached
540
- const endResult = await waiters.upgradeEndRequest.promise;
541
- logger_1.logger.debug(`Got upgrade end request for ${logId}: ${JSON.stringify(endResult.payload)}`, NS);
542
- if (endResult.payload.status === zigbee_herdsman_1.Zcl.Status.SUCCESS) {
543
- const payload = {
544
- manufacturerCode: image.header.manufacturerCode,
545
- imageType: image.header.imageType,
546
- fileVersion: image.header.fileVersion,
547
- currentTime: 0,
548
- upgradeTime: 1,
549
- };
550
- try {
551
- await endpoint.commandResponse('genOta', 'upgradeEndResponse', payload, null, endResult.header.transactionSequenceNumber);
552
- logger_1.logger.debug(`Update successful. Waiting for device announce...`, NS);
553
- onProgress(100, null);
554
- let timer = null;
555
- return await new Promise((resolve) => {
556
- const onDeviceAnnounce = () => {
557
- clearTimeout(timer);
558
- logger_1.logger.debug(`Received device announce, update finished.`, NS);
559
- resolve(image.header.fileVersion);
560
- };
561
- // force "finished" after 2 minutes
562
- timer = setTimeout(() => {
563
- device.removeListener('deviceAnnounce', onDeviceAnnounce);
564
- logger_1.logger.debug(`Timed out waiting for device announce, update considered finished.`, NS);
565
- resolve(image.header.fileVersion);
566
- }, 120 * 1000);
567
- device.once('deviceAnnounce', onDeviceAnnounce);
568
- });
569
- }
570
- catch (error) {
571
- throw new Error(`Upgrade end response failed: ${error}`);
572
- }
573
- }
574
- else {
575
- /**
576
- * For other status value received such as INVALID_IMAGE, REQUIRE_MORE_IMAGE, or ABORT,
577
- * the upgrade server SHALL not send Upgrade End Response command but it SHALL send default
578
- * response command with status of success and it SHALL wait for the client to reinitiate the upgrade process.
579
- */
580
- try {
581
- await endpoint.defaultResponse(zigbee_herdsman_1.Zcl.Clusters.genOta.commands.upgradeEndRequest.ID, zigbee_herdsman_1.Zcl.Status.SUCCESS, zigbee_herdsman_1.Zcl.Clusters.genOta.ID, endResult.header.transactionSequenceNumber);
582
- }
583
- catch (error) {
584
- logger_1.logger.debug(`Upgrade end request default response failed: ${error}`, NS);
585
- }
586
- throw new Error(`Update failed with reason: '${zigbee_herdsman_1.Zcl.Status[endResult.payload.status]}'`);
587
- }
588
- }
589
- async function getNewImage(current, device, getImageMeta, downloadImage, suppressElementImageParseFailure) {
590
- // TODO: better errors (these are reported in frontend notifies)
591
- const logId = `'${device.ieeeAddr}' (${device.modelID})`;
592
- const meta = await getImageMeta(current, device);
593
- (0, assert_1.default)(!!meta, `Images for ${logId} currently unavailable`);
594
- logger_1.logger.debug(`Getting new image for ${logId}, latest meta ${JSON.stringify(meta)}`, NS);
595
- (0, assert_1.default)(meta.fileVersion > current.fileVersion || meta.force, `No new image available`);
596
- const download = downloadImage ? await downloadImage(meta) : await getAxios().get(meta.url, { responseType: 'arraybuffer' });
597
- const checksum = meta.sha512 || meta.sha256;
598
- if (checksum) {
599
- const hash = crypto_1.default.createHash(meta.sha512 ? 'sha512' : 'sha256');
600
- hash.update(download.data);
601
- (0, assert_1.default)(hash.digest('hex') === checksum, `File checksum validation failed`);
602
- logger_1.logger.debug(`Update checksum validation succeeded for ${logId}`, NS);
603
- }
604
- const start = download.data.indexOf(exports.UPGRADE_FILE_IDENTIFIER);
605
- const image = parseImage(download.data.slice(start), suppressElementImageParseFailure);
606
- logger_1.logger.debug(`Get new image for ${logId}, image header ${JSON.stringify(image.header)}`, NS);
607
- (0, assert_1.default)(image.header.fileVersion === meta.fileVersion, `File version mismatch`);
608
- (0, assert_1.default)(!meta.fileSize || image.header.totalImageSize === meta.fileSize, `Image size mismatch`);
609
- (0, assert_1.default)(image.header.manufacturerCode === current.manufacturerCode, `Manufacturer code mismatch`);
610
- (0, assert_1.default)(image.header.imageType === current.imageType, `Image type mismatch`);
611
- if ('minimumHardwareVersion' in image.header && 'maximumHardwareVersion' in image.header) {
612
- (0, assert_1.default)(image.header.minimumHardwareVersion <= device.hardwareVersion && device.hardwareVersion <= image.header.maximumHardwareVersion, `Hardware version mismatch`);
613
- }
614
- validateImageData(image);
615
- return image;
616
- }
617
- exports.UPGRADE_FILE_IDENTIFIER = exports.UPGRADE_FILE_IDENTIFIER;
618
- exports.isUpdateAvailable = isUpdateAvailable;
619
- exports.parseImage = parseImage;
620
- exports.validateImageData = validateImageData;
621
- exports.isNewImageAvailable = isNewImageAvailable;
622
- exports.updateToLatest = updateToLatest;
623
- exports.getNewImage = getNewImage;
624
- exports.getAxios = getAxios;
625
- exports.isValidUrl = isValidUrl;
626
- exports.setDataDir = setDataDir;
627
- exports.getFirmwareFile = getFirmwareFile;
628
- exports.readLocalFile = readLocalFile;
629
- exports.getOverrideIndexFile = getOverrideIndexFile;
630
- //# sourceMappingURL=common.js.map