@robotical/raftjs 1.3.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 (260) hide show
  1. package/.editorconfig +14 -0
  2. package/.gitattributes +11 -0
  3. package/.nvmrc +1 -0
  4. package/LICENSE +22 -0
  5. package/README.md +13 -0
  6. package/TODO.md +1 -0
  7. package/dist/react-native/RaftAttributeHandler.d.ts +12 -0
  8. package/dist/react-native/RaftAttributeHandler.js +241 -0
  9. package/dist/react-native/RaftAttributeHandler.js.map +1 -0
  10. package/dist/react-native/RaftChannel.d.ts +18 -0
  11. package/dist/react-native/RaftChannel.js +12 -0
  12. package/dist/react-native/RaftChannel.js.map +1 -0
  13. package/dist/react-native/RaftChannelBLE.native.d.ts +93 -0
  14. package/dist/react-native/RaftChannelBLE.native.js +455 -0
  15. package/dist/react-native/RaftChannelBLE.native.js.map +1 -0
  16. package/dist/react-native/RaftChannelBLE.web.d.ts +39 -0
  17. package/dist/react-native/RaftChannelBLE.web.js +294 -0
  18. package/dist/react-native/RaftChannelBLE.web.js.map +1 -0
  19. package/dist/react-native/RaftChannelBLEFactory.d.ts +10 -0
  20. package/dist/react-native/RaftChannelBLEFactory.js +17 -0
  21. package/dist/react-native/RaftChannelBLEFactory.js.map +1 -0
  22. package/dist/react-native/RaftChannelBLEScanner.native.d.ts +18 -0
  23. package/dist/react-native/RaftChannelBLEScanner.native.js +146 -0
  24. package/dist/react-native/RaftChannelBLEScanner.native.js.map +1 -0
  25. package/dist/react-native/RaftChannelWebSerial.d.ts +37 -0
  26. package/dist/react-native/RaftChannelWebSerial.js +320 -0
  27. package/dist/react-native/RaftChannelWebSerial.js.map +1 -0
  28. package/dist/react-native/RaftChannelWebSocket.d.ts +28 -0
  29. package/dist/react-native/RaftChannelWebSocket.js +197 -0
  30. package/dist/react-native/RaftChannelWebSocket.js.map +1 -0
  31. package/dist/react-native/RaftCommsStats.d.ts +39 -0
  32. package/dist/react-native/RaftCommsStats.js +128 -0
  33. package/dist/react-native/RaftCommsStats.js.map +1 -0
  34. package/dist/react-native/RaftConnEvents.d.ts +39 -0
  35. package/dist/react-native/RaftConnEvents.js +54 -0
  36. package/dist/react-native/RaftConnEvents.js.map +1 -0
  37. package/dist/react-native/RaftConnector.d.ts +245 -0
  38. package/dist/react-native/RaftConnector.js +614 -0
  39. package/dist/react-native/RaftConnector.js.map +1 -0
  40. package/dist/react-native/RaftCustomAttrHandler.d.ts +4 -0
  41. package/dist/react-native/RaftCustomAttrHandler.js +50 -0
  42. package/dist/react-native/RaftCustomAttrHandler.js.map +1 -0
  43. package/dist/react-native/RaftDeviceInfo.d.ts +59 -0
  44. package/dist/react-native/RaftDeviceInfo.js +36 -0
  45. package/dist/react-native/RaftDeviceInfo.js.map +1 -0
  46. package/dist/react-native/RaftDeviceManager.d.ts +35 -0
  47. package/dist/react-native/RaftDeviceManager.js +353 -0
  48. package/dist/react-native/RaftDeviceManager.js.map +1 -0
  49. package/dist/react-native/RaftDeviceMgrIF.d.ts +12 -0
  50. package/dist/react-native/RaftDeviceMgrIF.js +11 -0
  51. package/dist/react-native/RaftDeviceMgrIF.js.map +1 -0
  52. package/dist/react-native/RaftDeviceMsg.d.ts +9 -0
  53. package/dist/react-native/RaftDeviceMsg.js +11 -0
  54. package/dist/react-native/RaftDeviceMsg.js.map +1 -0
  55. package/dist/react-native/RaftDeviceStates.d.ts +33 -0
  56. package/dist/react-native/RaftDeviceStates.js +60 -0
  57. package/dist/react-native/RaftDeviceStates.js.map +1 -0
  58. package/dist/react-native/RaftFileHandler.d.ts +52 -0
  59. package/dist/react-native/RaftFileHandler.js +502 -0
  60. package/dist/react-native/RaftFileHandler.js.map +1 -0
  61. package/dist/react-native/RaftLog.d.ts +22 -0
  62. package/dist/react-native/RaftLog.js +63 -0
  63. package/dist/react-native/RaftLog.js.map +1 -0
  64. package/dist/react-native/RaftMiniHDLC.d.ts +18 -0
  65. package/dist/react-native/RaftMiniHDLC.js +383 -0
  66. package/dist/react-native/RaftMiniHDLC.js.map +1 -0
  67. package/dist/react-native/RaftMsgHandler.d.ts +57 -0
  68. package/dist/react-native/RaftMsgHandler.js +480 -0
  69. package/dist/react-native/RaftMsgHandler.js.map +1 -0
  70. package/dist/react-native/RaftMsgTrackInfo.d.ts +17 -0
  71. package/dist/react-native/RaftMsgTrackInfo.js +42 -0
  72. package/dist/react-native/RaftMsgTrackInfo.js.map +1 -0
  73. package/dist/react-native/RaftProtocolDefs.d.ts +30 -0
  74. package/dist/react-native/RaftProtocolDefs.js +48 -0
  75. package/dist/react-native/RaftProtocolDefs.js.map +1 -0
  76. package/dist/react-native/RaftStreamHandler.d.ts +38 -0
  77. package/dist/react-native/RaftStreamHandler.js +257 -0
  78. package/dist/react-native/RaftStreamHandler.js.map +1 -0
  79. package/dist/react-native/RaftSystemType.d.ts +25 -0
  80. package/dist/react-native/RaftSystemType.js +3 -0
  81. package/dist/react-native/RaftSystemType.js.map +1 -0
  82. package/dist/react-native/RaftSystemUtils.d.ts +136 -0
  83. package/dist/react-native/RaftSystemUtils.js +410 -0
  84. package/dist/react-native/RaftSystemUtils.js.map +1 -0
  85. package/dist/react-native/RaftTypes.d.ts +195 -0
  86. package/dist/react-native/RaftTypes.js +190 -0
  87. package/dist/react-native/RaftTypes.js.map +1 -0
  88. package/dist/react-native/RaftUpdateEvents.d.ts +33 -0
  89. package/dist/react-native/RaftUpdateEvents.js +46 -0
  90. package/dist/react-native/RaftUpdateEvents.js.map +1 -0
  91. package/dist/react-native/RaftUpdateManager.d.ts +61 -0
  92. package/dist/react-native/RaftUpdateManager.js +618 -0
  93. package/dist/react-native/RaftUpdateManager.js.map +1 -0
  94. package/dist/react-native/RaftUtils.d.ts +125 -0
  95. package/dist/react-native/RaftUtils.js +454 -0
  96. package/dist/react-native/RaftUtils.js.map +1 -0
  97. package/dist/react-native/RaftWifiTypes.d.ts +23 -0
  98. package/dist/react-native/RaftWifiTypes.js +43 -0
  99. package/dist/react-native/RaftWifiTypes.js.map +1 -0
  100. package/dist/react-native/main.d.ts +22 -0
  101. package/dist/react-native/main.js +48 -0
  102. package/dist/react-native/main.js.map +1 -0
  103. package/dist/web/RaftAttributeHandler.d.ts +12 -0
  104. package/dist/web/RaftAttributeHandler.js +241 -0
  105. package/dist/web/RaftAttributeHandler.js.map +1 -0
  106. package/dist/web/RaftChannel.d.ts +18 -0
  107. package/dist/web/RaftChannel.js +12 -0
  108. package/dist/web/RaftChannel.js.map +1 -0
  109. package/dist/web/RaftChannelBLE.web.d.ts +39 -0
  110. package/dist/web/RaftChannelBLE.web.js +294 -0
  111. package/dist/web/RaftChannelBLE.web.js.map +1 -0
  112. package/dist/web/RaftChannelBLEFactory.d.ts +10 -0
  113. package/dist/web/RaftChannelBLEFactory.js +17 -0
  114. package/dist/web/RaftChannelBLEFactory.js.map +1 -0
  115. package/dist/web/RaftChannelWebSerial.d.ts +37 -0
  116. package/dist/web/RaftChannelWebSerial.js +320 -0
  117. package/dist/web/RaftChannelWebSerial.js.map +1 -0
  118. package/dist/web/RaftChannelWebSocket.d.ts +28 -0
  119. package/dist/web/RaftChannelWebSocket.js +197 -0
  120. package/dist/web/RaftChannelWebSocket.js.map +1 -0
  121. package/dist/web/RaftCommsStats.d.ts +39 -0
  122. package/dist/web/RaftCommsStats.js +128 -0
  123. package/dist/web/RaftCommsStats.js.map +1 -0
  124. package/dist/web/RaftConnEvents.d.ts +39 -0
  125. package/dist/web/RaftConnEvents.js +54 -0
  126. package/dist/web/RaftConnEvents.js.map +1 -0
  127. package/dist/web/RaftConnector.d.ts +245 -0
  128. package/dist/web/RaftConnector.js +614 -0
  129. package/dist/web/RaftConnector.js.map +1 -0
  130. package/dist/web/RaftCustomAttrHandler.d.ts +4 -0
  131. package/dist/web/RaftCustomAttrHandler.js +50 -0
  132. package/dist/web/RaftCustomAttrHandler.js.map +1 -0
  133. package/dist/web/RaftDeviceInfo.d.ts +59 -0
  134. package/dist/web/RaftDeviceInfo.js +36 -0
  135. package/dist/web/RaftDeviceInfo.js.map +1 -0
  136. package/dist/web/RaftDeviceManager.d.ts +35 -0
  137. package/dist/web/RaftDeviceManager.js +353 -0
  138. package/dist/web/RaftDeviceManager.js.map +1 -0
  139. package/dist/web/RaftDeviceMgrIF.d.ts +12 -0
  140. package/dist/web/RaftDeviceMgrIF.js +11 -0
  141. package/dist/web/RaftDeviceMgrIF.js.map +1 -0
  142. package/dist/web/RaftDeviceMsg.d.ts +9 -0
  143. package/dist/web/RaftDeviceMsg.js +11 -0
  144. package/dist/web/RaftDeviceMsg.js.map +1 -0
  145. package/dist/web/RaftDeviceStates.d.ts +33 -0
  146. package/dist/web/RaftDeviceStates.js +60 -0
  147. package/dist/web/RaftDeviceStates.js.map +1 -0
  148. package/dist/web/RaftFileHandler.d.ts +52 -0
  149. package/dist/web/RaftFileHandler.js +502 -0
  150. package/dist/web/RaftFileHandler.js.map +1 -0
  151. package/dist/web/RaftLog.d.ts +22 -0
  152. package/dist/web/RaftLog.js +63 -0
  153. package/dist/web/RaftLog.js.map +1 -0
  154. package/dist/web/RaftMiniHDLC.d.ts +18 -0
  155. package/dist/web/RaftMiniHDLC.js +383 -0
  156. package/dist/web/RaftMiniHDLC.js.map +1 -0
  157. package/dist/web/RaftMsgHandler.d.ts +57 -0
  158. package/dist/web/RaftMsgHandler.js +480 -0
  159. package/dist/web/RaftMsgHandler.js.map +1 -0
  160. package/dist/web/RaftMsgTrackInfo.d.ts +17 -0
  161. package/dist/web/RaftMsgTrackInfo.js +42 -0
  162. package/dist/web/RaftMsgTrackInfo.js.map +1 -0
  163. package/dist/web/RaftProtocolDefs.d.ts +30 -0
  164. package/dist/web/RaftProtocolDefs.js +48 -0
  165. package/dist/web/RaftProtocolDefs.js.map +1 -0
  166. package/dist/web/RaftStreamHandler.d.ts +38 -0
  167. package/dist/web/RaftStreamHandler.js +257 -0
  168. package/dist/web/RaftStreamHandler.js.map +1 -0
  169. package/dist/web/RaftSystemType.d.ts +25 -0
  170. package/dist/web/RaftSystemType.js +3 -0
  171. package/dist/web/RaftSystemType.js.map +1 -0
  172. package/dist/web/RaftSystemUtils.d.ts +136 -0
  173. package/dist/web/RaftSystemUtils.js +410 -0
  174. package/dist/web/RaftSystemUtils.js.map +1 -0
  175. package/dist/web/RaftTypes.d.ts +195 -0
  176. package/dist/web/RaftTypes.js +190 -0
  177. package/dist/web/RaftTypes.js.map +1 -0
  178. package/dist/web/RaftUpdateEvents.d.ts +33 -0
  179. package/dist/web/RaftUpdateEvents.js +46 -0
  180. package/dist/web/RaftUpdateEvents.js.map +1 -0
  181. package/dist/web/RaftUpdateManager.d.ts +61 -0
  182. package/dist/web/RaftUpdateManager.js +618 -0
  183. package/dist/web/RaftUpdateManager.js.map +1 -0
  184. package/dist/web/RaftUtils.d.ts +125 -0
  185. package/dist/web/RaftUtils.js +454 -0
  186. package/dist/web/RaftUtils.js.map +1 -0
  187. package/dist/web/RaftWifiTypes.d.ts +23 -0
  188. package/dist/web/RaftWifiTypes.js +43 -0
  189. package/dist/web/RaftWifiTypes.js.map +1 -0
  190. package/dist/web/main.d.ts +22 -0
  191. package/dist/web/main.js +48 -0
  192. package/dist/web/main.js.map +1 -0
  193. package/eslint.config.mjs +33 -0
  194. package/examples/dashboard/package.json +43 -0
  195. package/examples/dashboard/src/CommandPanel.tsx +147 -0
  196. package/examples/dashboard/src/ConnManager.ts +85 -0
  197. package/examples/dashboard/src/DeviceActionsForm.tsx +133 -0
  198. package/examples/dashboard/src/DeviceAttrsForm.tsx +49 -0
  199. package/examples/dashboard/src/DeviceLineChart.tsx +139 -0
  200. package/examples/dashboard/src/DevicePanel.tsx +135 -0
  201. package/examples/dashboard/src/DevicesPanel.tsx +57 -0
  202. package/examples/dashboard/src/DispLedGrid.tsx +110 -0
  203. package/examples/dashboard/src/DispOneLed.tsx +20 -0
  204. package/examples/dashboard/src/Main.tsx +106 -0
  205. package/examples/dashboard/src/StatusPanel.tsx +71 -0
  206. package/examples/dashboard/src/SystemTypeCog/CogStateInfo.ts +157 -0
  207. package/examples/dashboard/src/SystemTypeCog/SystemTypeCog.ts +84 -0
  208. package/examples/dashboard/src/SystemTypeMarty/RICAddOn.ts +70 -0
  209. package/examples/dashboard/src/SystemTypeMarty/RICAddOnBase.ts +33 -0
  210. package/examples/dashboard/src/SystemTypeMarty/RICAddOnManager.ts +342 -0
  211. package/examples/dashboard/src/SystemTypeMarty/RICCommsStats.ts +170 -0
  212. package/examples/dashboard/src/SystemTypeMarty/RICHWElem.ts +123 -0
  213. package/examples/dashboard/src/SystemTypeMarty/RICLEDPatternChecker.ts +207 -0
  214. package/examples/dashboard/src/SystemTypeMarty/RICROSSerial.ts +464 -0
  215. package/examples/dashboard/src/SystemTypeMarty/RICServoFaultDetector.ts +146 -0
  216. package/examples/dashboard/src/SystemTypeMarty/RICStateInfo.ts +78 -0
  217. package/examples/dashboard/src/SystemTypeMarty/RICSystemUtils.ts +371 -0
  218. package/examples/dashboard/src/SystemTypeMarty/RICTypes.ts +20 -0
  219. package/examples/dashboard/src/SystemTypeMarty/SystemTypeMarty.ts +116 -0
  220. package/examples/dashboard/src/index.html +15 -0
  221. package/examples/dashboard/src/index.tsx +15 -0
  222. package/examples/dashboard/src/styles.css +386 -0
  223. package/examples/dashboard/tsconfig.json +18 -0
  224. package/jest.config.js +11 -0
  225. package/package.json +59 -0
  226. package/src/RaftAttributeHandler.ts +289 -0
  227. package/src/RaftChannel.ts +30 -0
  228. package/src/RaftChannelBLE.native.ts +583 -0
  229. package/src/RaftChannelBLE.web.ts +362 -0
  230. package/src/RaftChannelBLEFactory.ts +13 -0
  231. package/src/RaftChannelBLEScanner.native.ts +190 -0
  232. package/src/RaftChannelWebSerial.ts +409 -0
  233. package/src/RaftChannelWebSocket.ts +245 -0
  234. package/src/RaftCommsStats.ts +142 -0
  235. package/src/RaftConnEvents.ts +58 -0
  236. package/src/RaftConnector.ts +737 -0
  237. package/src/RaftCustomAttrHandler.ts +54 -0
  238. package/src/RaftDeviceInfo.ts +98 -0
  239. package/src/RaftDeviceManager.ts +436 -0
  240. package/src/RaftDeviceMgrIF.ts +28 -0
  241. package/src/RaftDeviceMsg.ts +20 -0
  242. package/src/RaftDeviceStates.ts +88 -0
  243. package/src/RaftFileHandler.ts +668 -0
  244. package/src/RaftLog.ts +70 -0
  245. package/src/RaftMiniHDLC.ts +396 -0
  246. package/src/RaftMsgHandler.ts +778 -0
  247. package/src/RaftMsgTrackInfo.ts +51 -0
  248. package/src/RaftProtocolDefs.ts +46 -0
  249. package/src/RaftStreamHandler.ts +328 -0
  250. package/src/RaftSystemType.ts +29 -0
  251. package/src/RaftSystemUtils.ts +487 -0
  252. package/src/RaftTypes.ts +281 -0
  253. package/src/RaftUpdateEvents.ts +48 -0
  254. package/src/RaftUpdateManager.ts +778 -0
  255. package/src/RaftUtils.ts +484 -0
  256. package/src/RaftWifiTypes.ts +36 -0
  257. package/src/main.ts +36 -0
  258. package/testdata/TestDeviceTypeRecs.json +492 -0
  259. package/tsconfig.json +30 -0
  260. package/tsconfig.react-native.json +29 -0
