@willieee802/zigbee-herdsman 0.19.2 → 0.34.3

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 (530) hide show
  1. package/.babelrc.js +0 -4
  2. package/.release-please-manifest.json +1 -2
  3. package/CHANGELOG.md +376 -0
  4. package/README.md +1 -1
  5. package/dist/adapter/adapter.d.ts +61 -61
  6. package/dist/adapter/adapter.d.ts.map +1 -1
  7. package/dist/adapter/adapter.js +158 -146
  8. package/dist/adapter/adapter.js.map +1 -1
  9. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +68 -68
  10. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
  11. package/dist/adapter/deconz/adapter/deconzAdapter.js +1081 -1060
  12. package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
  13. package/dist/adapter/deconz/adapter/index.d.ts +2 -2
  14. package/dist/adapter/deconz/adapter/index.js +10 -10
  15. package/dist/adapter/deconz/driver/constants.d.ts +104 -104
  16. package/dist/adapter/deconz/driver/constants.js +55 -55
  17. package/dist/adapter/deconz/driver/driver.d.ts +81 -81
  18. package/dist/adapter/deconz/driver/driver.d.ts.map +1 -1
  19. package/dist/adapter/deconz/driver/driver.js +750 -732
  20. package/dist/adapter/deconz/driver/driver.js.map +1 -1
  21. package/dist/adapter/deconz/driver/frame.d.ts +6 -6
  22. package/dist/adapter/deconz/driver/frame.js +13 -13
  23. package/dist/adapter/deconz/driver/frameParser.d.ts +2 -2
  24. package/dist/adapter/deconz/driver/frameParser.js +443 -443
  25. package/dist/adapter/deconz/driver/frameParser.js.map +1 -1
  26. package/dist/adapter/deconz/driver/parser.d.ts +12 -12
  27. package/dist/adapter/deconz/driver/parser.js +63 -61
  28. package/dist/adapter/deconz/driver/parser.js.map +1 -1
  29. package/dist/adapter/deconz/driver/writer.d.ts +8 -8
  30. package/dist/adapter/deconz/driver/writer.js +44 -44
  31. package/dist/adapter/ember/adapter/emberAdapter.d.ts +817 -0
  32. package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -0
  33. package/dist/adapter/ember/adapter/emberAdapter.js +2981 -0
  34. package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -0
  35. package/dist/adapter/ember/adapter/endpoints.d.ts +25 -0
  36. package/dist/adapter/ember/adapter/endpoints.d.ts.map +1 -0
  37. package/dist/adapter/ember/adapter/endpoints.js +66 -0
  38. package/dist/adapter/ember/adapter/endpoints.js.map +1 -0
  39. package/dist/adapter/ember/adapter/index.d.ts +3 -0
  40. package/dist/adapter/ember/adapter/index.d.ts.map +1 -0
  41. package/dist/adapter/ember/adapter/index.js +6 -0
  42. package/dist/adapter/ember/adapter/index.js.map +1 -0
  43. package/dist/adapter/ember/adapter/oneWaitress.d.ts +97 -0
  44. package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -0
  45. package/dist/adapter/ember/adapter/oneWaitress.js +226 -0
  46. package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -0
  47. package/dist/adapter/ember/adapter/requestQueue.d.ts +59 -0
  48. package/dist/adapter/ember/adapter/requestQueue.d.ts.map +1 -0
  49. package/dist/adapter/ember/adapter/requestQueue.js +144 -0
  50. package/dist/adapter/ember/adapter/requestQueue.js.map +1 -0
  51. package/dist/adapter/ember/adapter/tokensManager.d.ts +69 -0
  52. package/dist/adapter/ember/adapter/tokensManager.d.ts.map +1 -0
  53. package/dist/adapter/ember/adapter/tokensManager.js +685 -0
  54. package/dist/adapter/ember/adapter/tokensManager.js.map +1 -0
  55. package/dist/adapter/ember/consts.d.ts +198 -0
  56. package/dist/adapter/ember/consts.d.ts.map +1 -0
  57. package/dist/adapter/ember/consts.js +253 -0
  58. package/dist/adapter/ember/consts.js.map +1 -0
  59. package/dist/adapter/ember/enums.d.ts +2184 -0
  60. package/dist/adapter/ember/enums.d.ts.map +1 -0
  61. package/dist/adapter/ember/enums.js +2391 -0
  62. package/dist/adapter/ember/enums.js.map +1 -0
  63. package/dist/adapter/ember/ezsp/buffalo.d.ts +156 -0
  64. package/dist/adapter/ember/ezsp/buffalo.d.ts.map +1 -0
  65. package/dist/adapter/ember/ezsp/buffalo.js +1033 -0
  66. package/dist/adapter/ember/ezsp/buffalo.js.map +1 -0
  67. package/dist/adapter/ember/ezsp/consts.d.ts +116 -0
  68. package/dist/adapter/ember/ezsp/consts.d.ts.map +1 -0
  69. package/dist/adapter/ember/ezsp/consts.js +128 -0
  70. package/dist/adapter/ember/ezsp/consts.js.map +1 -0
  71. package/dist/adapter/ember/ezsp/enums.d.ts +879 -0
  72. package/dist/adapter/ember/ezsp/enums.d.ts.map +1 -0
  73. package/dist/adapter/ember/ezsp/enums.js +948 -0
  74. package/dist/adapter/ember/ezsp/enums.js.map +1 -0
  75. package/dist/adapter/ember/ezsp/ezsp.d.ts +2664 -0
  76. package/dist/adapter/ember/ezsp/ezsp.d.ts.map +1 -0
  77. package/dist/adapter/ember/ezsp/ezsp.js +6438 -0
  78. package/dist/adapter/ember/ezsp/ezsp.js.map +1 -0
  79. package/dist/adapter/ember/types.d.ts +733 -0
  80. package/dist/adapter/ember/types.d.ts.map +1 -0
  81. package/dist/adapter/ember/types.js +3 -0
  82. package/dist/adapter/ember/types.js.map +1 -0
  83. package/dist/adapter/ember/uart/ash.d.ts +451 -0
  84. package/dist/adapter/ember/uart/ash.d.ts.map +1 -0
  85. package/dist/adapter/ember/uart/ash.js +1584 -0
  86. package/dist/adapter/ember/uart/ash.js.map +1 -0
  87. package/dist/adapter/ember/uart/consts.d.ts +91 -0
  88. package/dist/adapter/ember/uart/consts.d.ts.map +1 -0
  89. package/dist/adapter/ember/uart/consts.js +100 -0
  90. package/dist/adapter/ember/uart/consts.js.map +1 -0
  91. package/dist/adapter/ember/uart/enums.d.ts +191 -0
  92. package/dist/adapter/ember/uart/enums.d.ts.map +1 -0
  93. package/dist/adapter/ember/uart/enums.js +197 -0
  94. package/dist/adapter/ember/uart/enums.js.map +1 -0
  95. package/dist/adapter/ember/uart/parser.d.ts +10 -0
  96. package/dist/adapter/ember/uart/parser.d.ts.map +1 -0
  97. package/dist/adapter/ember/uart/parser.js +41 -0
  98. package/dist/adapter/ember/uart/parser.js.map +1 -0
  99. package/dist/adapter/ember/uart/queues.d.ts +85 -0
  100. package/dist/adapter/ember/uart/queues.d.ts.map +1 -0
  101. package/dist/adapter/ember/uart/queues.js +212 -0
  102. package/dist/adapter/ember/uart/queues.js.map +1 -0
  103. package/dist/adapter/ember/uart/writer.d.ts +15 -0
  104. package/dist/adapter/ember/uart/writer.d.ts.map +1 -0
  105. package/dist/adapter/ember/uart/writer.js +48 -0
  106. package/dist/adapter/ember/uart/writer.js.map +1 -0
  107. package/dist/adapter/ember/utils/initters.d.ts +20 -0
  108. package/dist/adapter/ember/utils/initters.d.ts.map +1 -0
  109. package/dist/adapter/ember/utils/initters.js +58 -0
  110. package/dist/adapter/ember/utils/initters.js.map +1 -0
  111. package/dist/adapter/ember/utils/math.d.ts +51 -0
  112. package/dist/adapter/ember/utils/math.d.ts.map +1 -0
  113. package/dist/adapter/ember/utils/math.js +102 -0
  114. package/dist/adapter/ember/utils/math.js.map +1 -0
  115. package/dist/adapter/ember/zdo.d.ts +921 -0
  116. package/dist/adapter/ember/zdo.d.ts.map +1 -0
  117. package/dist/adapter/ember/zdo.js +723 -0
  118. package/dist/adapter/ember/zdo.js.map +1 -0
  119. package/dist/adapter/events.d.ts +47 -47
  120. package/dist/adapter/events.js +13 -14
  121. package/dist/adapter/events.js.map +1 -1
  122. package/dist/adapter/ezsp/adapter/backup.d.ts +9 -9
  123. package/dist/adapter/ezsp/adapter/backup.d.ts.map +1 -1
  124. package/dist/adapter/ezsp/adapter/backup.js +72 -53
  125. package/dist/adapter/ezsp/adapter/backup.js.map +1 -1
  126. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +61 -59
  127. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +1 -1
  128. package/dist/adapter/ezsp/adapter/ezspAdapter.js +629 -603
  129. package/dist/adapter/ezsp/adapter/ezspAdapter.js.map +1 -1
  130. package/dist/adapter/ezsp/adapter/index.d.ts +2 -2
  131. package/dist/adapter/ezsp/adapter/index.js +10 -10
  132. package/dist/adapter/ezsp/driver/commands.d.ts +36 -36
  133. package/dist/adapter/ezsp/driver/commands.d.ts.map +1 -1
  134. package/dist/adapter/ezsp/driver/commands.js +2388 -2359
  135. package/dist/adapter/ezsp/driver/commands.js.map +1 -1
  136. package/dist/adapter/ezsp/driver/consts.d.ts +10 -10
  137. package/dist/adapter/ezsp/driver/consts.js +13 -13
  138. package/dist/adapter/ezsp/driver/driver.d.ts +106 -103
  139. package/dist/adapter/ezsp/driver/driver.d.ts.map +1 -1
  140. package/dist/adapter/ezsp/driver/driver.js +731 -639
  141. package/dist/adapter/ezsp/driver/driver.js.map +1 -1
  142. package/dist/adapter/ezsp/driver/ezsp.d.ts +105 -96
  143. package/dist/adapter/ezsp/driver/ezsp.d.ts.map +1 -1
  144. package/dist/adapter/ezsp/driver/ezsp.js +651 -586
  145. package/dist/adapter/ezsp/driver/ezsp.js.map +1 -1
  146. package/dist/adapter/ezsp/driver/frame.d.ts +40 -0
  147. package/dist/adapter/ezsp/driver/frame.d.ts.map +1 -0
  148. package/dist/adapter/ezsp/driver/frame.js +101 -0
  149. package/dist/adapter/ezsp/driver/frame.js.map +1 -0
  150. package/dist/adapter/ezsp/driver/index.d.ts +3 -3
  151. package/dist/adapter/ezsp/driver/index.js +8 -8
  152. package/dist/adapter/ezsp/driver/multicast.d.ts +12 -12
  153. package/dist/adapter/ezsp/driver/multicast.d.ts.map +1 -1
  154. package/dist/adapter/ezsp/driver/multicast.js +77 -74
  155. package/dist/adapter/ezsp/driver/multicast.js.map +1 -1
  156. package/dist/adapter/ezsp/driver/parser.d.ts +11 -12
  157. package/dist/adapter/ezsp/driver/parser.d.ts.map +1 -1
  158. package/dist/adapter/ezsp/driver/parser.js +104 -111
  159. package/dist/adapter/ezsp/driver/parser.js.map +1 -1
  160. package/dist/adapter/ezsp/driver/types/basic.d.ts +62 -62
  161. package/dist/adapter/ezsp/driver/types/basic.js +208 -208
  162. package/dist/adapter/ezsp/driver/types/basic.js.map +1 -1
  163. package/dist/adapter/ezsp/driver/types/index.d.ts +9 -9
  164. package/dist/adapter/ezsp/driver/types/index.d.ts.map +1 -1
  165. package/dist/adapter/ezsp/driver/types/index.js +138 -133
  166. package/dist/adapter/ezsp/driver/types/index.js.map +1 -1
  167. package/dist/adapter/ezsp/driver/types/named.d.ts +1287 -697
  168. package/dist/adapter/ezsp/driver/types/named.d.ts.map +1 -1
  169. package/dist/adapter/ezsp/driver/types/named.js +2329 -1726
  170. package/dist/adapter/ezsp/driver/types/named.js.map +1 -1
  171. package/dist/adapter/ezsp/driver/types/struct.d.ts +270 -251
  172. package/dist/adapter/ezsp/driver/types/struct.d.ts.map +1 -1
  173. package/dist/adapter/ezsp/driver/types/struct.js +803 -708
  174. package/dist/adapter/ezsp/driver/types/struct.js.map +1 -1
  175. package/dist/adapter/ezsp/driver/uart.d.ts +48 -44
  176. package/dist/adapter/ezsp/driver/uart.d.ts.map +1 -1
  177. package/dist/adapter/ezsp/driver/uart.js +382 -368
  178. package/dist/adapter/ezsp/driver/uart.js.map +1 -1
  179. package/dist/adapter/ezsp/driver/utils/crc16ccitt.d.ts +2 -2
  180. package/dist/adapter/ezsp/driver/utils/crc16ccitt.js +55 -55
  181. package/dist/adapter/ezsp/driver/utils/crc16ccitt.js.map +1 -1
  182. package/dist/adapter/ezsp/driver/utils/index.d.ts +18 -18
  183. package/dist/adapter/ezsp/driver/utils/index.js +72 -67
  184. package/dist/adapter/ezsp/driver/utils/index.js.map +1 -1
  185. package/dist/adapter/ezsp/driver/writer.d.ts +13 -13
  186. package/dist/adapter/ezsp/driver/writer.d.ts.map +1 -1
  187. package/dist/adapter/ezsp/driver/writer.js +85 -88
  188. package/dist/adapter/ezsp/driver/writer.js.map +1 -1
  189. package/dist/adapter/index.d.ts +4 -4
  190. package/dist/adapter/index.js +35 -35
  191. package/dist/adapter/serialPort.d.ts +10 -8
  192. package/dist/adapter/serialPort.d.ts.map +1 -1
  193. package/dist/adapter/serialPort.js +53 -22
  194. package/dist/adapter/serialPort.js.map +1 -1
  195. package/dist/adapter/serialPortUtils.d.ts +12 -12
  196. package/dist/adapter/serialPortUtils.js +18 -18
  197. package/dist/adapter/serialPortUtils.js.map +1 -1
  198. package/dist/adapter/socketPortUtils.d.ts +10 -10
  199. package/dist/adapter/socketPortUtils.js +16 -16
  200. package/dist/adapter/tstype.d.ts +85 -85
  201. package/dist/adapter/tstype.d.ts.map +1 -1
  202. package/dist/adapter/tstype.js +2 -2
  203. package/dist/adapter/z-stack/adapter/adapter-backup.d.ts +62 -62
  204. package/dist/adapter/z-stack/adapter/adapter-backup.d.ts.map +1 -1
  205. package/dist/adapter/z-stack/adapter/adapter-backup.js +462 -460
  206. package/dist/adapter/z-stack/adapter/adapter-backup.js.map +1 -1
  207. package/dist/adapter/z-stack/adapter/adapter-nv-memory.d.ts +150 -150
  208. package/dist/adapter/z-stack/adapter/adapter-nv-memory.js +258 -258
  209. package/dist/adapter/z-stack/adapter/adapter-nv-memory.js.map +1 -1
  210. package/dist/adapter/z-stack/adapter/endpoints.d.ts +11 -11
  211. package/dist/adapter/z-stack/adapter/endpoints.js +73 -73
  212. package/dist/adapter/z-stack/adapter/index.d.ts +2 -2
  213. package/dist/adapter/z-stack/adapter/index.js +8 -8
  214. package/dist/adapter/z-stack/adapter/manager.d.ts +86 -86
  215. package/dist/adapter/z-stack/adapter/manager.d.ts.map +1 -1
  216. package/dist/adapter/z-stack/adapter/manager.js +482 -476
  217. package/dist/adapter/z-stack/adapter/manager.js.map +1 -1
  218. package/dist/adapter/z-stack/adapter/tstype.d.ts +6 -6
  219. package/dist/adapter/z-stack/adapter/tstype.js +9 -10
  220. package/dist/adapter/z-stack/adapter/tstype.js.map +1 -1
  221. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +81 -81
  222. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +1 -1
  223. package/dist/adapter/z-stack/adapter/zStackAdapter.js +891 -868
  224. package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
  225. package/dist/adapter/z-stack/constants/af.d.ts +23 -23
  226. package/dist/adapter/z-stack/constants/af.js +27 -27
  227. package/dist/adapter/z-stack/constants/common.d.ts +278 -278
  228. package/dist/adapter/z-stack/constants/common.d.ts.map +1 -1
  229. package/dist/adapter/z-stack/constants/common.js +292 -289
  230. package/dist/adapter/z-stack/constants/common.js.map +1 -1
  231. package/dist/adapter/z-stack/constants/dbg.d.ts +22 -22
  232. package/dist/adapter/z-stack/constants/dbg.js +24 -24
  233. package/dist/adapter/z-stack/constants/index.d.ts +10 -10
  234. package/dist/adapter/z-stack/constants/index.js +47 -47
  235. package/dist/adapter/z-stack/constants/mac.d.ts +127 -127
  236. package/dist/adapter/z-stack/constants/mac.js +129 -129
  237. package/dist/adapter/z-stack/constants/sapi.d.ts +24 -24
  238. package/dist/adapter/z-stack/constants/sapi.js +26 -26
  239. package/dist/adapter/z-stack/constants/sys.d.ts +71 -71
  240. package/dist/adapter/z-stack/constants/sys.js +73 -73
  241. package/dist/adapter/z-stack/constants/util.d.ts +81 -81
  242. package/dist/adapter/z-stack/constants/util.js +83 -83
  243. package/dist/adapter/z-stack/constants/utils.d.ts +4 -4
  244. package/dist/adapter/z-stack/constants/utils.js +14 -14
  245. package/dist/adapter/z-stack/constants/zdo.d.ts +102 -102
  246. package/dist/adapter/z-stack/constants/zdo.js +104 -104
  247. package/dist/adapter/z-stack/models/index.d.ts +1 -1
  248. package/dist/adapter/z-stack/models/index.js +17 -17
  249. package/dist/adapter/z-stack/models/startup-options.d.ts +12 -12
  250. package/dist/adapter/z-stack/models/startup-options.js +2 -2
  251. package/dist/adapter/z-stack/structs/entries/address-manager-entry.d.ts +23 -23
  252. package/dist/adapter/z-stack/structs/entries/address-manager-entry.js +45 -45
  253. package/dist/adapter/z-stack/structs/entries/address-manager-entry.js.map +1 -1
  254. package/dist/adapter/z-stack/structs/entries/address-manager-table.d.ts +10 -10
  255. package/dist/adapter/z-stack/structs/entries/address-manager-table.js +22 -22
  256. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.d.ts +10 -10
  257. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.js +21 -21
  258. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.d.ts +10 -10
  259. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.js +23 -23
  260. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.d.ts +10 -10
  261. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.js +24 -24
  262. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.d.ts +10 -10
  263. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.js +23 -23
  264. package/dist/adapter/z-stack/structs/entries/channel-list.d.ts +8 -8
  265. package/dist/adapter/z-stack/structs/entries/channel-list.js +15 -15
  266. package/dist/adapter/z-stack/structs/entries/has-configured.d.ts +8 -8
  267. package/dist/adapter/z-stack/structs/entries/has-configured.js +16 -16
  268. package/dist/adapter/z-stack/structs/entries/index.d.ts +16 -16
  269. package/dist/adapter/z-stack/structs/entries/index.js +32 -32
  270. package/dist/adapter/z-stack/structs/entries/nib.d.ts +10 -10
  271. package/dist/adapter/z-stack/structs/entries/nib.js +68 -68
  272. package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.d.ts +10 -10
  273. package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.js +18 -18
  274. package/dist/adapter/z-stack/structs/entries/nwk-key.d.ts +8 -8
  275. package/dist/adapter/z-stack/structs/entries/nwk-key.js +15 -15
  276. package/dist/adapter/z-stack/structs/entries/nwk-pan-id.d.ts +8 -8
  277. package/dist/adapter/z-stack/structs/entries/nwk-pan-id.js +15 -15
  278. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.d.ts +13 -13
  279. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.js +23 -23
  280. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.d.ts +10 -10
  281. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.js +22 -22
  282. package/dist/adapter/z-stack/structs/entries/security-manager-entry.d.ts +20 -20
  283. package/dist/adapter/z-stack/structs/entries/security-manager-entry.js +36 -36
  284. package/dist/adapter/z-stack/structs/entries/security-manager-entry.js.map +1 -1
  285. package/dist/adapter/z-stack/structs/entries/security-manager-table.d.ts +10 -10
  286. package/dist/adapter/z-stack/structs/entries/security-manager-table.js +24 -24
  287. package/dist/adapter/z-stack/structs/index.d.ts +4 -4
  288. package/dist/adapter/z-stack/structs/index.js +20 -20
  289. package/dist/adapter/z-stack/structs/serializable-memory-object.d.ts +13 -13
  290. package/dist/adapter/z-stack/structs/serializable-memory-object.js +2 -2
  291. package/dist/adapter/z-stack/structs/struct.d.ts +99 -99
  292. package/dist/adapter/z-stack/structs/struct.js +296 -295
  293. package/dist/adapter/z-stack/structs/struct.js.map +1 -1
  294. package/dist/adapter/z-stack/structs/table.d.ts +94 -94
  295. package/dist/adapter/z-stack/structs/table.js +163 -161
  296. package/dist/adapter/z-stack/structs/table.js.map +1 -1
  297. package/dist/adapter/z-stack/unpi/constants.d.ts +28 -28
  298. package/dist/adapter/z-stack/unpi/constants.js +39 -41
  299. package/dist/adapter/z-stack/unpi/constants.js.map +1 -1
  300. package/dist/adapter/z-stack/unpi/frame.d.ts +16 -16
  301. package/dist/adapter/z-stack/unpi/frame.js +54 -48
  302. package/dist/adapter/z-stack/unpi/frame.js.map +1 -1
  303. package/dist/adapter/z-stack/unpi/index.d.ts +5 -5
  304. package/dist/adapter/z-stack/unpi/index.js +37 -37
  305. package/dist/adapter/z-stack/unpi/parser.d.ts +10 -10
  306. package/dist/adapter/z-stack/unpi/parser.js +75 -74
  307. package/dist/adapter/z-stack/unpi/parser.js.map +1 -1
  308. package/dist/adapter/z-stack/unpi/writer.d.ts +10 -10
  309. package/dist/adapter/z-stack/unpi/writer.js +44 -44
  310. package/dist/adapter/z-stack/utils/channel-list.d.ts +20 -20
  311. package/dist/adapter/z-stack/utils/channel-list.js +40 -40
  312. package/dist/adapter/z-stack/utils/channel-list.js.map +1 -1
  313. package/dist/adapter/z-stack/utils/index.d.ts +2 -2
  314. package/dist/adapter/z-stack/utils/index.js +18 -18
  315. package/dist/adapter/z-stack/utils/network-options.d.ts +8 -8
  316. package/dist/adapter/z-stack/utils/network-options.js +22 -22
  317. package/dist/adapter/z-stack/znp/buffaloZnp.d.ts +11 -11
  318. package/dist/adapter/z-stack/znp/buffaloZnp.js +113 -113
  319. package/dist/adapter/z-stack/znp/buffaloZnp.js.map +1 -1
  320. package/dist/adapter/z-stack/znp/definition.d.ts +5 -5
  321. package/dist/adapter/z-stack/znp/definition.js +3050 -3050
  322. package/dist/adapter/z-stack/znp/index.d.ts +3 -3
  323. package/dist/adapter/z-stack/znp/index.js +10 -10
  324. package/dist/adapter/z-stack/znp/parameterType.d.ts +22 -22
  325. package/dist/adapter/z-stack/znp/parameterType.js +25 -25
  326. package/dist/adapter/z-stack/znp/tstype.d.ts +21 -21
  327. package/dist/adapter/z-stack/znp/tstype.js +2 -2
  328. package/dist/adapter/z-stack/znp/znp.d.ts +44 -43
  329. package/dist/adapter/z-stack/znp/znp.d.ts.map +1 -1
  330. package/dist/adapter/z-stack/znp/znp.js +326 -325
  331. package/dist/adapter/z-stack/znp/znp.js.map +1 -1
  332. package/dist/adapter/z-stack/znp/zpiObject.d.ts +19 -19
  333. package/dist/adapter/z-stack/znp/zpiObject.js +102 -96
  334. package/dist/adapter/z-stack/znp/zpiObject.js.map +1 -1
  335. package/dist/adapter/zigate/adapter/index.d.ts +2 -2
  336. package/dist/adapter/zigate/adapter/index.js +10 -10
  337. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +70 -69
  338. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +1 -1
  339. package/dist/adapter/zigate/adapter/zigateAdapter.js +689 -678
  340. package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
  341. package/dist/adapter/zigate/debug.d.ts +7 -7
  342. package/dist/adapter/zigate/debug.d.ts.map +1 -1
  343. package/dist/adapter/zigate/debug.js +19 -22
  344. package/dist/adapter/zigate/debug.js.map +1 -1
  345. package/dist/adapter/zigate/driver/buffaloZiGate.d.ts +18 -18
  346. package/dist/adapter/zigate/driver/buffaloZiGate.js +139 -139
  347. package/dist/adapter/zigate/driver/buffaloZiGate.js.map +1 -1
  348. package/dist/adapter/zigate/driver/commandType.d.ts +41 -41
  349. package/dist/adapter/zigate/driver/commandType.js +385 -385
  350. package/dist/adapter/zigate/driver/commandType.js.map +1 -1
  351. package/dist/adapter/zigate/driver/constants.d.ts +276 -276
  352. package/dist/adapter/zigate/driver/constants.d.ts.map +1 -1
  353. package/dist/adapter/zigate/driver/constants.js +371 -371
  354. package/dist/adapter/zigate/driver/constants.js.map +1 -1
  355. package/dist/adapter/zigate/driver/frame.d.ts +26 -26
  356. package/dist/adapter/zigate/driver/frame.js +172 -172
  357. package/dist/adapter/zigate/driver/frame.js.map +1 -1
  358. package/dist/adapter/zigate/driver/messageType.d.ts +11 -11
  359. package/dist/adapter/zigate/driver/messageType.js +278 -278
  360. package/dist/adapter/zigate/driver/messageType.js.map +1 -1
  361. package/dist/adapter/zigate/driver/parameterType.d.ts +20 -20
  362. package/dist/adapter/zigate/driver/parameterType.js +23 -23
  363. package/dist/adapter/zigate/driver/ziGateObject.d.ts +23 -23
  364. package/dist/adapter/zigate/driver/ziGateObject.js +110 -106
  365. package/dist/adapter/zigate/driver/ziGateObject.js.map +1 -1
  366. package/dist/adapter/zigate/driver/zigate.d.ts +49 -49
  367. package/dist/adapter/zigate/driver/zigate.d.ts.map +1 -1
  368. package/dist/adapter/zigate/driver/zigate.js +296 -303
  369. package/dist/adapter/zigate/driver/zigate.js.map +1 -1
  370. package/dist/buffalo/buffalo.d.ts +50 -50
  371. package/dist/buffalo/buffalo.js +324 -322
  372. package/dist/buffalo/buffalo.js.map +1 -1
  373. package/dist/buffalo/index.d.ts +3 -3
  374. package/dist/buffalo/index.js +33 -33
  375. package/dist/buffalo/tstype.d.ts +8 -8
  376. package/dist/buffalo/tstype.js +2 -2
  377. package/dist/controller/controller.d.ts +113 -113
  378. package/dist/controller/controller.d.ts.map +1 -1
  379. package/dist/controller/controller.js +641 -619
  380. package/dist/controller/controller.js.map +1 -1
  381. package/dist/controller/database.d.ts +18 -18
  382. package/dist/controller/database.js +96 -93
  383. package/dist/controller/database.js.map +1 -1
  384. package/dist/controller/events.d.ts +58 -58
  385. package/dist/controller/events.d.ts.map +1 -1
  386. package/dist/controller/events.js +108 -101
  387. package/dist/controller/events.js.map +1 -1
  388. package/dist/controller/greenPower.d.ts +12 -12
  389. package/dist/controller/greenPower.js +221 -220
  390. package/dist/controller/greenPower.js.map +1 -1
  391. package/dist/controller/helpers/index.d.ts +2 -2
  392. package/dist/controller/helpers/index.js +28 -28
  393. package/dist/controller/helpers/request.d.ts +21 -22
  394. package/dist/controller/helpers/request.d.ts.map +1 -1
  395. package/dist/controller/helpers/request.js +77 -71
  396. package/dist/controller/helpers/request.js.map +1 -1
  397. package/dist/controller/helpers/requestQueue.d.ts +13 -0
  398. package/dist/controller/helpers/requestQueue.d.ts.map +1 -0
  399. package/dist/controller/helpers/requestQueue.js +116 -0
  400. package/dist/controller/helpers/requestQueue.js.map +1 -0
  401. package/dist/controller/helpers/zclFrameConverter.d.ts +7 -7
  402. package/dist/controller/helpers/zclFrameConverter.d.ts.map +1 -1
  403. package/dist/controller/helpers/zclFrameConverter.js +50 -31
  404. package/dist/controller/helpers/zclFrameConverter.js.map +1 -1
  405. package/dist/controller/helpers/zclTransactionSequenceNumber.d.ts +5 -5
  406. package/dist/controller/helpers/zclTransactionSequenceNumber.js +13 -13
  407. package/dist/controller/helpers/zclTransactionSequenceNumber.js.map +1 -1
  408. package/dist/controller/index.d.ts +5 -5
  409. package/dist/controller/index.js +8 -8
  410. package/dist/controller/logger-stub.d.ts +6 -6
  411. package/dist/controller/logger-stub.js +2 -2
  412. package/dist/controller/model/device.d.ts +132 -133
  413. package/dist/controller/model/device.d.ts.map +1 -1
  414. package/dist/controller/model/device.js +724 -717
  415. package/dist/controller/model/device.js.map +1 -1
  416. package/dist/controller/model/endpoint.d.ts +128 -131
  417. package/dist/controller/model/endpoint.d.ts.map +1 -1
  418. package/dist/controller/model/endpoint.js +755 -816
  419. package/dist/controller/model/endpoint.js.map +1 -1
  420. package/dist/controller/model/entity.d.ts +14 -14
  421. package/dist/controller/model/entity.js +26 -26
  422. package/dist/controller/model/entity.js.map +1 -1
  423. package/dist/controller/model/group.d.ts +38 -38
  424. package/dist/controller/model/group.d.ts.map +1 -1
  425. package/dist/controller/model/group.js +225 -221
  426. package/dist/controller/model/group.js.map +1 -1
  427. package/dist/controller/model/index.d.ts +5 -5
  428. package/dist/controller/model/index.js +14 -14
  429. package/dist/controller/touchlink.d.ts +19 -19
  430. package/dist/controller/touchlink.js +159 -157
  431. package/dist/controller/touchlink.js.map +1 -1
  432. package/dist/controller/tstype.d.ts +20 -21
  433. package/dist/controller/tstype.d.ts.map +1 -1
  434. package/dist/controller/tstype.js +8 -9
  435. package/dist/controller/tstype.js.map +1 -1
  436. package/dist/index.d.ts +3 -3
  437. package/dist/index.js +33 -33
  438. package/dist/models/backup-storage-legacy.d.ts +26 -26
  439. package/dist/models/backup-storage-legacy.js +2 -2
  440. package/dist/models/backup-storage-unified.d.ts +49 -49
  441. package/dist/models/backup-storage-unified.js +2 -2
  442. package/dist/models/backup.d.ts +37 -37
  443. package/dist/models/backup.js +2 -2
  444. package/dist/models/index.d.ts +4 -4
  445. package/dist/models/index.js +20 -20
  446. package/dist/models/network-options.d.ts +12 -12
  447. package/dist/models/network-options.js +2 -2
  448. package/dist/utils/assertString.d.ts +2 -2
  449. package/dist/utils/assertString.js +8 -8
  450. package/dist/utils/assertString.js.map +1 -1
  451. package/dist/utils/backup.d.ts +20 -20
  452. package/dist/utils/backup.d.ts.map +1 -1
  453. package/dist/utils/backup.js +189 -187
  454. package/dist/utils/backup.js.map +1 -1
  455. package/dist/utils/equalsPartial.d.ts +2 -2
  456. package/dist/utils/equalsPartial.js +11 -11
  457. package/dist/utils/index.d.ts +9 -9
  458. package/dist/utils/index.js +45 -45
  459. package/dist/utils/isNumberArray.d.ts +2 -2
  460. package/dist/utils/isNumberArray.js +6 -6
  461. package/dist/utils/queue.d.ts +11 -11
  462. package/dist/utils/queue.d.ts.map +1 -1
  463. package/dist/utils/queue.js +61 -50
  464. package/dist/utils/queue.js.map +1 -1
  465. package/dist/utils/realpathSync.d.ts +2 -2
  466. package/dist/utils/realpathSync.js +12 -12
  467. package/dist/utils/wait.d.ts +2 -2
  468. package/dist/utils/wait.js +8 -8
  469. package/dist/utils/waitress.d.ts +21 -21
  470. package/dist/utils/waitress.d.ts.map +1 -1
  471. package/dist/utils/waitress.js +68 -61
  472. package/dist/utils/waitress.js.map +1 -1
  473. package/dist/zcl/buffaloZcl.d.ts +41 -41
  474. package/dist/zcl/buffaloZcl.d.ts.map +1 -1
  475. package/dist/zcl/buffaloZcl.js +594 -591
  476. package/dist/zcl/buffaloZcl.js.map +1 -1
  477. package/dist/zcl/definition/buffaloZclDataType.d.ts +17 -17
  478. package/dist/zcl/definition/buffaloZclDataType.js +20 -20
  479. package/dist/zcl/definition/cluster.d.ts +29 -29
  480. package/dist/zcl/definition/cluster.d.ts.map +1 -1
  481. package/dist/zcl/definition/cluster.js +5520 -5335
  482. package/dist/zcl/definition/cluster.js.map +1 -1
  483. package/dist/zcl/definition/dataType.d.ts +59 -59
  484. package/dist/zcl/definition/dataType.js +64 -64
  485. package/dist/zcl/definition/direction.d.ts +5 -5
  486. package/dist/zcl/definition/direction.js +8 -8
  487. package/dist/zcl/definition/endpointDeviceType.d.ts +4 -4
  488. package/dist/zcl/definition/endpointDeviceType.js +15 -15
  489. package/dist/zcl/definition/foundation.d.ts +11 -11
  490. package/dist/zcl/definition/foundation.js +167 -167
  491. package/dist/zcl/definition/frameControl.d.ts +10 -10
  492. package/dist/zcl/definition/frameControl.js +2 -2
  493. package/dist/zcl/definition/frameType.d.ts +5 -5
  494. package/dist/zcl/definition/frameType.js +8 -8
  495. package/dist/zcl/definition/index.d.ts +13 -13
  496. package/dist/zcl/definition/index.js +51 -51
  497. package/dist/zcl/definition/manufacturerCode.d.ts +1077 -1074
  498. package/dist/zcl/definition/manufacturerCode.d.ts.map +1 -1
  499. package/dist/zcl/definition/manufacturerCode.js +1082 -1079
  500. package/dist/zcl/definition/manufacturerCode.js.map +1 -1
  501. package/dist/zcl/definition/powerSource.d.ts +4 -4
  502. package/dist/zcl/definition/powerSource.js +12 -12
  503. package/dist/zcl/definition/status.d.ts +38 -38
  504. package/dist/zcl/definition/status.js +41 -41
  505. package/dist/zcl/definition/tstype.d.ts +16 -16
  506. package/dist/zcl/definition/tstype.js +2 -2
  507. package/dist/zcl/index.d.ts +16 -15
  508. package/dist/zcl/index.d.ts.map +1 -1
  509. package/dist/zcl/index.js +55 -55
  510. package/dist/zcl/index.js.map +1 -1
  511. package/dist/zcl/tstype.d.ts +56 -56
  512. package/dist/zcl/tstype.js +9 -10
  513. package/dist/zcl/tstype.js.map +1 -1
  514. package/dist/zcl/utils.d.ts +6 -6
  515. package/dist/zcl/utils.js +164 -165
  516. package/dist/zcl/utils.js.map +1 -1
  517. package/dist/zcl/zclFrame.d.ts +40 -45
  518. package/dist/zcl/zclFrame.d.ts.map +1 -1
  519. package/dist/zcl/zclFrame.js +351 -347
  520. package/dist/zcl/zclFrame.js.map +1 -1
  521. package/dist/zcl/zclHeader.d.ts +9 -0
  522. package/dist/zcl/zclHeader.d.ts.map +1 -0
  523. package/dist/zcl/zclHeader.js +3 -0
  524. package/dist/zcl/zclHeader.js.map +1 -0
  525. package/dist/zcl/zclStatusError.d.ts +5 -5
  526. package/dist/zcl/zclStatusError.js +14 -13
  527. package/dist/zcl/zclStatusError.js.map +1 -1
  528. package/package.json +11 -11
  529. package/release-please-config.json +1 -5
  530. package/tsconfig.json +4 -2
@@ -0,0 +1,1584 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.UartAsh = exports.AshEvents = void 0;
7
+ /* istanbul ignore file */
8
+ const debug_1 = __importDefault(require("debug"));
9
+ const stream_1 = require("stream");
10
+ const net_1 = require("net");
11
+ const socketPortUtils_1 = __importDefault(require("../../socketPortUtils"));
12
+ const serialPort_1 = require("../../serialPort");
13
+ const consts_1 = require("./consts");
14
+ const math_1 = require("../utils/math");
15
+ const enums_1 = require("../enums");
16
+ const enums_2 = require("./enums");
17
+ const queues_1 = require("./queues");
18
+ const writer_1 = require("./writer");
19
+ const parser_1 = require("./parser");
20
+ const utils_1 = require("../../../utils");
21
+ const debug = (0, debug_1.default)('zigbee-herdsman:adapter:ember:uart:ash');
22
+ /** ASH get rflag in control byte */
23
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
24
+ const ashGetRFlag = (ctrl) => ((ctrl & consts_1.ASH_RFLAG_MASK) >> consts_1.ASH_RFLAG_BIT);
25
+ /** ASH get nflag in control byte */
26
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
27
+ const ashGetNFlag = (ctrl) => ((ctrl & consts_1.ASH_NFLAG_MASK) >> consts_1.ASH_NFLAG_BIT);
28
+ /** ASH get frmnum in control byte */
29
+ const ashGetFrmNum = (ctrl) => ((ctrl & consts_1.ASH_FRMNUM_MASK) >> consts_1.ASH_FRMNUM_BIT);
30
+ /** ASH get acknum in control byte */
31
+ const ashGetACKNum = (ctrl) => ((ctrl & consts_1.ASH_ACKNUM_MASK) >> consts_1.ASH_ACKNUM_BIT);
32
+ var AshEvents;
33
+ (function (AshEvents) {
34
+ /** When the host detects a fatal error */
35
+ AshEvents["hostError"] = "hostError";
36
+ /** When the NCP reports a fatal error */
37
+ AshEvents["ncpError"] = "ncpError";
38
+ /** When a frame has been parsed and queued in the rxQueue. */
39
+ AshEvents["frame"] = "frame";
40
+ })(AshEvents || (exports.AshEvents = AshEvents = {}));
41
+ var SendState;
42
+ (function (SendState) {
43
+ SendState[SendState["IDLE"] = 0] = "IDLE";
44
+ SendState[SendState["SHFRAME"] = 1] = "SHFRAME";
45
+ SendState[SendState["TX_DATA"] = 2] = "TX_DATA";
46
+ SendState[SendState["RETX_DATA"] = 3] = "RETX_DATA";
47
+ })(SendState || (SendState = {}));
48
+ // Bits in ashFlags
49
+ var Flag;
50
+ (function (Flag) {
51
+ /** Reject Condition */
52
+ Flag[Flag["REJ"] = 1] = "REJ";
53
+ /** Retransmit Condition */
54
+ Flag[Flag["RETX"] = 2] = "RETX";
55
+ /** send NAK */
56
+ Flag[Flag["NAK"] = 4] = "NAK";
57
+ /** send ACK */
58
+ Flag[Flag["ACK"] = 8] = "ACK";
59
+ /** send RST */
60
+ Flag[Flag["RST"] = 16] = "RST";
61
+ /** send immediate CAN */
62
+ Flag[Flag["CAN"] = 32] = "CAN";
63
+ /** in CONNECTED state, else ERROR */
64
+ Flag[Flag["CONNECTED"] = 64] = "CONNECTED";
65
+ /** not ready to receive DATA frames */
66
+ Flag[Flag["NR"] = 256] = "NR";
67
+ /** last transmitted NR status */
68
+ Flag[Flag["NRTX"] = 512] = "NRTX";
69
+ })(Flag || (Flag = {}));
70
+ /** max frames sent without being ACKed (1-7) */
71
+ const CONFIG_TX_K = 3;
72
+ /** enables randomizing DATA frame payloads */
73
+ const CONFIG_RANDOMIZE = true;
74
+ /** adaptive rec'd ACK timeout initial value */
75
+ const CONFIG_ACK_TIME_INIT = 800;
76
+ /** " " " " " minimum value */
77
+ const CONFIG_ACK_TIME_MIN = 400;
78
+ /** " " " " " maximum value */
79
+ const CONFIG_ACK_TIME_MAX = 2400;
80
+ /** time allowed to receive RSTACK after ncp is reset */
81
+ const CONFIG_TIME_RST = 2500;
82
+ /** time between checks for received RSTACK (CONNECTED status) */
83
+ const CONFIG_TIME_RST_CHECK = 100;
84
+ /** if free buffers < limit, host receiver isn't ready, will hold off the ncp from sending normal priority frames */
85
+ const CONFIG_NR_LOW_LIMIT = 8; // RX_FREE_LW
86
+ /** if free buffers > limit, host receiver is ready */
87
+ const CONFIG_NR_HIGH_LIMIT = 12; // RX_FREE_HW
88
+ /** time until a set nFlag must be resent (max 2032) */
89
+ const CONFIG_NR_TIME = 480;
90
+ /** Read/write max bytes count at stream level */
91
+ const CONFIG_HIGHWATER_MARK = 256;
92
+ /**
93
+ * ASH Protocol handler.
94
+ */
95
+ class UartAsh extends stream_1.EventEmitter {
96
+ portOptions;
97
+ serialPort;
98
+ socketPort;
99
+ writer;
100
+ parser;
101
+ /** True when serial/socket is currently closing. */
102
+ closing;
103
+ /** time ackTimer started: 0 means not ready uint16_t */
104
+ ackTimer;
105
+ /** time used to check ackTimer expiry (msecs) uint16_t */
106
+ ackPeriod;
107
+ /** not ready timer (16 msec units). Set to (now + config.nrTime) when started. uint8_t */
108
+ nrTimer;
109
+ /** frame decode in progress */
110
+ decodeInProgress;
111
+ // Variables used in encoding frames
112
+ /** true when preceding byte was escaped */
113
+ encodeEscFlag;
114
+ /** byte to send after ASH_ESC uint8_t */
115
+ encodeFlip;
116
+ /** uint16_t */
117
+ encodeCrc;
118
+ /** encoder state: 0 = control/data bytes, 1 = crc low byte, 2 = crc high byte, 3 = flag. uint8_t */
119
+ encodeState;
120
+ /** bytes remaining to encode. uint8_t */
121
+ encodeCount;
122
+ // Variables used in decoding frames
123
+ /** bytes in frame, plus CRC, clamped to limit +1: high values also used to record certain errors. uint8_t */
124
+ decodeLen;
125
+ /** ASH_FLIP if previous byte was ASH_ESC. uint8_t */
126
+ decodeFlip;
127
+ /** a 2 byte queue to avoid outputting crc bytes. uint8_t */
128
+ decodeByte1;
129
+ /** at frame end, they contain the received crc. uint8_t */
130
+ decodeByte2;
131
+ /** uint16_t */
132
+ decodeCrc;
133
+ /** outgoing short frames */
134
+ txSHBuffer;
135
+ /** incoming short frames */
136
+ rxSHBuffer;
137
+ /** bit flags for top-level logic. uint16_t */
138
+ flags;
139
+ /** frame ack'ed from remote peer. uint8_t */
140
+ ackRx;
141
+ /** frame ack'ed to remote peer. uint8_t */
142
+ ackTx;
143
+ /** next frame to be transmitted. uint8_t */
144
+ frmTx;
145
+ /** next frame to be retransmitted. uint8_t */
146
+ frmReTx;
147
+ /** next frame expected to be rec'd. uint8_t */
148
+ frmRx;
149
+ /** frame at retx queue's head. uint8_t */
150
+ frmReTxHead;
151
+ /** consecutive timeout counter. uint8_t */
152
+ timeouts;
153
+ /** rec'd DATA frame buffer. uint8_t */
154
+ rxDataBuffer;
155
+ /** rec'd frame length. uint8_t */
156
+ rxLen;
157
+ /** tx frame offset. uint8_t */
158
+ txOffset;
159
+ counters;
160
+ /**
161
+ * Errors reported by the NCP.
162
+ * The `NcpFailedCode` from the frame reporting this is logged before this is set to make it clear where it failed:
163
+ * - The NCP sent an ERROR frame during the initial reset sequence (before CONNECTED state)
164
+ * - The NCP sent an ERROR frame
165
+ * - The NCP sent an unexpected RSTACK
166
+ */
167
+ ncpError;
168
+ /** Errors reported by the Host. */
169
+ hostError;
170
+ /** sendExec() state variable */
171
+ sendState;
172
+ /** NCP is enabled to sleep, set by EZSP, not supported atm, always false */
173
+ ncpSleepEnabled;
174
+ /**
175
+ * Set when the ncp has indicated it has a pending callback by seting the callback flag in the frame control byte
176
+ * or (uart version only) by sending an an ASH_WAKE byte between frames.
177
+ */
178
+ ncpHasCallbacks;
179
+ /** Transmit buffers */
180
+ txPool;
181
+ txQueue;
182
+ reTxQueue;
183
+ txFree;
184
+ /** Receive buffers */
185
+ rxPool;
186
+ rxQueue;
187
+ rxFree;
188
+ constructor(options) {
189
+ super();
190
+ this.portOptions = options;
191
+ this.serialPort = null;
192
+ this.socketPort = null;
193
+ this.writer = null;
194
+ this.parser = null;
195
+ this.txPool = new Array(consts_1.TX_POOL_BUFFERS);
196
+ this.txQueue = new queues_1.EzspQueue();
197
+ this.reTxQueue = new queues_1.EzspQueue();
198
+ this.txFree = new queues_1.EzspFreeList();
199
+ this.rxPool = new Array(consts_1.EZSP_HOST_RX_POOL_SIZE);
200
+ this.rxQueue = new queues_1.EzspQueue();
201
+ this.rxFree = new queues_1.EzspFreeList();
202
+ }
203
+ /**
204
+ * Check if port is valid, open, and not closing.
205
+ */
206
+ get portOpen() {
207
+ if (this.closing) {
208
+ return false;
209
+ }
210
+ return this.serialPort != null ? this.serialPort.isOpen : !this.socketPort?.closed;
211
+ }
212
+ /**
213
+ * Get max wait time before response is considered timed out.
214
+ */
215
+ get responseTimeout() {
216
+ return consts_1.ASH_MAX_TIMEOUTS * CONFIG_ACK_TIME_MAX;
217
+ }
218
+ /**
219
+ * Indicates if the host is in the Connected state.
220
+ * If not, the host and NCP cannot exchange DATA frames.
221
+ * Note that this function does not actively confirm that communication with NCP is healthy, but simply returns its last known status.
222
+ *
223
+ * @returns
224
+ * - true - host and NCP can exchange DATA frames
225
+ * - false - host and NCP cannot now exchange DATA frames
226
+ */
227
+ get connected() {
228
+ return ((this.flags & Flag.CONNECTED) !== 0);
229
+ }
230
+ /**
231
+ * Has nothing to do...
232
+ */
233
+ get idle() {
234
+ return (!this.decodeInProgress // don't have a partial frame
235
+ // && (this.serial.readAvailable() === EzspStatus.NO_RX_DATA) // no rx data
236
+ && this.rxQueue.empty // no rx frames to process
237
+ && !this.ncpHasCallbacks // no pending callbacks
238
+ && (this.flags === Flag.CONNECTED) // no pending ACKs, NAKs, etc.
239
+ && (this.ackTx === this.frmRx) // do not need to send an ACK
240
+ && (this.ackRx === this.frmTx) // not waiting to receive an ACK
241
+ && (this.sendState === SendState.IDLE) // nothing being transmitted now
242
+ && this.txQueue.empty // nothing waiting to transmit
243
+ // && this.serial.outputIsIdle() // nothing in OS buffers or UART FIFO
244
+ );
245
+ }
246
+ /**
247
+ * Initialize ASH variables, timers and queues, but not the serial port
248
+ */
249
+ initVariables() {
250
+ this.closing = false;
251
+ this.serialPort = null;
252
+ this.socketPort = null;
253
+ this.writer = null;
254
+ this.parser = null;
255
+ this.txSHBuffer = Buffer.alloc(consts_1.SH_TX_BUFFER_LEN);
256
+ this.rxSHBuffer = Buffer.alloc(consts_1.SH_RX_BUFFER_LEN);
257
+ this.ackTimer = 0;
258
+ this.ackPeriod = 0;
259
+ this.nrTimer = 0;
260
+ this.flags = 0;
261
+ this.decodeInProgress = false;
262
+ this.ackRx = 0;
263
+ this.ackTx = 0;
264
+ this.frmTx = 0;
265
+ this.frmReTx = 0;
266
+ this.frmRx = 0;
267
+ this.frmReTxHead = 0;
268
+ this.timeouts = 0;
269
+ this.rxDataBuffer = null;
270
+ this.rxLen = 0;
271
+ // init to "start of frame" default
272
+ this.encodeCount = 0;
273
+ this.encodeState = 0;
274
+ this.encodeEscFlag = false;
275
+ this.encodeCrc = 0xFFFF;
276
+ this.txOffset = 0;
277
+ // init to "start of frame" default
278
+ this.decodeLen = 0;
279
+ this.decodeByte1 = 0;
280
+ this.decodeByte2 = 0;
281
+ this.decodeFlip = 0;
282
+ this.decodeCrc = 0xFFFF;
283
+ this.ncpError = enums_1.EzspStatus.NO_ERROR;
284
+ this.hostError = enums_1.EzspStatus.NO_ERROR;
285
+ this.sendState = SendState.IDLE;
286
+ this.ncpSleepEnabled = false;
287
+ this.ncpHasCallbacks = false;
288
+ this.stopAckTimer();
289
+ this.stopNrTimer();
290
+ this.initQueues();
291
+ this.counters = {
292
+ txData: 0,
293
+ txAllFrames: 0,
294
+ txDataFrames: 0,
295
+ txAckFrames: 0,
296
+ txNakFrames: 0,
297
+ txReDataFrames: 0,
298
+ // txN0Frames: 0,
299
+ txN1Frames: 0,
300
+ txCancelled: 0,
301
+ rxData: 0,
302
+ rxAllFrames: 0,
303
+ rxDataFrames: 0,
304
+ rxAckFrames: 0,
305
+ rxNakFrames: 0,
306
+ rxReDataFrames: 0,
307
+ // rxN0Frames: 0,
308
+ rxN1Frames: 0,
309
+ rxCancelled: 0,
310
+ rxCrcErrors: 0,
311
+ rxCommErrors: 0,
312
+ rxTooShort: 0,
313
+ rxTooLong: 0,
314
+ rxBadControl: 0,
315
+ rxBadLength: 0,
316
+ rxBadAckNumber: 0,
317
+ rxNoBuffer: 0,
318
+ rxDuplicates: 0,
319
+ rxOutOfSequence: 0,
320
+ rxAckTimeouts: 0,
321
+ };
322
+ }
323
+ /**
324
+ * Initializes all queues and free lists.
325
+ * All receive buffers are put into rxFree, and rxQueue is empty.
326
+ * All transmit buffers are put into txFree, and txQueue and reTxQueue are empty.
327
+ */
328
+ initQueues() {
329
+ this.txQueue.tail = null;
330
+ this.reTxQueue.tail = null;
331
+ this.txFree.link = null;
332
+ for (let i = 0; i < consts_1.TX_POOL_BUFFERS; i++) {
333
+ this.txFree.freeBuffer(this.txPool[i] = new queues_1.EzspBuffer());
334
+ }
335
+ this.rxQueue.tail = null;
336
+ this.rxFree.link = null;
337
+ for (let i = 0; i < consts_1.EZSP_HOST_RX_POOL_SIZE; i++) {
338
+ this.rxFree.freeBuffer(this.rxPool[i] = new queues_1.EzspBuffer());
339
+ }
340
+ }
341
+ async initPort() {
342
+ if (!socketPortUtils_1.default.isTcpPath(this.portOptions.path)) {
343
+ if (this.serialPort != null) {
344
+ this.serialPort.close();
345
+ }
346
+ const serialOpts = {
347
+ path: this.portOptions.path,
348
+ baudRate: typeof this.portOptions.baudRate === 'number' ? this.portOptions.baudRate : 115200,
349
+ rtscts: typeof this.portOptions.rtscts === 'boolean' ? this.portOptions.rtscts : false,
350
+ autoOpen: false,
351
+ parity: 'none',
352
+ stopBits: 1,
353
+ xon: false,
354
+ xoff: false,
355
+ };
356
+ // enable software flow control if RTS/CTS not enabled in config
357
+ if (!serialOpts.rtscts) {
358
+ debug(`RTS/CTS config is off, enabling software flow control.`);
359
+ serialOpts.xon = true;
360
+ serialOpts.xoff = true;
361
+ }
362
+ //@ts-expect-error Jest testing
363
+ if (this.portOptions.binding != null) {
364
+ //@ts-expect-error Jest testing
365
+ serialOpts.binding = this.portOptions.binding;
366
+ }
367
+ debug(`Opening SerialPort with ${JSON.stringify(serialOpts)}`);
368
+ this.serialPort = new serialPort_1.SerialPort(serialOpts);
369
+ this.writer = new writer_1.AshWriter({ highWaterMark: CONFIG_HIGHWATER_MARK });
370
+ this.writer.pipe(this.serialPort);
371
+ this.parser = new parser_1.AshParser({ readableHighWaterMark: CONFIG_HIGHWATER_MARK });
372
+ this.serialPort.pipe(this.parser);
373
+ this.parser.on('data', this.onFrame.bind(this));
374
+ try {
375
+ await this.serialPort.asyncOpen();
376
+ debug('Serialport opened');
377
+ this.serialPort.once('close', this.onPortClose.bind(this));
378
+ this.serialPort.on('error', this.onPortError.bind(this));
379
+ }
380
+ catch (error) {
381
+ await this.stop();
382
+ throw error;
383
+ }
384
+ }
385
+ else {
386
+ if (this.socketPort != null) {
387
+ this.socketPort.destroy();
388
+ }
389
+ const info = socketPortUtils_1.default.parseTcpPath(this.portOptions.path);
390
+ debug(`Opening TCP socket with ${info.host}:${info.port}`);
391
+ this.socketPort = new net_1.Socket();
392
+ this.socketPort.setNoDelay(true);
393
+ this.socketPort.setKeepAlive(true, 15000);
394
+ this.writer = new writer_1.AshWriter({ highWaterMark: CONFIG_HIGHWATER_MARK });
395
+ this.writer.pipe(this.socketPort);
396
+ this.parser = new parser_1.AshParser({ readableHighWaterMark: CONFIG_HIGHWATER_MARK });
397
+ this.socketPort.pipe(this.parser);
398
+ this.parser.on('data', this.onFrame.bind(this));
399
+ return new Promise((resolve, reject) => {
400
+ const openError = async (err) => {
401
+ await this.stop();
402
+ reject(err);
403
+ };
404
+ this.socketPort.on('connect', () => {
405
+ debug('Socket connected');
406
+ });
407
+ this.socketPort.on('ready', async () => {
408
+ debug('Socket ready');
409
+ this.socketPort.removeListener('error', openError);
410
+ this.socketPort.once('close', this.onPortClose.bind(this));
411
+ this.socketPort.on('error', this.onPortError.bind(this));
412
+ resolve();
413
+ });
414
+ this.socketPort.once('error', openError);
415
+ this.socketPort.connect(info.port, info.host);
416
+ });
417
+ }
418
+ }
419
+ /**
420
+ * Handle port closing
421
+ * @param err A boolean for Socket, an Error for serialport
422
+ */
423
+ async onPortClose(err) {
424
+ console.log(`Port closed. Error? ${err ?? 'no'}`);
425
+ }
426
+ /**
427
+ * Handle port error
428
+ * @param error
429
+ */
430
+ async onPortError(error) {
431
+ console.log(`Port error: ${error}`);
432
+ this.hostDisconnect(enums_1.EzspStatus.ERROR_SERIAL_INIT);
433
+ await this.stop();
434
+ }
435
+ /**
436
+ * Handle received frame from AshParser.
437
+ * @param buf
438
+ */
439
+ onFrame(buffer) {
440
+ const iCAN = buffer.lastIndexOf(enums_2.AshReservedByte.CANCEL); // should only be one, but just in case...
441
+ if (iCAN !== -1) {
442
+ // ignore the cancel before RSTACK
443
+ if (this.flags & Flag.CONNECTED) {
444
+ this.counters.rxCancelled += 1;
445
+ console.warn(`Frame(s) in progress cancelled in [${buffer.toString('hex')}]`);
446
+ }
447
+ // get rid of everything up to the CAN flag and start reading frame from there, no need to loop through bytes in vain
448
+ buffer = buffer.subarray(iCAN + 1);
449
+ }
450
+ if (!buffer.length) {
451
+ // skip any CANCEL that results in empty frame (have yet to see one, but just in case...)
452
+ // shouldn't happen for any other reason, unless receiving bad stuff from port?
453
+ debug(`Received empty frame. Skipping.`);
454
+ return;
455
+ }
456
+ const status = this.receiveFrame(buffer);
457
+ if (status === enums_1.EzspStatus.SUCCESS) {
458
+ // ?
459
+ }
460
+ else if ((status !== enums_1.EzspStatus.ASH_IN_PROGRESS) && (status !== enums_1.EzspStatus.NO_RX_DATA)) {
461
+ throw new Error(enums_1.EzspStatus[status]);
462
+ }
463
+ }
464
+ /**
465
+ * Initializes the ASH protocol, and waits until the NCP finishes rebooting, or a non-recoverable error occurs.
466
+ *
467
+ * @returns
468
+ * - EzspStatus.SUCCESS
469
+ * - EzspStatus.HOST_FATAL_ERROR
470
+ * - EzspStatus.ASH_NCP_FATAL_ERROR)
471
+ */
472
+ async start() {
473
+ if (this.closing || (this.flags & Flag.CONNECTED)) {
474
+ return enums_1.EzspStatus.ERROR_INVALID_CALL;
475
+ }
476
+ console.log(`======== ASH starting ========`);
477
+ if (this.serialPort != null) {
478
+ this.serialPort.flush(); // clear read/write buffers
479
+ }
480
+ else {
481
+ // XXX: Socket equiv?
482
+ }
483
+ this.sendExec();
484
+ // block til RSTACK or timeout
485
+ for (let i = 0; i < CONFIG_TIME_RST; i += CONFIG_TIME_RST_CHECK) {
486
+ if ((this.flags & Flag.CONNECTED)) {
487
+ console.log(`======== ASH started ========`);
488
+ return enums_1.EzspStatus.SUCCESS;
489
+ }
490
+ debug(`Waiting for RSTACK... ${i}/${CONFIG_TIME_RST}`);
491
+ await (0, utils_1.Wait)(CONFIG_TIME_RST_CHECK);
492
+ }
493
+ return enums_1.EzspStatus.HOST_FATAL_ERROR;
494
+ }
495
+ /**
496
+ * Stops the ASH protocol - flushes and closes the serial port, clears all queues, stops timers, etc.
497
+ */
498
+ async stop() {
499
+ this.closing = true;
500
+ this.printCounters();
501
+ if (this.serialPort?.isOpen) {
502
+ try {
503
+ await this.serialPort.asyncFlushAndClose();
504
+ debug(`Serial port closed.`);
505
+ }
506
+ catch (err) {
507
+ debug(`Failed to close serial port ${err}.`);
508
+ }
509
+ this.serialPort.removeAllListeners();
510
+ }
511
+ else if (this.socketPort != null && !this.socketPort.closed) {
512
+ this.socketPort.destroy();
513
+ this.socketPort.removeAllListeners();
514
+ debug(`Socket port closed.`);
515
+ }
516
+ this.initVariables();
517
+ console.log(`======== ASH stopped ========`);
518
+ }
519
+ /**
520
+ * Initializes the ASH serial port and (if enabled) resets the NCP.
521
+ * The method used to do the reset is specified by the the host configuration parameter resetMethod.
522
+ *
523
+ * When the reset method is sending a RST frame, the caller should retry NCP resets a few times if it fails.
524
+ *
525
+ * @returns
526
+ * - EzspStatus.SUCCESS
527
+ * - EzspStatus.HOST_FATAL_ERROR
528
+ */
529
+ async resetNcp() {
530
+ if (this.closing) {
531
+ return enums_1.EzspStatus.ERROR_INVALID_CALL;
532
+ }
533
+ console.log(`======== ASH NCP reset ========`);
534
+ this.initVariables();
535
+ let status;
536
+ // ask ncp to reset itself using RST frame
537
+ try {
538
+ await this.initPort();
539
+ this.flags = Flag.RST | Flag.CAN;
540
+ return enums_1.EzspStatus.SUCCESS;
541
+ }
542
+ catch (err) {
543
+ this.hostError = status;
544
+ return enums_1.EzspStatus.HOST_FATAL_ERROR;
545
+ }
546
+ }
547
+ /**
548
+ * Adds a DATA frame to the transmit queue to send to the NCP.
549
+ * Frames that are too long or too short will not be sent, and frames will not be added to the queue
550
+ * if the host is not in the Connected state, or the NCP is not ready to receive a DATA frame or if there
551
+ * is no room in the queue;
552
+ *
553
+ * @param len length of data field
554
+ * @param inBuf array containing the data to be sent
555
+ *
556
+ * @returns
557
+ * - EzspStatus.SUCCESS
558
+ * - EzspStatus.NO_TX_SPACE
559
+ * - EzspStatus.DATA_FRAME_TOO_SHORT
560
+ * - EzspStatus.DATA_FRAME_TOO_LONG
561
+ * - EzspStatus.NOT_CONNECTED
562
+ */
563
+ send(len, inBuf) {
564
+ // Check for errors that might have been detected
565
+ if (this.hostError !== enums_1.EzspStatus.NO_ERROR) {
566
+ return enums_1.EzspStatus.HOST_FATAL_ERROR;
567
+ }
568
+ if (this.ncpError !== enums_1.EzspStatus.NO_ERROR) {
569
+ return enums_1.EzspStatus.ASH_NCP_FATAL_ERROR;
570
+ }
571
+ // After verifying that the data field length is within bounds,
572
+ // copies data frame to a buffer and appends it to the transmit queue.
573
+ if (len < consts_1.ASH_MIN_DATA_FIELD_LEN) {
574
+ return enums_1.EzspStatus.DATA_FRAME_TOO_SHORT;
575
+ }
576
+ else if (len > consts_1.ASH_MAX_DATA_FIELD_LEN) {
577
+ return enums_1.EzspStatus.DATA_FRAME_TOO_LONG;
578
+ }
579
+ if (!(this.flags & Flag.CONNECTED)) {
580
+ return enums_1.EzspStatus.NOT_CONNECTED;
581
+ }
582
+ const buffer = this.txFree.allocBuffer();
583
+ if (buffer == null) {
584
+ return enums_1.EzspStatus.NO_TX_SPACE;
585
+ }
586
+ inBuf.copy(buffer.data, 0, 0, len);
587
+ buffer.len = len;
588
+ this.randomizeBuffer(buffer.data, buffer.len); // IN/OUT data
589
+ this.txQueue.addTail(buffer);
590
+ this.sendExec();
591
+ return enums_1.EzspStatus.SUCCESS;
592
+ }
593
+ /**
594
+ * Manages outgoing communication to the NCP, including DATA frames as well as the frames used for
595
+ * initialization and error detection and recovery.
596
+ */
597
+ sendExec() {
598
+ let outByte = 0x00;
599
+ let inByte = 0x00;
600
+ let len = 0;
601
+ let buffer = null;
602
+ // Check for received acknowledgement timer expiry
603
+ if (this.ackTimerHasExpired()) {
604
+ if (this.flags & Flag.CONNECTED) {
605
+ const expectedFrm = ((this.flags & Flag.RETX) ? this.frmReTx : this.frmTx);
606
+ if (this.ackRx !== expectedFrm) {
607
+ this.counters.rxAckTimeouts += 1;
608
+ this.adjustAckPeriod(true);
609
+ debug(`Timer expired waiting for ACK for ${expectedFrm}, current=${this.ackRx}`);
610
+ if (++this.timeouts >= consts_1.ASH_MAX_TIMEOUTS) {
611
+ this.hostDisconnect(enums_1.EzspStatus.ASH_ERROR_TIMEOUTS);
612
+ return;
613
+ }
614
+ this.startRetransmission();
615
+ }
616
+ else {
617
+ this.stopAckTimer();
618
+ }
619
+ }
620
+ else {
621
+ this.hostDisconnect(enums_1.EzspStatus.ASH_ERROR_RESET_FAIL);
622
+ }
623
+ }
624
+ while (this.writer.writeAvailable()) {
625
+ // Send ASH_CAN character immediately, ahead of any other transmit data
626
+ if (this.flags & Flag.CAN) {
627
+ if (this.sendState === SendState.IDLE) {
628
+ // sending RST or just woke NCP
629
+ this.writer.writeByte(enums_2.AshReservedByte.CANCEL);
630
+ }
631
+ else if (this.sendState === SendState.TX_DATA) {
632
+ // cancel frame in progress
633
+ this.counters.txCancelled += 1;
634
+ this.writer.writeByte(enums_2.AshReservedByte.CANCEL);
635
+ this.stopAckTimer();
636
+ this.sendState = SendState.IDLE;
637
+ }
638
+ this.flags &= ~Flag.CAN;
639
+ continue;
640
+ }
641
+ switch (this.sendState) {
642
+ case SendState.IDLE:
643
+ // In between frames - do some housekeeping and decide what to send next
644
+ // If retransmitting, set the next frame to send to the last ackNum
645
+ // received, then check to see if retransmission is now complete.
646
+ if (this.flags & Flag.RETX) {
647
+ if ((0, math_1.withinRange)(this.frmReTx, this.ackRx, this.frmTx)) {
648
+ this.frmReTx = this.ackRx;
649
+ }
650
+ if (this.frmReTx === this.frmTx) {
651
+ this.flags &= ~Flag.RETX;
652
+ this.scrubReTxQueue();
653
+ }
654
+ }
655
+ // restrain ncp if needed
656
+ this.dataFrameFlowControl();
657
+ // See if a short frame is flagged to be sent
658
+ // The order of the tests below - RST, NAK and ACK -
659
+ // sets the relative priority of sending these frame types.
660
+ if (this.flags & Flag.RST) {
661
+ this.txSHBuffer[0] = enums_2.AshFrameType.RST;
662
+ this.setAndStartAckTimer(CONFIG_TIME_RST);
663
+ len = 1;
664
+ this.flags &= ~(Flag.RST | Flag.NAK | Flag.ACK);
665
+ this.sendState = SendState.SHFRAME;
666
+ debug(`---> [FRAME type=RST]`);
667
+ }
668
+ else if (this.flags & (Flag.NAK | Flag.ACK)) {
669
+ if (this.flags & Flag.NAK) {
670
+ this.txSHBuffer[0] = enums_2.AshFrameType.NAK + (this.frmRx << consts_1.ASH_ACKNUM_BIT);
671
+ this.flags &= ~(Flag.NRTX | Flag.NAK | Flag.ACK);
672
+ debug(`---> [FRAME type=NAK frmRx=${this.frmRx}]`);
673
+ }
674
+ else {
675
+ this.txSHBuffer[0] = enums_2.AshFrameType.ACK + (this.frmRx << consts_1.ASH_ACKNUM_BIT);
676
+ this.flags &= ~(Flag.NRTX | Flag.ACK);
677
+ debug(`---> [FRAME type=ACK frmRx=${this.frmRx}]`);
678
+ }
679
+ if (this.flags & Flag.NR) {
680
+ this.txSHBuffer[0] |= consts_1.ASH_NFLAG_MASK;
681
+ this.flags |= Flag.NRTX;
682
+ this.startNrTimer();
683
+ }
684
+ this.ackTx = this.frmRx;
685
+ len = 1;
686
+ this.sendState = SendState.SHFRAME;
687
+ }
688
+ else if (this.flags & Flag.RETX) {
689
+ // Retransmitting DATA frames for error recovery
690
+ buffer = this.reTxQueue.getNthEntry((0, math_1.mod8)(this.frmTx - this.frmReTx));
691
+ len = buffer.len + 1;
692
+ this.txSHBuffer[0] = enums_2.AshFrameType.DATA | (this.frmReTx << consts_1.ASH_FRMNUM_BIT) | (this.frmRx << consts_1.ASH_ACKNUM_BIT) | consts_1.ASH_RFLAG_MASK;
693
+ this.sendState = SendState.RETX_DATA;
694
+ debug(`---> [FRAME type=DATA_RETX frmReTx=${this.frmReTx} frmRx=${this.frmRx}]`);
695
+ }
696
+ else if (this.ackTx != this.frmRx) {
697
+ // An ACK should be generated
698
+ this.flags |= Flag.ACK;
699
+ break;
700
+ }
701
+ else if (!this.txQueue.empty && (0, math_1.withinRange)(this.ackRx, this.frmTx, (this.ackRx + CONFIG_TX_K - 1))) {
702
+ // Send a DATA frame if ready
703
+ buffer = this.txQueue.head;
704
+ len = buffer.len + 1;
705
+ this.counters.txData += (len - 1);
706
+ this.txSHBuffer[0] = enums_2.AshFrameType.DATA | (this.frmTx << consts_1.ASH_FRMNUM_BIT) | (this.frmRx << consts_1.ASH_ACKNUM_BIT);
707
+ this.sendState = SendState.TX_DATA;
708
+ debug(`---> [FRAME type=DATA frmTx=${this.frmTx} frmRx=${this.frmRx}]`);
709
+ }
710
+ else {
711
+ // Otherwise there's nothing to send
712
+ this.writer.writeFlush();
713
+ return;
714
+ }
715
+ this.countFrame(true);
716
+ // Start frame - encodeByte() is inited by a non-zero length argument
717
+ outByte = this.encodeByte(len, this.txSHBuffer[0]);
718
+ this.writer.writeByte(outByte);
719
+ break;
720
+ case SendState.SHFRAME:
721
+ // sending short frame
722
+ if (this.txOffset !== 0xFF) {
723
+ inByte = this.txSHBuffer[this.txOffset];
724
+ outByte = this.encodeByte(0, inByte);
725
+ this.writer.writeByte(outByte);
726
+ }
727
+ else {
728
+ this.sendState = SendState.IDLE;
729
+ }
730
+ break;
731
+ case SendState.TX_DATA:
732
+ case SendState.RETX_DATA:
733
+ // sending OR resending data frame
734
+ if (this.txOffset !== 0xFF) {
735
+ inByte = this.txOffset ? buffer.data[this.txOffset - 1] : this.txSHBuffer[0];
736
+ outByte = this.encodeByte(0, inByte);
737
+ this.writer.writeByte(outByte);
738
+ }
739
+ else {
740
+ if (this.sendState === SendState.TX_DATA) {
741
+ this.frmTx = (0, math_1.inc8)(this.frmTx);
742
+ buffer = this.txQueue.removeHead();
743
+ this.reTxQueue.addTail(buffer);
744
+ }
745
+ else {
746
+ this.frmReTx = (0, math_1.inc8)(this.frmReTx);
747
+ }
748
+ if (this.ackTimerIsNotRunning()) {
749
+ this.startAckTimer();
750
+ }
751
+ this.ackTx = this.frmRx;
752
+ this.sendState = SendState.IDLE;
753
+ }
754
+ break;
755
+ }
756
+ }
757
+ this.writer.writeFlush();
758
+ }
759
+ /**
760
+ * Retrieve a frame and accept, reTx, reject, fail based on type & validity in current state.
761
+ * @returns
762
+ * - EzspStatus.SUCCESS On valid RSTACK or valid DATA frame.
763
+ * - EzspStatus.ASH_IN_PROGRESS
764
+ * - EzspStatus.NO_RX_DATA
765
+ * - EzspStatus.NO_RX_SPACE
766
+ * - EzspStatus.HOST_FATAL_ERROR
767
+ * - EzspStatus.ASH_NCP_FATAL_ERROR
768
+ */
769
+ receiveFrame(buffer) {
770
+ // Check for errors that might have been detected
771
+ if (this.hostError !== enums_1.EzspStatus.NO_ERROR) {
772
+ return enums_1.EzspStatus.HOST_FATAL_ERROR;
773
+ }
774
+ if (this.ncpError !== enums_1.EzspStatus.NO_ERROR) {
775
+ return enums_1.EzspStatus.ASH_NCP_FATAL_ERROR;
776
+ }
777
+ let ackNum = 0;
778
+ let frmNum = 0;
779
+ let frameType = enums_2.AshFrameType.INVALID;
780
+ // Read data from serial port and assemble a frame until complete, aborted
781
+ // due to an error, cancelled, or there is no more serial data available.
782
+ const status = this.readFrame(buffer);
783
+ switch (status) {
784
+ case enums_1.EzspStatus.SUCCESS:
785
+ break;
786
+ case enums_1.EzspStatus.ASH_IN_PROGRESS:
787
+ // should have a complete frame by now, if not, don't process further
788
+ return enums_1.EzspStatus.NO_RX_DATA;
789
+ case enums_1.EzspStatus.ASH_CANCELLED:
790
+ // should have been taken out in onFrame
791
+ return this.hostDisconnect(status);
792
+ case enums_1.EzspStatus.ASH_BAD_CRC:
793
+ this.counters.rxCrcErrors += 1;
794
+ this.rejectFrame();
795
+ console.error(`Received frame with CRC error`);
796
+ return enums_1.EzspStatus.NO_RX_DATA;
797
+ case enums_1.EzspStatus.ASH_COMM_ERROR:
798
+ this.counters.rxCommErrors += 1;
799
+ this.rejectFrame();
800
+ console.error(`Received frame with comm error`);
801
+ return enums_1.EzspStatus.NO_RX_DATA;
802
+ case enums_1.EzspStatus.ASH_TOO_SHORT:
803
+ this.counters.rxTooShort += 1;
804
+ this.rejectFrame();
805
+ console.error(`Received frame shorter than minimum`);
806
+ return enums_1.EzspStatus.NO_RX_DATA;
807
+ case enums_1.EzspStatus.ASH_TOO_LONG:
808
+ this.counters.rxTooLong += 1;
809
+ this.rejectFrame();
810
+ console.error(`Received frame longer than maximum`);
811
+ return enums_1.EzspStatus.NO_RX_DATA;
812
+ case enums_1.EzspStatus.ASH_ERROR_XON_XOFF:
813
+ return this.hostDisconnect(status);
814
+ default:
815
+ throw new Error(`Unhandled error while receiving frame.`);
816
+ }
817
+ // Got a complete frame - validate its control and length.
818
+ // On an error the type returned will be TYPE_INVALID.
819
+ frameType = this.getFrameType(this.rxSHBuffer[0], this.rxLen);
820
+ // Free buffer allocated for a received frame if:
821
+ // DATA frame, and out of order
822
+ // DATA frame, and not in the CONNECTED state
823
+ // not a DATA frame
824
+ if (frameType === enums_2.AshFrameType.DATA) {
825
+ if (!(this.flags & Flag.CONNECTED) || (ashGetFrmNum(this.rxSHBuffer[0]) !== this.frmRx)) {
826
+ this.freeNonNullRxBuffer();
827
+ }
828
+ }
829
+ else {
830
+ this.freeNonNullRxBuffer();
831
+ }
832
+ const frameTypeStr = enums_2.AshFrameType[frameType];
833
+ debug(`<--- [FRAME type=${frameTypeStr}]`);
834
+ this.countFrame(false);
835
+ // Process frames received while not in the connected state -
836
+ // ignore everything except RSTACK and ERROR frames
837
+ if (!(this.flags & Flag.CONNECTED)) {
838
+ if (frameType === enums_2.AshFrameType.RSTACK) {
839
+ // RSTACK frames have the ncp ASH version in the first data field byte,
840
+ // and the reset reason in the second byte
841
+ if (this.rxSHBuffer[1] !== consts_1.ASH_VERSION) {
842
+ return this.hostDisconnect(enums_1.EzspStatus.ASH_ERROR_VERSION);
843
+ }
844
+ // Ignore a RSTACK if the reset reason doesn't match our reset method
845
+ if (this.rxSHBuffer[2] !== enums_2.NcpFailedCode.RESET_SOFTWARE) {
846
+ return enums_1.EzspStatus.ASH_IN_PROGRESS;
847
+ }
848
+ this.ncpError = enums_1.EzspStatus.NO_ERROR;
849
+ this.stopAckTimer();
850
+ this.timeouts = 0;
851
+ this.setAckPeriod(CONFIG_ACK_TIME_INIT);
852
+ this.flags = Flag.CONNECTED | Flag.ACK;
853
+ console.log(`======== ASH connected ========`);
854
+ return enums_1.EzspStatus.SUCCESS;
855
+ }
856
+ else if (frameType === enums_2.AshFrameType.ERROR) {
857
+ console.error(`Received ERROR from NCP while connecting, with code=${enums_2.NcpFailedCode[this.rxSHBuffer[2]]}.`);
858
+ return this.ncpDisconnect(enums_1.EzspStatus.ASH_NCP_FATAL_ERROR);
859
+ }
860
+ return enums_1.EzspStatus.ASH_IN_PROGRESS;
861
+ }
862
+ // Connected - process the ackNum in ACK, NAK and DATA frames
863
+ if ((frameType === enums_2.AshFrameType.DATA) || (frameType === enums_2.AshFrameType.ACK) || (frameType === enums_2.AshFrameType.NAK)) {
864
+ ackNum = ashGetACKNum(this.rxSHBuffer[0]);
865
+ debug(`<--- [FRAME type=${frameTypeStr} ackNum=${ackNum}]`);
866
+ if (!(0, math_1.withinRange)(this.ackRx, ackNum, this.frmTx)) {
867
+ this.counters.rxBadAckNumber += 1;
868
+ debug(`<-x- [FRAME type=${frameTypeStr} ackNum=${ackNum}] Invalid ACK num; not within <${this.ackRx}-${this.frmTx}>`);
869
+ frameType = enums_2.AshFrameType.INVALID;
870
+ }
871
+ else if (ackNum !== this.ackRx) {
872
+ // new frame(s) ACK'ed?
873
+ this.ackRx = ackNum;
874
+ this.timeouts = 0;
875
+ if (this.flags & Flag.RETX) {
876
+ // start timer if unACK'ed frames
877
+ this.stopAckTimer();
878
+ if (ackNum !== this.frmReTx) {
879
+ this.startAckTimer();
880
+ }
881
+ }
882
+ else {
883
+ this.adjustAckPeriod(false); // factor ACK time into period
884
+ if (ackNum !== this.frmTx) {
885
+ // if more unACK'ed frames,
886
+ this.startAckTimer(); // then restart ACK timer
887
+ }
888
+ this.scrubReTxQueue(); // free buffer(s) in ReTx queue
889
+ }
890
+ }
891
+ }
892
+ // Process frames received while connected
893
+ switch (frameType) {
894
+ case enums_2.AshFrameType.DATA:
895
+ frmNum = ashGetFrmNum(this.rxSHBuffer[0]);
896
+ const frameStr = `[FRAME type=${frameTypeStr} ackNum=${ackNum} frmNum=${frmNum}]`;
897
+ if (frmNum === this.frmRx) {
898
+ // is frame in sequence?
899
+ if (this.rxDataBuffer == null) {
900
+ // valid frame but no memory?
901
+ this.counters.rxNoBuffer += 1;
902
+ debug(`<-x- ${frameStr} No buffer available`);
903
+ this.rejectFrame();
904
+ return enums_1.EzspStatus.NO_RX_SPACE;
905
+ }
906
+ if (this.rxSHBuffer[0] & consts_1.ASH_RFLAG_MASK) {
907
+ // if retransmitted, force ACK
908
+ this.flags |= Flag.ACK;
909
+ }
910
+ this.flags &= ~(Flag.REJ | Flag.NAK); // clear the REJ condition
911
+ this.frmRx = (0, math_1.inc8)(this.frmRx);
912
+ this.randomizeBuffer(this.rxDataBuffer.data, this.rxDataBuffer.len); // IN/OUT data
913
+ this.rxQueue.addTail(this.rxDataBuffer); // add frame to receive queue
914
+ debug(`<--- ${frameStr} Added to rxQueue`);
915
+ this.counters.rxData += this.rxDataBuffer.len;
916
+ setImmediate(() => {
917
+ this.emit(AshEvents.frame);
918
+ });
919
+ return enums_1.EzspStatus.SUCCESS;
920
+ }
921
+ else {
922
+ // frame is out of sequence
923
+ if (this.rxSHBuffer[0] & consts_1.ASH_RFLAG_MASK) {
924
+ // if retransmitted, force ACK
925
+ this.counters.rxDuplicates += 1;
926
+ this.flags |= Flag.ACK;
927
+ }
928
+ else {
929
+ // 1st OOS? then set REJ, send NAK
930
+ if ((this.flags & Flag.REJ) === 0) {
931
+ this.counters.rxOutOfSequence += 1;
932
+ debug(`<-x- ${frameStr} Out of sequence: expected ${this.frmRx}; got ${frmNum}.`);
933
+ }
934
+ this.rejectFrame();
935
+ }
936
+ }
937
+ break;
938
+ case enums_2.AshFrameType.ACK:
939
+ // already fully processed
940
+ break;
941
+ case enums_2.AshFrameType.NAK:
942
+ // start retransmission if needed
943
+ this.startRetransmission();
944
+ break;
945
+ case enums_2.AshFrameType.RSTACK:
946
+ // unexpected ncp reset
947
+ console.error(`Received unexpected reset from NCP, with reason=${enums_2.NcpFailedCode[this.rxSHBuffer[2]]}.`);
948
+ this.ncpError = enums_1.EzspStatus.ASH_NCP_FATAL_ERROR;
949
+ return this.hostDisconnect(enums_1.EzspStatus.ASH_ERROR_NCP_RESET);
950
+ case enums_2.AshFrameType.ERROR:
951
+ // ncp error
952
+ console.error(`Received ERROR from NCP, with code=${enums_2.NcpFailedCode[this.rxSHBuffer[2]]}.`);
953
+ return this.ncpDisconnect(enums_1.EzspStatus.ASH_NCP_FATAL_ERROR);
954
+ case enums_2.AshFrameType.INVALID:
955
+ // reject invalid frames
956
+ debug(`<-x- [FRAME type=${frameTypeStr}] Rejecting. ${this.rxSHBuffer.toString('hex')}`);
957
+ this.rejectFrame();
958
+ break;
959
+ }
960
+ return enums_1.EzspStatus.ASH_IN_PROGRESS;
961
+ }
962
+ /**
963
+ * If the last control byte received was a DATA control, and we are connected and not already in the reject condition,
964
+ * then send a NAK and set the reject condition.
965
+ */
966
+ rejectFrame() {
967
+ if (((this.rxSHBuffer[0] & consts_1.ASH_DFRAME_MASK) === enums_2.AshFrameType.DATA)
968
+ && ((this.flags & (Flag.REJ | Flag.CONNECTED)) === Flag.CONNECTED)) {
969
+ this.flags |= (Flag.REJ | Flag.NAK);
970
+ }
971
+ }
972
+ /**
973
+ * Retrieve and process serial bytes.
974
+ * @returns
975
+ */
976
+ readFrame(buffer) {
977
+ let status = enums_1.EzspStatus.ERROR_INVALID_CALL; // no actual data to read, something's very wrong
978
+ let index = 0;
979
+ // let inByte: number = 0x00;
980
+ let outByte = 0x00;
981
+ if (!this.decodeInProgress) {
982
+ this.rxLen = 0;
983
+ this.rxDataBuffer = null;
984
+ }
985
+ for (const inByte of buffer) {
986
+ // 0xFF byte signals a callback is pending when between frames in synchronous (polled) callback mode.
987
+ if (!this.decodeInProgress && (inByte === consts_1.ASH_WAKE)) {
988
+ if (this.ncpSleepEnabled) {
989
+ this.ncpHasCallbacks = true;
990
+ }
991
+ status = enums_1.EzspStatus.ASH_IN_PROGRESS;
992
+ continue;
993
+ }
994
+ // Decode next input byte - note that many input bytes do not produce
995
+ // an output byte. Return on any error in decoding.
996
+ index = this.rxLen;
997
+ [status, outByte, this.rxLen] = this.decodeByte(inByte, outByte, this.rxLen);
998
+ // discard an invalid frame
999
+ if ((status !== enums_1.EzspStatus.ASH_IN_PROGRESS) && (status !== enums_1.EzspStatus.SUCCESS)) {
1000
+ this.freeNonNullRxBuffer();
1001
+ break;
1002
+ }
1003
+ // if input byte produced an output byte
1004
+ if (this.rxLen !== index) {
1005
+ if (this.rxLen <= consts_1.SH_RX_BUFFER_LEN) {
1006
+ // if a short frame, return in rxBuffer
1007
+ this.rxSHBuffer[index] = outByte;
1008
+ }
1009
+ else {
1010
+ // if a longer DATA frame, allocate an EzspBuffer for it.
1011
+ // (Note the control byte is always returned in shRxBuffer[0].
1012
+ // Even if no buffer can be allocated, the control's ackNum must be processed.)
1013
+ if (this.rxLen === (consts_1.SH_RX_BUFFER_LEN + 1)) {
1014
+ // alloc buffer, copy prior data
1015
+ this.rxDataBuffer = this.rxFree.allocBuffer();
1016
+ if (this.rxDataBuffer !== null) {
1017
+ // const len = SH_RX_BUFFER_LEN - 1;
1018
+ // (void) memcpy(this.rxDataBuffer.data, this.shRxBuffer + 1, SH_RX_BUFFER_LEN - 1);
1019
+ this.rxSHBuffer.copy(this.rxDataBuffer.data, 0, 1, consts_1.SH_RX_BUFFER_LEN);
1020
+ this.rxDataBuffer.len = consts_1.SH_RX_BUFFER_LEN - 1;
1021
+ }
1022
+ }
1023
+ if (this.rxDataBuffer !== null) {
1024
+ // copy next byte to buffer
1025
+ this.rxDataBuffer.data[index - 1] = outByte; // -1 since control is omitted
1026
+ this.rxDataBuffer.len = index;
1027
+ }
1028
+ }
1029
+ }
1030
+ if (status !== enums_1.EzspStatus.ASH_IN_PROGRESS) {
1031
+ break;
1032
+ }
1033
+ }
1034
+ return status;
1035
+ }
1036
+ /**
1037
+ *
1038
+ */
1039
+ freeNonNullRxBuffer() {
1040
+ if (this.rxDataBuffer !== null) {
1041
+ this.rxFree.freeBuffer(this.rxDataBuffer);
1042
+ this.rxDataBuffer = null;
1043
+ }
1044
+ }
1045
+ /**
1046
+ *
1047
+ */
1048
+ scrubReTxQueue() {
1049
+ let buffer;
1050
+ while (this.ackRx !== this.frmReTxHead) {
1051
+ buffer = this.reTxQueue.removeHead();
1052
+ this.txFree.freeBuffer(buffer);
1053
+ this.frmReTxHead = (0, math_1.inc8)(this.frmReTxHead);
1054
+ }
1055
+ }
1056
+ /**
1057
+ * If not already retransmitting, and there are unacked frames, start retransmitting after the last frame that was acked.
1058
+ */
1059
+ startRetransmission() {
1060
+ if (!(this.flags & Flag.RETX) && (this.ackRx != this.frmTx)) {
1061
+ this.stopAckTimer();
1062
+ this.frmReTx = this.ackRx;
1063
+ this.flags |= (Flag.RETX | Flag.CAN);
1064
+ }
1065
+ }
1066
+ /**
1067
+ * Check free rx buffers to see whether able to receive DATA frames: set or clear NR flag appropriately.
1068
+ * Inform ncp of our status using the nFlag in ACKs and NAKs.
1069
+ * Note that not ready status must be refreshed if it persists beyond a maximum time limit.
1070
+ */
1071
+ dataFrameFlowControl() {
1072
+ if (this.flags & Flag.CONNECTED) {
1073
+ // Set/clear NR flag based on the number of buffers free
1074
+ if (this.rxFree.length < CONFIG_NR_LOW_LIMIT) {
1075
+ this.flags |= Flag.NR;
1076
+ debug(`NOT READY - Signaling NCP`);
1077
+ }
1078
+ else if (this.rxFree.length > CONFIG_NR_HIGH_LIMIT) {
1079
+ this.flags &= ~Flag.NR;
1080
+ this.stopNrTimer(); // needed??
1081
+ // debug(`READY - Signaling NCP`);// spams-a-lot
1082
+ }
1083
+ // Force an ACK (or possibly NAK) if we need to send an updated nFlag
1084
+ // due to either a changed NR status or to refresh a set nFlag
1085
+ if (this.flags & Flag.NR) {
1086
+ if (!(this.flags & Flag.NRTX) || this.nrTimerHasExpired()) {
1087
+ this.flags |= Flag.ACK;
1088
+ this.startNrTimer();
1089
+ }
1090
+ }
1091
+ else {
1092
+ this.nrTimerHasExpired(); // ensure timer checked often
1093
+ if (this.flags & Flag.NRTX) {
1094
+ this.flags |= Flag.ACK;
1095
+ this.stopNrTimer(); // needed???
1096
+ }
1097
+ }
1098
+ }
1099
+ else {
1100
+ this.stopNrTimer();
1101
+ this.flags &= ~(Flag.NRTX | Flag.NR);
1102
+ }
1103
+ }
1104
+ /**
1105
+ * Sets a fatal error state at the Host level.
1106
+ * @param error
1107
+ * @returns EzspStatus.HOST_FATAL_ERROR
1108
+ */
1109
+ hostDisconnect(error) {
1110
+ this.flags = 0;
1111
+ this.hostError = error;
1112
+ console.error(`ASH disconnected: ${enums_1.EzspStatus[error]} | NCP status: ${enums_1.EzspStatus[this.ncpError]}`);
1113
+ this.emit(AshEvents.hostError, error);
1114
+ return enums_1.EzspStatus.HOST_FATAL_ERROR;
1115
+ }
1116
+ /**
1117
+ * Sets a fatal error state at the NCP level. Will require a reset.
1118
+ * @param error
1119
+ * @returns EzspStatus.ASH_NCP_FATAL_ERROR
1120
+ */
1121
+ ncpDisconnect(error) {
1122
+ this.flags = 0;
1123
+ this.ncpError = error;
1124
+ console.error(`ASH disconnected | NCP status: ${enums_1.EzspStatus[this.ncpError]}`);
1125
+ this.emit(AshEvents.ncpError, error);
1126
+ return enums_1.EzspStatus.ASH_NCP_FATAL_ERROR;
1127
+ }
1128
+ /**
1129
+ * Same as randomizeArray(0, buffer, len).
1130
+ * Returns buffer as-is if randomize is OFF.
1131
+ * @param buffer IN/OUT
1132
+ * @param len
1133
+ */
1134
+ randomizeBuffer(buffer, len) {
1135
+ // If enabled, exclusive-OR buffer data with a pseudo-random sequence
1136
+ if (CONFIG_RANDOMIZE) {
1137
+ this.randomizeArray(0, buffer, len); // zero inits the random sequence
1138
+ }
1139
+ }
1140
+ /**
1141
+ * Randomizes array contents by XORing with an 8-bit pseudo random sequence.
1142
+ * This reduces the likelihood that byte-stuffing will greatly increase the size of the payload.
1143
+ * (This could happen if a DATA frame contained repeated instances of the same reserved byte value.)
1144
+ *
1145
+ * @param seed zero initializes the random sequence a non-zero value continues from a previous invocation
1146
+ * @param buf IN/OUT pointer to the array whose contents will be randomized
1147
+ * @param len number of bytes in the array to modify
1148
+ * @returns last value of the sequence.
1149
+ * If a buffer is processed in two or more chunks, as with linked buffers,
1150
+ * this value should be passed back as the value of the seed argument
1151
+ */
1152
+ randomizeArray(seed, buf, len) {
1153
+ let outIdx = 0;
1154
+ if (seed === 0) {
1155
+ seed = consts_1.LFSR_SEED;
1156
+ }
1157
+ while (len--) {
1158
+ // *buf++ ^= seed;
1159
+ buf[outIdx++] ^= seed;
1160
+ seed = (seed & 1) ? ((seed >> 1) ^ consts_1.LFSR_POLY) : (seed >> 1);
1161
+ }
1162
+ return seed;
1163
+ }
1164
+ /**
1165
+ * Get the frame type from the control byte and validate it against the frame length.
1166
+ * @param control
1167
+ * @param len Frame length
1168
+ * @returns AshFrameType.INVALID if bad control/length otherwise the frame type.
1169
+ */
1170
+ getFrameType(control, len) {
1171
+ if (control === enums_2.AshFrameType.RSTACK) {
1172
+ if (len === consts_1.ASH_FRAME_LEN_RSTACK) {
1173
+ return enums_2.AshFrameType.RSTACK;
1174
+ }
1175
+ }
1176
+ else if (control === enums_2.AshFrameType.ERROR) {
1177
+ if (len === consts_1.ASH_FRAME_LEN_ERROR) {
1178
+ return enums_2.AshFrameType.ERROR;
1179
+ }
1180
+ }
1181
+ else if ((control & consts_1.ASH_DFRAME_MASK) === enums_2.AshFrameType.DATA) {
1182
+ if (len >= consts_1.ASH_FRAME_LEN_DATA_MIN) {
1183
+ return enums_2.AshFrameType.DATA;
1184
+ }
1185
+ }
1186
+ else if ((control & consts_1.ASH_SHFRAME_MASK) === enums_2.AshFrameType.ACK) {
1187
+ if (len === consts_1.ASH_FRAME_LEN_ACK) {
1188
+ return enums_2.AshFrameType.ACK;
1189
+ }
1190
+ }
1191
+ else if ((control & consts_1.ASH_SHFRAME_MASK) === enums_2.AshFrameType.NAK) {
1192
+ if (len === consts_1.ASH_FRAME_LEN_NAK) {
1193
+ return enums_2.AshFrameType.NAK;
1194
+ }
1195
+ }
1196
+ else {
1197
+ this.counters.rxBadControl += 1;
1198
+ debug(`Frame illegal control ${control}.`); // EzspStatus.ASH_BAD_CONTROL
1199
+ return enums_2.AshFrameType.INVALID;
1200
+ }
1201
+ this.counters.rxBadLength += 1;
1202
+ debug(`Frame illegal length ${len} for control ${control}.`); // EzspStatus.ASH_BAD_LENGTH
1203
+ return enums_2.AshFrameType.INVALID;
1204
+ }
1205
+ /**
1206
+ * Encode byte for sending.
1207
+ * @param len Start a new frame if non-zero
1208
+ * @param byte
1209
+ * @returns outByte
1210
+ */
1211
+ encodeByte(len, byte) {
1212
+ // start a new frame if len is non-zero
1213
+ if (len) {
1214
+ this.encodeCount = len;
1215
+ this.txOffset = 0;
1216
+ this.encodeState = 0;
1217
+ this.encodeEscFlag = false;
1218
+ this.encodeCrc = 0xFFFF;
1219
+ }
1220
+ // was an escape last time?
1221
+ if (this.encodeEscFlag) {
1222
+ this.encodeEscFlag = false;
1223
+ // send data byte with bit flipped
1224
+ return this.encodeFlip;
1225
+ }
1226
+ // control and data field bytes
1227
+ if (this.encodeState === 0) {
1228
+ this.encodeCrc = (0, math_1.halCommonCrc16)(byte, this.encodeCrc);
1229
+ if (--this.encodeCount === 0) {
1230
+ this.encodeState = 1;
1231
+ }
1232
+ else {
1233
+ ++this.txOffset;
1234
+ }
1235
+ return this.encodeStuffByte(byte);
1236
+ }
1237
+ else if (this.encodeState === 1) {
1238
+ // CRC high byte
1239
+ this.encodeState = 2;
1240
+ return this.encodeStuffByte(this.encodeCrc >> 8);
1241
+ }
1242
+ else if (this.encodeState === 2) {
1243
+ // CRC low byte
1244
+ this.encodeState = 3;
1245
+ return this.encodeStuffByte(this.encodeCrc & 0xFF);
1246
+ }
1247
+ this.txOffset = 0xFF;
1248
+ return enums_2.AshReservedByte.FLAG;
1249
+ }
1250
+ /**
1251
+ * Stuff byte as defined by ASH protocol.
1252
+ * @param byte
1253
+ * @returns
1254
+ */
1255
+ encodeStuffByte(byte) {
1256
+ if (enums_2.AshReservedByte[byte] != null) {
1257
+ // is special byte
1258
+ this.encodeEscFlag = true;
1259
+ this.encodeFlip = byte ^ consts_1.ASH_FLIP;
1260
+ return enums_2.AshReservedByte.ESCAPE;
1261
+ }
1262
+ else {
1263
+ return byte;
1264
+ }
1265
+ }
1266
+ /**
1267
+ * Decode received byte.
1268
+ * @param byte
1269
+ * @param inByte IN/OUT
1270
+ * @param inLen IN/OUT
1271
+ * @returns [EzspStatus, outByte, outLen]
1272
+ * - EzspStatus.ASH_IN_PROGRESS
1273
+ * - EzspStatus.ASH_COMM_ERROR
1274
+ * - EzspStatus.ASH_BAD_CRC
1275
+ * - EzspStatus.ASH_TOO_SHORT
1276
+ * - EzspStatus.ASH_TOO_LONG
1277
+ * - EzspStatus.SUCCESS
1278
+ * - EzspStatus.ASH_CANCELLED
1279
+ * - EzspStatus.ASH_ERROR_XON_XOFF
1280
+ */
1281
+ decodeByte(byte, inByte, inLen) {
1282
+ let status = enums_1.EzspStatus.ASH_IN_PROGRESS;
1283
+ if (!this.decodeInProgress) {
1284
+ this.decodeLen = 0;
1285
+ this.decodeByte1 = 0;
1286
+ this.decodeByte2 = 0;
1287
+ this.decodeFlip = 0;
1288
+ this.decodeCrc = 0xFFFF;
1289
+ }
1290
+ switch (byte) {
1291
+ case enums_2.AshReservedByte.FLAG:
1292
+ // flag byte (frame delimiter)
1293
+ if (this.decodeLen === 0) {
1294
+ // if no frame data, not end flag, so ignore it
1295
+ this.decodeFlip = 0; // ignore isolated data escape between flags
1296
+ break;
1297
+ }
1298
+ else if (this.decodeLen === 0xFF) {
1299
+ status = enums_1.EzspStatus.ASH_COMM_ERROR;
1300
+ }
1301
+ else if (this.decodeCrc !== ((this.decodeByte2 << 8) + this.decodeByte1)) {
1302
+ status = enums_1.EzspStatus.ASH_BAD_CRC;
1303
+ }
1304
+ else if (this.decodeLen < consts_1.ASH_MIN_FRAME_WITH_CRC_LEN) {
1305
+ status = enums_1.EzspStatus.ASH_TOO_SHORT;
1306
+ }
1307
+ else if (this.decodeLen > consts_1.ASH_MAX_FRAME_WITH_CRC_LEN) {
1308
+ status = enums_1.EzspStatus.ASH_TOO_LONG;
1309
+ }
1310
+ else {
1311
+ status = enums_1.EzspStatus.SUCCESS;
1312
+ }
1313
+ break;
1314
+ case enums_2.AshReservedByte.ESCAPE:
1315
+ // byte stuffing escape byte
1316
+ this.decodeFlip = consts_1.ASH_FLIP;
1317
+ break;
1318
+ case enums_2.AshReservedByte.CANCEL:
1319
+ // cancel frame without an error
1320
+ status = enums_1.EzspStatus.ASH_CANCELLED;
1321
+ break;
1322
+ case enums_2.AshReservedByte.SUBSTITUTE:
1323
+ // discard remainder of frame
1324
+ this.decodeLen = 0xFF; // special value flags low level comm error
1325
+ break;
1326
+ case enums_2.AshReservedByte.XON:
1327
+ case enums_2.AshReservedByte.XOFF:
1328
+ // If host is using RTS/CTS, ignore any XON/XOFFs received from the NCP.
1329
+ // If using XON/XOFF, the host driver must remove them from the input stream.
1330
+ // If it doesn't, it probably means the driver isn't setup for XON/XOFF,
1331
+ // so issue an error to flag the serial port driver problem.
1332
+ if (this.serialPort != null && !this.serialPort.settings.rtscts) {
1333
+ status = enums_1.EzspStatus.ASH_ERROR_XON_XOFF;
1334
+ }
1335
+ break;
1336
+ default:
1337
+ // a normal byte
1338
+ byte ^= this.decodeFlip;
1339
+ this.decodeFlip = 0;
1340
+ if (this.decodeLen <= consts_1.ASH_MAX_FRAME_WITH_CRC_LEN) {
1341
+ // limit length to max + 1
1342
+ ++this.decodeLen;
1343
+ }
1344
+ if (this.decodeLen > consts_1.ASH_CRC_LEN) {
1345
+ // compute frame CRC even if too long
1346
+ this.decodeCrc = (0, math_1.halCommonCrc16)(this.decodeByte2, this.decodeCrc);
1347
+ if (this.decodeLen <= consts_1.ASH_MAX_FRAME_WITH_CRC_LEN) {
1348
+ // store to only max len
1349
+ inByte = this.decodeByte2;
1350
+ inLen = this.decodeLen - consts_1.ASH_CRC_LEN; // CRC is not output, reduce length
1351
+ }
1352
+ }
1353
+ this.decodeByte2 = this.decodeByte1;
1354
+ this.decodeByte1 = byte;
1355
+ break;
1356
+ }
1357
+ this.decodeInProgress = (status === enums_1.EzspStatus.ASH_IN_PROGRESS);
1358
+ return [status, inByte, inLen];
1359
+ }
1360
+ /**
1361
+ * Starts the Not Ready timer
1362
+ *
1363
+ * On the host, this times nFlag refreshing when the host doesn't have room for callbacks for a prolonged period.
1364
+ *
1365
+ * On the NCP, if this times out the NCP resumes sending callbacks.
1366
+ */
1367
+ startNrTimer() {
1368
+ this.nrTimer = (Date.now() + CONFIG_NR_TIME);
1369
+ }
1370
+ /**
1371
+ * Stop Not Ready timer (set to 0).
1372
+ */
1373
+ stopNrTimer() {
1374
+ this.nrTimer = 0;
1375
+ }
1376
+ /**
1377
+ * Tests whether the Not Ready timer has expired or has stopped. If expired, it is stopped.
1378
+ *
1379
+ * @returns true if the Not Ready timer has expired or stopped
1380
+ */
1381
+ nrTimerHasExpired() {
1382
+ if (this.nrTimer) {
1383
+ if ((Date.now() - this.nrTimer) >= 0) {
1384
+ this.nrTimer = 0;
1385
+ }
1386
+ }
1387
+ return (!this.nrTimer);
1388
+ }
1389
+ /**
1390
+ * Indicates whether or not Not Ready timer is currently running.
1391
+ *
1392
+ * @return True if nrTime == 0
1393
+ */
1394
+ nrTimerIsNotRunning() {
1395
+ return this.nrTimer === 0;
1396
+ }
1397
+ /**
1398
+ * Sets the acknowledgement timer period (in msec) and stops the timer.
1399
+ */
1400
+ setAckPeriod(msec) {
1401
+ this.ackPeriod = msec;
1402
+ this.ackTimer = 0;
1403
+ }
1404
+ /**
1405
+ * Sets the acknowledgement timer period (in msec), and starts the timer running.
1406
+ */
1407
+ setAndStartAckTimer(msec) {
1408
+ this.setAckPeriod(msec);
1409
+ this.startAckTimer();
1410
+ }
1411
+ /**
1412
+ * Adapts the acknowledgement timer period to the observed ACK delay.
1413
+ * If the timer is not running, it does nothing.
1414
+ * If the timer has expired, the timeout period is doubled.
1415
+ * If the timer has not expired, the elapsed time is fed into simple
1416
+ *
1417
+ * IIR filter:
1418
+ * T[n+1] = (7*T[n] + elapsedTime) / 8
1419
+ *
1420
+ * The timeout period, ackPeriod, is limited such that:
1421
+ * config.ackTimeMin <= ackPeriod <= config.ackTimeMax.
1422
+ *
1423
+ * The acknowledgement timer is always stopped by this function.
1424
+ *
1425
+ * @param expired true if timer has expired
1426
+ */
1427
+ adjustAckPeriod(expired) {
1428
+ if (expired) {
1429
+ // if expired, double the period
1430
+ this.ackPeriod += this.ackPeriod;
1431
+ }
1432
+ else if (this.ackTimer) {
1433
+ // adjust period only if running
1434
+ // time elapsed since timer was started
1435
+ let temp = this.ackPeriod;
1436
+ // compute time to receive acknowledgement, then stop timer
1437
+ const lastAckTime = Date.now() - this.ackTimer;
1438
+ temp = (temp << 3) - temp;
1439
+ temp += lastAckTime << 2;
1440
+ temp >>= 3;
1441
+ this.ackPeriod = (temp & 0xFFFF);
1442
+ }
1443
+ // keep ackPeriod within limits
1444
+ if (this.ackPeriod > CONFIG_ACK_TIME_MAX) {
1445
+ this.ackPeriod = CONFIG_ACK_TIME_MAX;
1446
+ }
1447
+ else if (this.ackPeriod < CONFIG_ACK_TIME_MIN) {
1448
+ this.ackPeriod = CONFIG_ACK_TIME_MIN;
1449
+ }
1450
+ this.ackTimer = 0; // always stop the timer
1451
+ }
1452
+ /**
1453
+ * Sets ACK Timer to the specified period and starts it running.
1454
+ */
1455
+ startAckTimer() {
1456
+ this.ackTimer = Date.now();
1457
+ }
1458
+ /**
1459
+ * Stops and clears ACK Timer.
1460
+ */
1461
+ stopAckTimer() {
1462
+ this.ackTimer = 0;
1463
+ }
1464
+ /**
1465
+ * Indicates whether or not ACK Timer has expired.
1466
+ * If the timer is stopped (0) then it is not expired.
1467
+ *
1468
+ * @returns
1469
+ */
1470
+ ackTimerHasExpired() {
1471
+ if (this.ackTimer === 0) {
1472
+ // if timer is not running, return false
1473
+ return false;
1474
+ }
1475
+ // return ((halCommonGetInt16uMillisecondTick() - this.ackTimer) >= this.ackPeriod);
1476
+ return ((Date.now() - this.ackTimer) >= this.ackPeriod);
1477
+ }
1478
+ /**
1479
+ * Indicates whether or not ACK Timer is currently running (!= 0).
1480
+ * The timer may be running even if expired.
1481
+ */
1482
+ ackTimerIsNotRunning() {
1483
+ return this.ackTimer === 0;
1484
+ }
1485
+ /**
1486
+ * Increase counters based on frame type and direction.
1487
+ * @param sent True if frame being sent, false if being received.
1488
+ */
1489
+ countFrame(sent) {
1490
+ let control;
1491
+ if (sent) {
1492
+ control = this.txSHBuffer[0];
1493
+ this.counters.txAllFrames += 1;
1494
+ }
1495
+ else {
1496
+ control = this.rxSHBuffer[0];
1497
+ this.counters.rxAllFrames += 1;
1498
+ }
1499
+ if ((control & consts_1.ASH_DFRAME_MASK) === enums_2.AshFrameType.DATA) {
1500
+ if (sent) {
1501
+ if (control & consts_1.ASH_RFLAG_MASK) {
1502
+ this.counters.txReDataFrames += 1;
1503
+ }
1504
+ else {
1505
+ this.counters.txDataFrames += 1;
1506
+ }
1507
+ }
1508
+ else {
1509
+ if (control & consts_1.ASH_RFLAG_MASK) {
1510
+ this.counters.rxReDataFrames += 1;
1511
+ }
1512
+ else {
1513
+ this.counters.rxDataFrames += 1;
1514
+ }
1515
+ }
1516
+ }
1517
+ else if ((control & consts_1.ASH_SHFRAME_MASK) === enums_2.AshFrameType.ACK) {
1518
+ if (sent) {
1519
+ this.counters.txAckFrames += 1;
1520
+ if (control & consts_1.ASH_NFLAG_MASK) {
1521
+ this.counters.txN1Frames += 1;
1522
+ } /* else {
1523
+ this.counters.txN0Frames += 1;
1524
+ }*/
1525
+ }
1526
+ else {
1527
+ this.counters.rxAckFrames += 1;
1528
+ if (control & consts_1.ASH_NFLAG_MASK) {
1529
+ this.counters.rxN1Frames += 1;
1530
+ } /* else {
1531
+ this.counters.rxN0Frames += 1;
1532
+ }*/
1533
+ }
1534
+ }
1535
+ else if ((control & consts_1.ASH_SHFRAME_MASK) === enums_2.AshFrameType.NAK) {
1536
+ if (sent) {
1537
+ this.counters.txNakFrames += 1;
1538
+ if (control & consts_1.ASH_NFLAG_MASK) {
1539
+ this.counters.txN1Frames += 1;
1540
+ } /* else {
1541
+ this.counters.txN0Frames += 1;
1542
+ }*/
1543
+ }
1544
+ else {
1545
+ this.counters.rxNakFrames += 1;
1546
+ if (control & consts_1.ASH_NFLAG_MASK) {
1547
+ this.counters.rxN1Frames += 1;
1548
+ } /* else {
1549
+ this.counters.rxN0Frames += 1;
1550
+ }*/
1551
+ }
1552
+ }
1553
+ }
1554
+ /**
1555
+ * Prints counters in a nicely formatted table.
1556
+ */
1557
+ printCounters() {
1558
+ console.table({
1559
+ "Total frames": { "Received": this.counters.rxAllFrames, "Transmitted": this.counters.txAllFrames },
1560
+ "Cancelled": { "Received": this.counters.rxCancelled, "Transmitted": this.counters.txCancelled },
1561
+ "DATA frames": { "Received": this.counters.rxDataFrames, "Transmitted": this.counters.txDataFrames },
1562
+ "DATA bytes": { "Received": this.counters.rxData, "Transmitted": this.counters.txData },
1563
+ "Retry frames": { "Received": this.counters.rxReDataFrames, "Transmitted": this.counters.txReDataFrames },
1564
+ "ACK frames": { "Received": this.counters.rxAckFrames, "Transmitted": this.counters.txAckFrames },
1565
+ "NAK frames": { "Received": this.counters.rxNakFrames, "Transmitted": this.counters.txNakFrames },
1566
+ "nRdy frames": { "Received": this.counters.rxN1Frames, "Transmitted": this.counters.txN1Frames },
1567
+ });
1568
+ console.table({
1569
+ "CRC errors": { "Received": this.counters.rxCrcErrors },
1570
+ "Comm errors": { "Received": this.counters.rxCommErrors },
1571
+ "Length < minimum": { "Received": this.counters.rxTooShort },
1572
+ "Length > maximum": { "Received": this.counters.rxTooLong },
1573
+ "Bad controls": { "Received": this.counters.rxBadControl },
1574
+ "Bad lengths": { "Received": this.counters.rxBadLength },
1575
+ "Bad ACK numbers": { "Received": this.counters.rxBadAckNumber },
1576
+ "Out of buffers": { "Received": this.counters.rxNoBuffer },
1577
+ "Retry dupes": { "Received": this.counters.rxDuplicates },
1578
+ "Out of sequence": { "Received": this.counters.rxOutOfSequence },
1579
+ "ACK timeouts": { "Received": this.counters.rxAckTimeouts },
1580
+ });
1581
+ }
1582
+ }
1583
+ exports.UartAsh = UartAsh;
1584
+ //# sourceMappingURL=ash.js.map