@@ -0,0 +1,737 @@
1
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // RaftConnector
4
+ // Part of RaftJS
5
+ //
6
+ // Rob Dobson & Chris Greening 2020-2024
7
+ // (C) 2020-2024 All rights reserved
8
+ //
9
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10
+
11
+ import RaftChannel from "./RaftChannel";
12
+ import RaftMsgHandler, { RaftMsgResultCode } from "./RaftMsgHandler";
13
+ import RaftChannelWebSocket from "./RaftChannelWebSocket";
14
+ import RaftChannelWebSerial from "./RaftChannelWebSerial";
15
+ import RaftCommsStats from "./RaftCommsStats";
16
+ import { RaftEventFn, RaftOKFail, RaftFileSendType, RaftFileDownloadResult, RaftProgressCBType, RaftBridgeSetupResp, RaftFileDownloadFn } from "./RaftTypes";
17
+ import RaftSystemUtils from "./RaftSystemUtils";
18
+ import RaftFileHandler from "./RaftFileHandler";
19
+ import RaftStreamHandler from "./RaftStreamHandler";
20
+ import RaftLog from "./RaftLog";
21
+ import { RaftConnEvent, RaftConnEventNames } from "./RaftConnEvents";
22
+ import { RaftGetSystemTypeCBType, RaftSystemType } from "./RaftSystemType";
23
+ import { RaftUpdateEvent, RaftUpdateEventNames } from "./RaftUpdateEvents";
24
+ import RaftUpdateManager from "./RaftUpdateManager";
25
+ import { createBLEChannel } from "./RaftChannelBLEFactory";
26
+
27
+
28
+ export default class RaftConnector {
29
+
30
+ // Get system type callback
31
+ private _getSystemTypeCB: RaftGetSystemTypeCBType | null = null;
32
+
33
+ // System type
34
+ private _systemType: RaftSystemType | null = null;
35
+
36
+ // Channel
37
+ private _raftChannel: RaftChannel | null = null;
38
+
39
+ // Channel connection method and locator
40
+ private _channelConnMethod = "";
41
+ private _channelConnLocator: string | object = "";
42
+
43
+ // Comms stats
44
+ private _commsStats: RaftCommsStats = new RaftCommsStats();
45
+
46
+ // Message handler
47
+ private _raftMsgHandler: RaftMsgHandler = new RaftMsgHandler(
48
+ this._commsStats
49
+ );
50
+
51
+ // RaftSystem
52
+ private _raftSystemUtils: RaftSystemUtils = new RaftSystemUtils(this._raftMsgHandler);
53
+
54
+ // Connection performance checker
55
+ private readonly _testConnPerfBlockSize = 500;
56
+ private readonly _testConnPerfNumBlocks = 50;
57
+ private readonly _connPerfRsltDelayMs = 4000;
58
+
59
+ // Retry connection if lost
60
+ private _retryIfLostEnabled = true;
61
+ private _retryIfLostForSecs = 10;
62
+ private _retryIfLostIsConnected = false;
63
+ private _retryIfLostDisconnectTime: number | null = null;
64
+ private readonly _retryIfLostRetryDelayMs = 500;
65
+
66
+ // File handler
67
+ private _raftFileHandler: RaftFileHandler = new RaftFileHandler(
68
+ this._raftMsgHandler,
69
+ this._commsStats,
70
+ );
71
+
72
+ // Stream handler
73
+ private _raftStreamHandler: RaftStreamHandler = new RaftStreamHandler(
74
+ this._raftMsgHandler,
75
+ this._commsStats,
76
+ this
77
+ );
78
+
79
+ // Event listener
80
+ private _onEventFn: RaftEventFn | null = null;
81
+
82
+ // Update manager
83
+ private _raftUpdateManager: RaftUpdateManager | null = null;
84
+
85
+ /**
86
+ * RaftConnector constructor
87
+ * @param getSystemTypeCB - callback to get system type
88
+ */
89
+ public constructor(getSystemTypeCB: RaftGetSystemTypeCBType | null = null) {
90
+
91
+ // Get system type callback
92
+ this._getSystemTypeCB = getSystemTypeCB;
93
+
94
+ // Debug
95
+ RaftLog.debug('RaftConnector starting up');
96
+ }
97
+
98
+ /**
99
+ * Configure the file handler
100
+ * @param fileBlockSize - size of file blocks to send
101
+ * @param batchAckSize - number of blocks to send before waiting for ack
102
+ * @returns void
103
+ */
104
+ configureFileHandler(fileBlockSize: number, batchAckSize: number) {
105
+ this._raftFileHandler.setRequestedFileBlockSize(fileBlockSize);
106
+ this._raftFileHandler.setRequestedBatchAckSize(batchAckSize);
107
+ }
108
+
109
+ /**
110
+ * Set event listener
111
+ * @param onEventFn - event listener
112
+ * @returns void
113
+ * */
114
+ setEventListener(onEventFn: RaftEventFn): void {
115
+ this._onEventFn = onEventFn;
116
+ }
117
+
118
+ /**
119
+ * isConnected
120
+ * @returns boolean - true if connected
121
+ * */
122
+ isConnected() {
123
+ // Check if connected
124
+ const isConnected = this._retryIfLostIsConnected || (this._raftChannel ? this._raftChannel.isConnected() : false);
125
+ return isConnected;
126
+ }
127
+
128
+ /**
129
+ * Set try to reconnect if connection lost
130
+ * @param enableRetry - true to enable retry
131
+ * @param retryForSecs - retry for this many seconds
132
+ * @returns void
133
+ * */
134
+ setRetryConnectionIfLost(enableRetry: boolean, retryForSecs: number): void {
135
+ this._retryIfLostEnabled = enableRetry;
136
+ this._retryIfLostForSecs = retryForSecs;
137
+ if (!this._retryIfLostEnabled) {
138
+ this._retryIfLostIsConnected = false;
139
+ }
140
+ RaftLog.debug(`setRetryConnectionIfLost ${enableRetry} retry for ${retryForSecs}`);
141
+ }
142
+
143
+ /**
144
+ * Get Raft system type (the type of hardware connected to - determined using the getSystemInfo API)
145
+ * @returns RaftSystemType | null - Raft system type
146
+ * */
147
+ getSystemType(): RaftSystemType | null {
148
+ return this._systemType;
149
+ }
150
+
151
+ /**
152
+ * Get connection method
153
+ * @returns string - connection method
154
+ * */
155
+ getConnMethod(): string {
156
+ return this._channelConnMethod;
157
+ }
158
+
159
+ /**
160
+ * Get connection locator
161
+ * @returns string | object - connection locator
162
+ * */
163
+ getConnLocator(): any | null {
164
+ return this._raftChannel ? this._raftChannel.getConnectedLocator() : null;
165
+ }
166
+
167
+ /**
168
+ * Get Raft channel (this is the channel used for commuinications with the Raft application)
169
+ * @returns RaftChannel | null - Raft channel
170
+ * */
171
+ getRaftChannel(): RaftChannel | null {
172
+ return this._raftChannel;
173
+ }
174
+
175
+ /**
176
+ * Get Raft system utils (access to system information and control)
177
+ * @returns RaftSystemUtils - Raft system utils
178
+ * */
179
+ getRaftSystemUtils(): RaftSystemUtils {
180
+ return this._raftSystemUtils;
181
+ }
182
+
183
+ /**
184
+ * Get communication stats
185
+ * @returns RaftCommsStats - communication stats
186
+ * */
187
+ getCommsStats(): RaftCommsStats {
188
+ return this._commsStats;
189
+ }
190
+
191
+ /**
192
+ * Get Raft message handler (to allow message sending and receiving)
193
+ * @returns RaftMsgHandler - Raft message handler
194
+ * */
195
+ getRaftMsgHandler(): RaftMsgHandler {
196
+ return this._raftMsgHandler;
197
+ }
198
+
199
+ /**
200
+ * Pause connection
201
+ * @param pause - true to pause, false to resume
202
+ */
203
+ pauseConnection(pause = true) {
204
+ if (this._raftChannel) this._raftChannel.pauseConnection(pause);
205
+ }
206
+
207
+ /**
208
+ * Initialize the Raft channel
209
+ */
210
+ async initializeChannel(method: string): Promise<boolean> {
211
+ // Initialize raft channel
212
+ if (method === 'WebBLE' || method === 'PhoneBLE') {
213
+ const RaftChannelBLE = createBLEChannel();
214
+ this._raftChannel = new RaftChannelBLE();
215
+ this._channelConnMethod = method;
216
+ } else if (method === 'WebSocket' || method === 'wifi') {
217
+ this._raftChannel = new RaftChannelWebSocket();
218
+ this._channelConnMethod = 'WebSocket';
219
+ } else if (method === 'WebSerial') {
220
+ this._raftChannel = new RaftChannelWebSerial();
221
+ this._channelConnMethod = 'WebSerial';
222
+ } else {
223
+ RaftLog.error('Unknown method: ' + method);
224
+ return false;
225
+ }
226
+
227
+ // Check channel established
228
+ if (this._raftChannel !== null) {
229
+ // Set message handler
230
+ this._raftChannel.setMsgHandler(this._raftMsgHandler);
231
+ this._raftChannel.setOnConnEvent(this.onConnEvent.bind(this));
232
+
233
+ // Message handling in and out
234
+ this._raftMsgHandler.registerForResults(this);
235
+ this._raftMsgHandler.registerMsgSender(this._raftChannel);
236
+
237
+ return true;
238
+ } else {
239
+ this._channelConnMethod = "";
240
+ return false;
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Connect to a Raft device
246
+ *
247
+ * @param {string | object} locator - either a string (WebSocket URL or serial port) or an object (WebBLE)
248
+ * @returns Promise<boolean>
249
+ *
250
+ */
251
+ async connect(locator: string | object): Promise<boolean> {
252
+ if (!this._raftChannel) {
253
+ RaftLog.error('Raft channel is not initialized.');
254
+ return false;
255
+ }
256
+
257
+ // Store locator
258
+ this._channelConnLocator = locator;
259
+
260
+ // Connect
261
+ let connOk = false;
262
+ try {
263
+ // Event
264
+ this.onConnEvent(RaftConnEvent.CONN_CONNECTING);
265
+
266
+ // Connect
267
+ connOk = await this._connectToChannel();
268
+ } catch (err) {
269
+ RaftLog.error('RaftConnector.connect - error: ' + err);
270
+ }
271
+
272
+ if (connOk) {
273
+ // Get system type
274
+ if (this._getSystemTypeCB) {
275
+ // Get system type
276
+ this._systemType = await this._getSystemTypeCB(this._raftSystemUtils);
277
+
278
+ // Set defaults
279
+ if (this._systemType) {
280
+ this._raftSystemUtils.setDefaultWiFiHostname(this._systemType.defaultWiFiHostname);
281
+ }
282
+ }
283
+
284
+ // Setup system type
285
+ if (this._systemType) {
286
+ this._systemType.setup(this._raftSystemUtils, this._onEventFn);
287
+ }
288
+
289
+ // Check if subscription required
290
+ if (this._systemType &&
291
+ this._systemType.subscribeForUpdates &&
292
+ this._raftChannel.requiresSubscription()) {
293
+ try {
294
+ // Subscription
295
+ await this._systemType.subscribeForUpdates(this._raftSystemUtils, true);
296
+ RaftLog.info(`connect subscribed for updates`);
297
+ } catch (error: unknown) {
298
+ RaftLog.warn(`connect subscribe for updates failed ${error}`)
299
+ }
300
+ }
301
+
302
+ // Send connected event
303
+ this.onConnEvent(RaftConnEvent.CONN_CONNECTED);
304
+
305
+ } else {
306
+ // Failed Event
307
+ this.onConnEvent(RaftConnEvent.CONN_CONNECTION_FAILED);
308
+ // configure file handler
309
+ this.configureFileHandler(this._raftChannel.fhFileBlockSize(), this._raftChannel.fhBatchAckSize());
310
+ }
311
+
312
+ return connOk;
313
+ }
314
+
315
+ async disconnect(): Promise<void> {
316
+ // Disconnect
317
+ this._retryIfLostIsConnected = false;
318
+ if (this._raftChannel) {
319
+ // Check if there is a RICREST command to send before disconnecting
320
+ const ricRestCommand = this._raftChannel.ricRestCmdBeforeDisconnect();
321
+ console.log(`sending RICREST command before disconnect: ${ricRestCommand}`);
322
+ if (ricRestCommand) {
323
+ await this.sendRICRESTMsg(ricRestCommand, {});
324
+ }
325
+ // await this.sendRICRESTMsg("bledisc", {});
326
+ await this._raftChannel.disconnect();
327
+ this._raftChannel = null;
328
+ }
329
+ }
330
+
331
+ // Mark: Tx Message handling -----------------------------------------------------------------------------------------
332
+
333
+ /**
334
+ *
335
+ * sendRICRESTMsg
336
+ * @param commandName command API string
337
+ * @param params parameters (simple name value pairs only) to parameterize trajectory
338
+ * @returns Promise<RaftOKFail>
339
+ *
340
+ */
341
+ async sendRICRESTMsg(commandName: string, params: object,
342
+ bridgeID: number | undefined = undefined): Promise<RaftOKFail> {
343
+ try {
344
+ // Format the paramList as query string
345
+ const paramEntries = Object.entries(params);
346
+ let paramQueryStr = '';
347
+ for (const param of paramEntries) {
348
+ if (paramQueryStr.length > 0) paramQueryStr += '&';
349
+ paramQueryStr += param[0] + '=' + param[1];
350
+ }
351
+ // Format the url to send
352
+ if (paramQueryStr.length > 0) commandName += '?' + paramQueryStr;
353
+ return await this._raftMsgHandler.sendRICRESTURL<RaftOKFail>(commandName, bridgeID);
354
+ } catch (error) {
355
+ RaftLog.warn(`sendRICRESTMsg failed ${error}`);
356
+ return new RaftOKFail();
357
+ }
358
+ }
359
+
360
+ // Mark: Rx Message handling -----------------------------------------------------------------------------------------
361
+
362
+ /**
363
+ * onRxReply - handle a reply message
364
+ * @param msgHandle number indicating the message that is being replied to (from the original message)
365
+ * @param msgRsltCode result code
366
+ * @param msgRsltJsonObj result object
367
+ */
368
+ onRxReply(
369
+ msgHandle: number,
370
+ msgRsltCode: RaftMsgResultCode,
371
+ msgRsltJsonObj: object | null,
372
+ ): void {
373
+ RaftLog.verbose(
374
+ `onRxReply msgHandle ${msgHandle} rsltCode ${msgRsltCode} obj ${JSON.stringify(
375
+ msgRsltJsonObj,
376
+ )}`,
377
+ );
378
+ }
379
+
380
+ /**
381
+ * onRxUnnumberedMsg - handle an unnumbered message
382
+ * @param msgRsltJsonObj result object
383
+ */
384
+ onRxUnnumberedMsg(msgRsltJsonObj: { [key: string]: number | string }): void {
385
+ RaftLog.verbose(
386
+ `onRxUnnumberedMsg rsltCode obj ${JSON.stringify(msgRsltJsonObj)}`,
387
+ );
388
+
389
+ // Inform the file handler
390
+ if ('okto' in msgRsltJsonObj) {
391
+ this._raftFileHandler.onOktoMsg(msgRsltJsonObj.okto as number);
392
+ } else if ('sokto' in msgRsltJsonObj) {
393
+ this._raftStreamHandler.onSoktoMsg(msgRsltJsonObj.sokto as number);
394
+ }
395
+ }
396
+
397
+ /**
398
+ * onRxFileBlock - handle a file block
399
+ * @param filePos file position
400
+ * @param fileBlockData file block data
401
+ */
402
+ onRxFileBlock(
403
+ filePos: number,
404
+ fileBlockData: Uint8Array
405
+ ): void {
406
+ // RaftLog.info(`onRxFileBlock filePos ${filePos} fileBlockData ${RaftUtils.bufferToHex(fileBlockData)}`);
407
+ this._raftFileHandler.onFileBlock(filePos, fileBlockData);
408
+ }
409
+
410
+
411
+ // Mark: Handling of other message types -----------------------------------------------------------------------------------------
412
+
413
+ /**
414
+ * onRxOtherMsgType - handle other message types
415
+ * @param payload message payload
416
+ * @param frameTimeMs time of frame
417
+ */
418
+ onRxOtherMsgType(payload: Uint8Array, _frameTimeMs: number): void {
419
+ // RaftLog.debug(`onRxOtherMsgType payload ${RaftUtils.bufferToHex(payload)}`);
420
+ RaftLog.verbose(`onRxOtherMsgType payloadLen ${payload.length}`);
421
+
422
+ // Handle other messages
423
+ if (this._systemType && this._systemType.rxOtherMsgType) {
424
+ this._systemType.rxOtherMsgType(payload, _frameTimeMs);
425
+ }
426
+ }
427
+
428
+ // Mark: File sending --------------------------------------------------------------------------------
429
+
430
+ /**
431
+ * sendFile - send a file
432
+ * @param fileName name of file to send
433
+ * @param fileContents file contents
434
+ * @param progressCallback callback to receive progress updates
435
+ * @returns Promise<boolean> - true if file sent successfully
436
+ */
437
+ async sendFile(fileName: string,
438
+ fileContents: Uint8Array,
439
+ progressCallback: ((sent: number, total: number, progress: number) => void) | undefined,
440
+ ): Promise<boolean> {
441
+ return this._raftFileHandler.fileSend(fileName, RaftFileSendType.NORMAL_FILE, "fs", fileContents, progressCallback);
442
+ }
443
+
444
+ // Mark: Streaming --------------------------------------------------------------------------------
445
+
446
+ /**
447
+ * streamAudio - stream audio
448
+ * @param streamContents audio data
449
+ * @param clearExisting true to clear existing audio
450
+ * @param duration duration of audio
451
+ */
452
+ streamAudio(streamContents: Uint8Array, clearExisting: boolean, duration: number): void {
453
+ if (this._raftStreamHandler && this.isConnected()) {
454
+ this._raftStreamHandler.streamAudio(streamContents, clearExisting, duration);
455
+ }
456
+ }
457
+
458
+ /**
459
+ * isStreamStarting - check if stream is starting
460
+ */
461
+ isStreamStarting() {
462
+ return this._raftStreamHandler.isStreamStarting();
463
+ }
464
+
465
+ // Mark: File system --------------------------------------------------------------------------------
466
+
467
+ /**
468
+ * fsGetContents - get file contents
469
+ * @param fileName name of file to get
470
+ * @param fileSource source of file to get (e.g. "fs" or "bridgeserial1", if omitted defaults to "fs")
471
+ * @param progressCallback callback to receive progress updates
472
+ * @returns Promise<RaftFileDownloadResult>
473
+ */
474
+ async fsGetContents(fileName: string,
475
+ fileSource: string,
476
+ progressCallback: RaftProgressCBType | undefined): Promise<RaftFileDownloadResult> {
477
+ return await this._raftFileHandler.fileReceive(fileName, fileSource, progressCallback);
478
+ }
479
+
480
+ /**
481
+ * setLegacySoktoMode - set legacy sokto mode
482
+ * @param legacyMode true to set legacy mode
483
+ */
484
+ setLegacySoktoMode(legacyMode: boolean) {
485
+ return this._raftStreamHandler.setLegacySoktoMode(legacyMode);
486
+ }
487
+
488
+ // Mark: Bridge serial --------------------------------------------------------------------------------
489
+
490
+ /**
491
+ * createCommsBridge - create a comms bridge
492
+ * @param bridgeSource source of bridge (e.g. "Serial1")
493
+ * @param bridgeName name of bridge
494
+ * @param idleCloseSecs idle close time seconds
495
+ * @returns Promise<RaftBridgeSetupResp>
496
+ */
497
+ async createCommsBridge(bridgeSource: string, bridgeName: string, idleCloseSecs = 0): Promise<RaftBridgeSetupResp> {
498
+ return await this._raftMsgHandler.createCommsBridge(bridgeSource, bridgeName, idleCloseSecs);
499
+ }
500
+
501
+ // Mark: Connection performance--------------------------------------------------------------------------
502
+
503
+ /**
504
+ * ParkMiller random number generator
505
+ * @param seed
506
+ * @returns number
507
+ */
508
+ private parkmiller_next(seed: number) {
509
+ const hi = Math.round(16807 * (seed & 0xffff));
510
+ let lo = Math.round(16807 * (seed >> 16));
511
+ lo += (hi & 0x7fff) << 16;
512
+ lo += hi >> 15;
513
+ if (lo > 0x7fffffff)
514
+ lo -= 0x7fffffff;
515
+ return lo;
516
+ }
517
+
518
+ /**
519
+ * checkConnPerformance - check connection performance
520
+ * @returns Promise<number | undefined> - connection performance
521
+ */
522
+ async checkConnPerformance(): Promise<number | undefined> {
523
+
524
+ // Sends a magic sequence of bytes followed by blocks of random data
525
+ // these will be ignored by the Raft library (as it recognises magic sequence)
526
+ // and is used performance evaluation
527
+ let prbsState = 1;
528
+ const testData = new Uint8Array(this._testConnPerfBlockSize);
529
+ for (let i = 0; i < this._testConnPerfNumBlocks; i++) {
530
+ testData.set([0, (i >> 24) & 0xff, (i >> 16) & 0xff, (i >> 8) & 0xff, i & 0xff, 0x1f, 0x9d, 0xf4, 0x7a, 0xb5]);
531
+ for (let j = 10; j < this._testConnPerfBlockSize; j++) {
532
+ prbsState = this.parkmiller_next(prbsState);
533
+ testData[j] = prbsState & 0xff;
534
+ }
535
+ if (this._raftChannel) {
536
+ await this._raftChannel.sendTxMsg(testData, false);
537
+ }
538
+ }
539
+
540
+ // Wait a little to allow the Raft app to process the data
541
+ await new Promise(resolve => setTimeout(resolve, this._connPerfRsltDelayMs));
542
+
543
+ // Get performance
544
+ const blePerf = await this._raftSystemUtils.getSysModInfoBLEMan();
545
+ if (blePerf) {
546
+ console.log(`checkConnPerformance result rate = ${blePerf.tBPS}BytesPS`);
547
+ return blePerf.tBPS;
548
+ } else {
549
+ throw new Error('checkConnPerformance: failed to get BLE performance');
550
+ }
551
+ }
552
+
553
+ // Mark: Connection event --------------------------------------------------------------------------
554
+
555
+ /**
556
+ * onConnEvent - handle connection event
557
+ * @param eventEnum connection event enumeration
558
+ * @param data data associated with event
559
+ * @returns void
560
+ */
561
+ onConnEvent(eventEnum: RaftConnEvent, data: object | string | null | undefined = undefined): void {
562
+ // Handle information clearing on disconnect
563
+ switch (eventEnum) {
564
+ case RaftConnEvent.CONN_DISCONNECTED:
565
+
566
+ // Disconnect time
567
+ this._retryIfLostDisconnectTime = Date.now();
568
+
569
+ // Check if retry required
570
+ if (this._retryIfLostIsConnected && this._retryIfLostEnabled) {
571
+
572
+ // Indicate connection disrupted
573
+ if (this._onEventFn) {
574
+ this._onEventFn("conn", RaftConnEvent.CONN_ISSUE_DETECTED, RaftConnEventNames[RaftConnEvent.CONN_ISSUE_DETECTED]);
575
+ }
576
+
577
+ // Retry connection
578
+ this._retryConnection();
579
+
580
+ // Don't allow disconnection to propagate until retries have occurred
581
+ return;
582
+
583
+ }
584
+
585
+ // Invalidate connection details
586
+ this._raftSystemUtils.invalidate();
587
+
588
+ // Invalidate system-type info
589
+ if (this._systemType && this._systemType.stateIsInvalid) {
590
+ this._systemType.stateIsInvalid();
591
+ }
592
+ break;
593
+ }
594
+ // Notify
595
+ if (this._onEventFn) {
596
+ this._onEventFn("conn", eventEnum, RaftConnEventNames[eventEnum], data);
597
+ }
598
+ }
599
+
600
+ /**
601
+ * Retry connection
602
+ */
603
+ private _retryConnection(): void {
604
+
605
+ // Check timeout
606
+ if ((this._retryIfLostDisconnectTime !== null) &&
607
+ (Date.now() - this._retryIfLostDisconnectTime < this._retryIfLostForSecs * 1000)) {
608
+
609
+ // Set timer to try to reconnect
610
+ setTimeout(async () => {
611
+
612
+ // Try to connect
613
+ const isConn = await this._connectToChannel();
614
+ if (!isConn) {
615
+ this._retryConnection();
616
+ } else {
617
+
618
+ // No longer retrying
619
+ this._retryIfLostDisconnectTime = null;
620
+
621
+ // Indicate connection problem resolved
622
+ if (this._onEventFn) {
623
+ this._onEventFn("conn", RaftConnEvent.CONN_ISSUE_RESOLVED, RaftConnEventNames[RaftConnEvent.CONN_ISSUE_RESOLVED]);
624
+ }
625
+
626
+ }
627
+ }, this._retryIfLostRetryDelayMs);
628
+ } else {
629
+
630
+ // No longer connected after retry timeout
631
+ this._retryIfLostIsConnected = false;
632
+
633
+ // Indicate disconnection
634
+ if (this._onEventFn) {
635
+ this._onEventFn("conn", RaftConnEvent.CONN_DISCONNECTED, RaftConnEventNames[RaftConnEvent.CONN_DISCONNECTED]);
636
+ }
637
+
638
+ // Invalidate connection details
639
+ this._raftSystemUtils.invalidate();
640
+
641
+ // Invalidate system-type info
642
+ if (this._systemType && this._systemType.stateIsInvalid) {
643
+ this._systemType.stateIsInvalid();
644
+ }
645
+ }
646
+ }
647
+
648
+ /**
649
+ * Connect to channel
650
+ * @returns Promise<boolean> - true if connected
651
+ */
652
+ private async _connectToChannel(): Promise<boolean> {
653
+ // Connect
654
+ try {
655
+ if (this._raftChannel) {
656
+ const connected = await this._raftChannel.connect(this._channelConnLocator, this._systemType ? this._systemType.connectorOptions : {});
657
+ if (connected) {
658
+ this._retryIfLostIsConnected = true;
659
+ return true;
660
+ }
661
+ }
662
+ } catch (error) {
663
+ RaftLog.error(`RaftConnector.connect() error: ${error}`);
664
+ }
665
+ return false;
666
+ }
667
+
668
+ // Mark: OTA Update -----------------------------------------------------------------------------------------
669
+
670
+ /**
671
+ * onUpdateEvent - handle update event
672
+ * @param eventEnum
673
+ * @param data
674
+ */
675
+ _onUpdateEvent(eventEnum: RaftUpdateEvent, data: object | string | null | undefined = undefined): void {
676
+ // Notify
677
+ if (this._onEventFn) {
678
+ this._onEventFn("ota", eventEnum, RaftUpdateEventNames[eventEnum], data);
679
+ }
680
+ }
681
+
682
+ /**
683
+ * otaUpdateCheck - check for OTA update
684
+ * @returns Promise<RaftUpdateEvent> - update event
685
+ * */
686
+ async otaUpdateCheck(): Promise<RaftUpdateEvent> {
687
+ if (!this._raftUpdateManager)
688
+ return RaftUpdateEvent.UPDATE_NOT_CONFIGURED;
689
+ return await this._raftUpdateManager.checkForUpdate(this._raftSystemUtils.getCachedSystemInfo());
690
+ }
691
+
692
+ /**
693
+ * otaUpdateStart - start OTA update
694
+ * @returns Promise<RaftUpdateEvent> - update event
695
+ * */
696
+ async otaUpdateStart(): Promise<RaftUpdateEvent> {
697
+ if (!this._raftUpdateManager)
698
+ return RaftUpdateEvent.UPDATE_NOT_CONFIGURED;
699
+ return await this._raftUpdateManager.firmwareUpdate();
700
+ }
701
+
702
+ /**
703
+ * otaUpdateCancel - cancel OTA update
704
+ * @returns Promise<void>
705
+ * */
706
+ async otaUpdateCancel(): Promise<void> {
707
+ if (!this._raftUpdateManager)
708
+ return;
709
+ return await this._raftUpdateManager.firmwareUpdateCancel();
710
+ }
711
+
712
+ /**
713
+ * setupUpdateManager - setup the update manager
714
+ * @param appVersion - app version
715
+ * @param appUpdateURL - app update URL
716
+ * @param firmwareBaseURL - firmware base URL
717
+ * @param fileDownloader - file downloader
718
+ * @returns void
719
+ * */
720
+ setupUpdateManager(appVersion: string, appUpdateURL: string, firmwareBaseURL: string, fileDownloader: RaftFileDownloadFn): void {
721
+ // Setup update manager
722
+ const firmwareTypeStrForMainFw = 'main';
723
+ this._raftUpdateManager = new RaftUpdateManager(
724
+ this._systemType,
725
+ this._raftMsgHandler,
726
+ this._raftFileHandler,
727
+ this._raftSystemUtils,
728
+ this._onUpdateEvent.bind(this),
729
+ firmwareTypeStrForMainFw,
730
+ appVersion,
731
+ fileDownloader,
732
+ appUpdateURL,
733
+ firmwareBaseURL,
734
+ this._raftChannel
735
+ );
736
+ }
737
+ }