@robdobsn/raftjs 1.8.5 → 1.11.5

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 (240) hide show
  1. package/.editorconfig +14 -0
  2. package/.gitattributes +11 -0
  3. package/.nvmrc +1 -0
  4. package/TODO.md +1 -0
  5. package/dist/react-native/RaftAttributeHandler.d.ts +14 -0
  6. package/dist/react-native/RaftAttributeHandler.js +375 -0
  7. package/dist/react-native/RaftAttributeHandler.js.map +1 -0
  8. package/dist/react-native/RaftChannel.d.ts +20 -0
  9. package/dist/react-native/RaftChannel.js +12 -0
  10. package/dist/react-native/RaftChannel.js.map +1 -0
  11. package/dist/react-native/RaftChannelBLE.native.d.ts +95 -0
  12. package/dist/react-native/RaftChannelBLE.native.js +483 -0
  13. package/dist/react-native/RaftChannelBLE.native.js.map +1 -0
  14. package/dist/react-native/RaftChannelBLE.web.d.ts +40 -0
  15. package/dist/react-native/RaftChannelBLE.web.js +302 -0
  16. package/dist/react-native/RaftChannelBLE.web.js.map +1 -0
  17. package/dist/react-native/RaftChannelBLEFactory.d.ts +10 -0
  18. package/dist/react-native/RaftChannelBLEFactory.js +17 -0
  19. package/dist/react-native/RaftChannelBLEFactory.js.map +1 -0
  20. package/dist/react-native/RaftChannelBLEScanner.native.d.ts +18 -0
  21. package/dist/react-native/RaftChannelBLEScanner.native.js +138 -0
  22. package/dist/react-native/RaftChannelBLEScanner.native.js.map +1 -0
  23. package/dist/react-native/RaftChannelSimulated.d.ts +42 -0
  24. package/dist/react-native/RaftChannelSimulated.js +1001 -0
  25. package/dist/react-native/RaftChannelSimulated.js.map +1 -0
  26. package/dist/react-native/RaftChannelWebSerial.d.ts +39 -0
  27. package/dist/react-native/RaftChannelWebSerial.js +329 -0
  28. package/dist/react-native/RaftChannelWebSerial.js.map +1 -0
  29. package/dist/react-native/RaftChannelWebSocket.d.ts +30 -0
  30. package/dist/react-native/RaftChannelWebSocket.js +222 -0
  31. package/dist/react-native/RaftChannelWebSocket.js.map +1 -0
  32. package/dist/react-native/RaftCommsStats.d.ts +39 -0
  33. package/dist/react-native/RaftCommsStats.js +128 -0
  34. package/dist/react-native/RaftCommsStats.js.map +1 -0
  35. package/dist/react-native/RaftConnEvents.d.ts +39 -0
  36. package/dist/react-native/RaftConnEvents.js +54 -0
  37. package/dist/react-native/RaftConnEvents.js.map +1 -0
  38. package/dist/react-native/RaftConnector.d.ts +257 -0
  39. package/dist/react-native/RaftConnector.js +671 -0
  40. package/dist/react-native/RaftConnector.js.map +1 -0
  41. package/dist/react-native/RaftCustomAttrHandler.d.ts +6 -0
  42. package/dist/react-native/RaftCustomAttrHandler.js +93 -0
  43. package/dist/react-native/RaftCustomAttrHandler.js.map +1 -0
  44. package/dist/react-native/RaftDeviceInfo.d.ts +71 -0
  45. package/dist/react-native/RaftDeviceInfo.js +50 -0
  46. package/dist/react-native/RaftDeviceInfo.js.map +1 -0
  47. package/dist/react-native/RaftDeviceManager.d.ts +73 -0
  48. package/dist/react-native/RaftDeviceManager.js +812 -0
  49. package/dist/react-native/RaftDeviceManager.js.map +1 -0
  50. package/dist/react-native/RaftDeviceMgrIF.d.ts +19 -0
  51. package/dist/react-native/RaftDeviceMgrIF.js +11 -0
  52. package/dist/react-native/RaftDeviceMgrIF.js.map +1 -0
  53. package/dist/react-native/RaftDeviceMsg.d.ts +9 -0
  54. package/dist/react-native/RaftDeviceMsg.js +11 -0
  55. package/dist/react-native/RaftDeviceMsg.js.map +1 -0
  56. package/dist/react-native/RaftDeviceStates.d.ts +55 -0
  57. package/dist/react-native/RaftDeviceStates.js +81 -0
  58. package/dist/react-native/RaftDeviceStates.js.map +1 -0
  59. package/dist/react-native/RaftFileHandler.d.ts +52 -0
  60. package/dist/react-native/RaftFileHandler.js +502 -0
  61. package/dist/react-native/RaftFileHandler.js.map +1 -0
  62. package/dist/react-native/RaftLog.d.ts +22 -0
  63. package/dist/react-native/RaftLog.js +63 -0
  64. package/dist/react-native/RaftLog.js.map +1 -0
  65. package/dist/react-native/RaftMiniHDLC.d.ts +18 -0
  66. package/dist/react-native/RaftMiniHDLC.js +383 -0
  67. package/dist/react-native/RaftMiniHDLC.js.map +1 -0
  68. package/dist/react-native/RaftMsgHandler.d.ts +62 -0
  69. package/dist/react-native/RaftMsgHandler.js +511 -0
  70. package/dist/react-native/RaftMsgHandler.js.map +1 -0
  71. package/dist/react-native/RaftMsgTrackInfo.d.ts +17 -0
  72. package/dist/react-native/RaftMsgTrackInfo.js +42 -0
  73. package/dist/react-native/RaftMsgTrackInfo.js.map +1 -0
  74. package/dist/react-native/RaftProtocolDefs.d.ts +30 -0
  75. package/dist/react-native/RaftProtocolDefs.js +48 -0
  76. package/dist/react-native/RaftProtocolDefs.js.map +1 -0
  77. package/dist/react-native/RaftPublish.d.ts +2 -0
  78. package/dist/react-native/RaftPublish.js +81 -0
  79. package/dist/react-native/RaftPublish.js.map +1 -0
  80. package/dist/react-native/RaftStreamHandler.d.ts +49 -0
  81. package/dist/react-native/RaftStreamHandler.js +324 -0
  82. package/dist/react-native/RaftStreamHandler.js.map +1 -0
  83. package/dist/react-native/RaftStruct.d.ts +3 -0
  84. package/dist/react-native/RaftStruct.js +258 -0
  85. package/dist/react-native/RaftStruct.js.map +1 -0
  86. package/dist/react-native/RaftSysTypeManager.d.ts +16 -0
  87. package/dist/react-native/RaftSysTypeManager.js +78 -0
  88. package/dist/react-native/RaftSysTypeManager.js.map +1 -0
  89. package/dist/react-native/RaftSystemType.d.ts +30 -0
  90. package/dist/react-native/RaftSystemType.js +3 -0
  91. package/dist/react-native/RaftSystemType.js.map +1 -0
  92. package/dist/react-native/RaftSystemUtils.d.ts +152 -0
  93. package/dist/react-native/RaftSystemUtils.js +463 -0
  94. package/dist/react-native/RaftSystemUtils.js.map +1 -0
  95. package/dist/react-native/RaftTypes.d.ts +216 -0
  96. package/dist/react-native/RaftTypes.js +153 -0
  97. package/dist/react-native/RaftTypes.js.map +1 -0
  98. package/dist/react-native/RaftUpdateEvents.d.ts +33 -0
  99. package/dist/react-native/RaftUpdateEvents.js +46 -0
  100. package/dist/react-native/RaftUpdateEvents.js.map +1 -0
  101. package/dist/react-native/RaftUpdateManager.d.ts +61 -0
  102. package/dist/react-native/RaftUpdateManager.js +621 -0
  103. package/dist/react-native/RaftUpdateManager.js.map +1 -0
  104. package/dist/react-native/RaftUtils.d.ts +128 -0
  105. package/dist/react-native/RaftUtils.js +487 -0
  106. package/dist/react-native/RaftUtils.js.map +1 -0
  107. package/dist/react-native/RaftWifiTypes.d.ts +23 -0
  108. package/dist/react-native/RaftWifiTypes.js +43 -0
  109. package/dist/react-native/RaftWifiTypes.js.map +1 -0
  110. package/dist/react-native/main.d.ts +27 -0
  111. package/dist/react-native/main.js +52 -0
  112. package/dist/react-native/main.js.map +1 -0
  113. package/dist/web/RaftAttributeHandler.js +1 -1
  114. package/dist/web/RaftAttributeHandler.js.map +1 -1
  115. package/dist/web/RaftChannelBLE.web.js +8 -6
  116. package/dist/web/RaftChannelBLE.web.js.map +1 -1
  117. package/dist/web/RaftChannelSimulated.d.ts +10 -0
  118. package/dist/web/RaftChannelSimulated.js +665 -82
  119. package/dist/web/RaftChannelSimulated.js.map +1 -1
  120. package/dist/web/RaftChannelWebSerial.js +2 -2
  121. package/dist/web/RaftChannelWebSerial.js.map +1 -1
  122. package/dist/web/RaftChannelWebSocket.js +16 -1
  123. package/dist/web/RaftChannelWebSocket.js.map +1 -1
  124. package/dist/web/RaftConnector.d.ts +12 -1
  125. package/dist/web/RaftConnector.js +45 -9
  126. package/dist/web/RaftConnector.js.map +1 -1
  127. package/dist/web/RaftCustomAttrHandler.d.ts +2 -0
  128. package/dist/web/RaftCustomAttrHandler.js +54 -26
  129. package/dist/web/RaftCustomAttrHandler.js.map +1 -1
  130. package/dist/web/RaftDeviceInfo.d.ts +3 -1
  131. package/dist/web/RaftDeviceInfo.js +17 -3
  132. package/dist/web/RaftDeviceInfo.js.map +1 -1
  133. package/dist/web/RaftDeviceManager.d.ts +32 -2
  134. package/dist/web/RaftDeviceManager.js +307 -74
  135. package/dist/web/RaftDeviceManager.js.map +1 -1
  136. package/dist/web/RaftDeviceMgrIF.d.ts +5 -1
  137. package/dist/web/RaftDeviceStates.d.ts +20 -2
  138. package/dist/web/RaftDeviceStates.js +25 -4
  139. package/dist/web/RaftDeviceStates.js.map +1 -1
  140. package/dist/web/RaftMsgHandler.js.map +1 -1
  141. package/dist/web/RaftPublish.d.ts +2 -0
  142. package/dist/web/RaftPublish.js +81 -0
  143. package/dist/web/RaftPublish.js.map +1 -0
  144. package/dist/web/RaftStreamHandler.d.ts +11 -0
  145. package/dist/web/RaftStreamHandler.js +68 -1
  146. package/dist/web/RaftStreamHandler.js.map +1 -1
  147. package/dist/web/RaftStruct.js +197 -147
  148. package/dist/web/RaftStruct.js.map +1 -1
  149. package/dist/web/RaftSystemUtils.d.ts +17 -1
  150. package/dist/web/RaftSystemUtils.js +51 -0
  151. package/dist/web/RaftSystemUtils.js.map +1 -1
  152. package/dist/web/RaftTypes.d.ts +21 -0
  153. package/dist/web/RaftTypes.js.map +1 -1
  154. package/dist/web/RaftUpdateManager.js +1 -1
  155. package/dist/web/RaftUpdateManager.js.map +1 -1
  156. package/dist/web/RaftUtils.d.ts +2 -0
  157. package/dist/web/RaftUtils.js +20 -0
  158. package/dist/web/RaftUtils.js.map +1 -1
  159. package/dist/web/main.d.ts +2 -0
  160. package/dist/web/main.js +1 -0
  161. package/dist/web/main.js.map +1 -1
  162. package/eslint.config.mjs +33 -0
  163. package/examples/dashboard/package.json +36 -0
  164. package/examples/dashboard/src/CommandPanel.tsx +147 -0
  165. package/examples/dashboard/src/ConnManager.ts +166 -0
  166. package/examples/dashboard/src/DeviceActionsForm.tsx +133 -0
  167. package/examples/dashboard/src/DeviceAttrsForm.tsx +49 -0
  168. package/examples/dashboard/src/DeviceLineChart.tsx +163 -0
  169. package/examples/dashboard/src/DevicePanel.tsx +247 -0
  170. package/examples/dashboard/src/DeviceStatsPanel.tsx +65 -0
  171. package/examples/dashboard/src/DevicesPanel.tsx +69 -0
  172. package/examples/dashboard/src/DispLedGrid.tsx +110 -0
  173. package/examples/dashboard/src/DispOneLed.tsx +20 -0
  174. package/examples/dashboard/src/LatencyTest.ts +130 -0
  175. package/examples/dashboard/src/LatencyTestPanel.tsx +92 -0
  176. package/examples/dashboard/src/Main.tsx +234 -0
  177. package/examples/dashboard/src/SettingsManager.ts +67 -0
  178. package/examples/dashboard/src/SettingsScreen.tsx +179 -0
  179. package/examples/dashboard/src/StatusPanel.tsx +71 -0
  180. package/examples/dashboard/src/SystemTypeCog/CogStateInfo.ts +170 -0
  181. package/examples/dashboard/src/SystemTypeCog/SystemTypeCog.ts +125 -0
  182. package/examples/dashboard/src/SystemTypeGeneric/StateInfoGeneric.ts +38 -0
  183. package/examples/dashboard/src/SystemTypeGeneric/SystemTypeGeneric.ts +125 -0
  184. package/examples/dashboard/src/SystemTypeMarty/RICAddOn.ts +70 -0
  185. package/examples/dashboard/src/SystemTypeMarty/RICAddOnBase.ts +33 -0
  186. package/examples/dashboard/src/SystemTypeMarty/RICAddOnManager.ts +342 -0
  187. package/examples/dashboard/src/SystemTypeMarty/RICCommsStats.ts +170 -0
  188. package/examples/dashboard/src/SystemTypeMarty/RICHWElem.ts +123 -0
  189. package/examples/dashboard/src/SystemTypeMarty/RICLEDPatternChecker.ts +207 -0
  190. package/examples/dashboard/src/SystemTypeMarty/RICROSSerial.ts +464 -0
  191. package/examples/dashboard/src/SystemTypeMarty/RICServoFaultDetector.ts +146 -0
  192. package/examples/dashboard/src/SystemTypeMarty/RICStateInfo.ts +105 -0
  193. package/examples/dashboard/src/SystemTypeMarty/RICSystemUtils.ts +371 -0
  194. package/examples/dashboard/src/SystemTypeMarty/RICTypes.ts +20 -0
  195. package/examples/dashboard/src/SystemTypeMarty/SystemTypeMarty.ts +119 -0
  196. package/examples/dashboard/src/index.html +15 -0
  197. package/examples/dashboard/src/index.tsx +13 -0
  198. package/examples/dashboard/src/styles.css +570 -0
  199. package/examples/dashboard/tsconfig.json +18 -0
  200. package/jest.config.js +11 -0
  201. package/package.json +49 -52
  202. package/src/RaftAttributeHandler.ts +450 -0
  203. package/src/RaftChannel.ts +32 -0
  204. package/src/RaftChannelBLE.native.ts +617 -0
  205. package/src/RaftChannelBLE.web.ts +374 -0
  206. package/src/RaftChannelBLEFactory.ts +13 -0
  207. package/src/RaftChannelBLEScanner.native.ts +184 -0
  208. package/src/RaftChannelSimulated.ts +1177 -0
  209. package/src/RaftChannelWebSerial.ts +420 -0
  210. package/src/RaftChannelWebSocket.ts +272 -0
  211. package/src/RaftCommsStats.ts +142 -0
  212. package/src/RaftConnEvents.ts +58 -0
  213. package/src/RaftConnector.ts +806 -0
  214. package/src/RaftCustomAttrHandler.ts +117 -0
  215. package/src/RaftDeviceInfo.ts +125 -0
  216. package/src/RaftDeviceManager.ts +1014 -0
  217. package/src/RaftDeviceMgrIF.ts +37 -0
  218. package/src/RaftDeviceMsg.ts +20 -0
  219. package/src/RaftDeviceStates.ts +122 -0
  220. package/src/RaftFileHandler.ts +668 -0
  221. package/src/RaftLog.ts +70 -0
  222. package/src/RaftMiniHDLC.ts +396 -0
  223. package/src/RaftMsgHandler.ts +812 -0
  224. package/src/RaftMsgTrackInfo.ts +51 -0
  225. package/src/RaftProtocolDefs.ts +46 -0
  226. package/src/RaftPublish.ts +92 -0
  227. package/src/RaftStreamHandler.ts +412 -0
  228. package/src/RaftStruct.ts +282 -0
  229. package/src/RaftSysTypeManager.ts +87 -0
  230. package/src/RaftSystemType.ts +34 -0
  231. package/src/RaftSystemUtils.ts +548 -0
  232. package/src/RaftTypes.ts +306 -0
  233. package/src/RaftUpdateEvents.ts +48 -0
  234. package/src/RaftUpdateManager.ts +781 -0
  235. package/src/RaftUtils.ts +514 -0
  236. package/src/RaftWifiTypes.ts +36 -0
  237. package/src/main.ts +40 -0
  238. package/testdata/TestDeviceTypeRecs.json +492 -0
  239. package/tsconfig.json +30 -0
  240. package/tsconfig.react-native.json +29 -0
@@ -0,0 +1,617 @@
1
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // RaftChannelPhoneBLE
4
+ // Part of RaftJS
5
+ //
6
+ // Rob Dobson & Chris Greening 2020-2024
7
+ // (C) 2020-2024 All rights reserved
8
+ //
9
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10
+
11
+ import { BleError, BleManager, Characteristic, ConnectionPriority, Device, State, Subscription } from "react-native-ble-plx";
12
+ import RaftChannel from "./RaftChannel";
13
+ import { RaftConnEvent, RaftConnEventFn } from "./RaftConnEvents";
14
+ import RaftLog from "./RaftLog";
15
+ import RaftMsgHandler from "./RaftMsgHandler";
16
+ import RaftUtils from "./RaftUtils";
17
+ import RaftChannelBLEScanner from "./RaftChannelBLEScanner.native";
18
+ import { DiscoveredDevice } from "./RaftTypes";
19
+
20
+ const _bleManager = new BleManager();
21
+
22
+ export default class RaftChannelPhoneBLE implements RaftChannel {
23
+
24
+ // Conn event fn
25
+ private _onConnEvent: RaftConnEventFn | null = null;
26
+
27
+ // Default command and response UUIDs
28
+ _cmdUUID = 'aa76677e-9cfd-4626-a510-0d305be57c8e';
29
+ _respUUID = 'aa76677e-9cfd-4626-a510-0d305be57c8f';
30
+ _serviceUUIDs = ['aa76677e-9cfd-4626-a510-0d305be57c8d', 'da903f65-d5c2-4f4d-a065-d1aade7af874'];
31
+
32
+ // BLE Scanner
33
+ _bleScanner: RaftChannelBLEScanner;
34
+
35
+ // Device to connect to using BLE
36
+ _deviceToConnectTo: DiscoveredDevice | null = null;
37
+
38
+ // Handle BLE disconnection through retry
39
+ // May be set after connection checking (e.g. using LEDs)
40
+ _retryConnectionIfLost: boolean = false;
41
+ RECONNECT_ATTEMPTS_AFTER_CONN_LOST = 20;
42
+
43
+ // BLE connection
44
+ _bleSubscrOnRx: Subscription | null = null;
45
+ _bleSubscrOnDisconnect: Subscription | null = null;
46
+ _bleSubscrOnStateChange: Subscription | null = null;
47
+ _bleDevice: Device | null = null;
48
+
49
+ // MTU (Maximum Transmission Unit) size to request
50
+ MTU_SIZE_TO_REQUEST = 512;
51
+
52
+ // Message handler
53
+ _raftMsgHandler: RaftMsgHandler | null = null;
54
+
55
+ // Last message tx time
56
+ private _msgTxTimeLast = Date.now();
57
+ private _msgTxMinTimeBetweenMs = 15;
58
+ private readonly maxRetries = 1;
59
+
60
+ // File Handler parameters
61
+ private _requestedBatchAckSize = 10;
62
+ private _requestedFileBlockSize = 500;
63
+
64
+ // Connected device UUID
65
+ private _connectedDeviceServiceUUID?: string;
66
+
67
+ constructor() {
68
+ RaftLog.debug('BLEChannel constructor');
69
+
70
+ // _bleManager.setLogLevel(LogLevel.Verbose);
71
+
72
+ // Scanner
73
+ this._bleScanner = new RaftChannelBLEScanner(
74
+ _bleManager,
75
+ this._serviceUUIDs,
76
+ this.scanningEvent.bind(this),
77
+ );
78
+
79
+ // Listen for BLE state changes
80
+ this._bleSubscrOnStateChange = _bleManager.onStateChange(state => {
81
+ this._onBLEStateChange(state);
82
+ }, true);
83
+ }
84
+
85
+ setConnectedDeviceUUID(serviceUUID: string) {
86
+ this._connectedDeviceServiceUUID = serviceUUID;
87
+ }
88
+
89
+ getBleManager(): BleManager {
90
+ return _bleManager;
91
+ }
92
+
93
+
94
+ fhBatchAckSize(): number { return this._requestedBatchAckSize; }
95
+ fhFileBlockSize(): number { return this._requestedFileBlockSize; }
96
+
97
+ pauseConnection(pause: boolean): void { RaftLog.verbose(`pauseConnection ${pause} - no effect for this channel type`); return; }
98
+
99
+ // isConnected
100
+ isConnected(): boolean {
101
+ return this._bleDevice !== null;
102
+ }
103
+
104
+ setOnConnEvent(connEventFn: RaftConnEventFn): void {
105
+ this._onConnEvent = connEventFn;
106
+ }
107
+
108
+ requiresSubscription(): boolean {
109
+ return true;
110
+ }
111
+
112
+ isEnabled() {
113
+ return true;
114
+ }
115
+
116
+ // Set message handler
117
+ setMsgHandler(raftMsgHandler: RaftMsgHandler): void {
118
+ this._raftMsgHandler = raftMsgHandler;
119
+ }
120
+
121
+ setRetryConnectionIfLost(retry: boolean): void {
122
+ RaftLog.debug(`BLEChannel setRetryConnectionIfLost ${retry}`);
123
+ this._retryConnectionIfLost = retry;
124
+ }
125
+
126
+ async discoveryStart(uuids: string[], tries = 10): Promise<boolean> {
127
+ if (tries <= 0) {
128
+ RaftLog.debug(`BLEChannel discoveryStart failed`);
129
+ return false;
130
+ }
131
+ // Disconnect any existing connection
132
+ // await this.disconnect();
133
+
134
+ // wait until the bt is powered on
135
+ const state = await _bleManager.state();
136
+ if (state !== State.PoweredOn) {
137
+ RaftLog.debug(`BLEChannel discoveryStart waiting for BLE powered on`);
138
+ await new Promise(resolve => setTimeout(resolve, 500));
139
+ return this.discoveryStart(uuids, tries - 1);
140
+ }
141
+ // Start scanning
142
+ await this._bleScanner.scanningStart(uuids);
143
+
144
+ // Event
145
+ RaftLog.debug(`BLEChannel discoveryStart emitting BLE_SCANNING_STARTED`);
146
+ this.emit(RaftConnEvent.BLE_SCANNING_STARTED);
147
+ return true;
148
+ }
149
+
150
+ discoveryCancel(): void {
151
+ // Stop scanning
152
+ this._bleScanner.scanningStop();
153
+ }
154
+
155
+ _onBLEStateChange(state: State) {
156
+ RaftLog.debug('BLEChannel state change ' + state);
157
+ if (state === State.PoweredOn) {
158
+ this.emit(RaftConnEvent.BLE_BLUETOOTH_STATE, {
159
+ btEnabled: true,
160
+ });
161
+ RaftLog.debug('BLEChannel BLE powered on');
162
+ } else if (state === State.PoweredOff) {
163
+ this.emit(RaftConnEvent.BLE_BLUETOOTH_STATE, {
164
+ btEnabled: false,
165
+ });
166
+ }
167
+ }
168
+
169
+ // Get connected locator
170
+ getConnectedLocator(): string | Device {
171
+ return this._bleDevice || '';
172
+ }
173
+
174
+ /**
175
+ * Get RIC connection status
176
+ *
177
+ * @returns boolean (true if connected)
178
+ *
179
+ */
180
+ async getIsConnected(forceCheck: boolean = false): Promise<boolean> {
181
+ if (this._bleDevice === null) {
182
+ return false;
183
+ }
184
+ if (!forceCheck) {
185
+ return true;
186
+ }
187
+ return await this._bleDevice?.isConnected();
188
+ }
189
+
190
+ /**
191
+ * Get the RSSI of the currently connected device
192
+ *
193
+ * @return number (or null if not connected)
194
+ *
195
+ */
196
+ async readRSSI(): Promise<number> {
197
+ if (this._bleDevice) {
198
+ const updatedDevice = await this._bleDevice.readRSSI();
199
+ if (updatedDevice.rssi !== null) {
200
+ return updatedDevice.rssi;
201
+ }
202
+ }
203
+ // is this a sensible default? should show up as a very weak signal
204
+ return -200;
205
+ }
206
+
207
+ /**
208
+ * Connect to a RIC
209
+ *
210
+ * @returns boolean (true if connected)
211
+ *
212
+ */
213
+ async connect(discoveredDevice: DiscoveredDevice): Promise<boolean> {
214
+ RaftLog.debug('BLEChannel requested connection ' + JSON.stringify(discoveredDevice));
215
+ this._connectedDeviceServiceUUID = discoveredDevice.serviceUUIDs ? discoveredDevice.serviceUUIDs[0] : undefined;
216
+
217
+ this._retryConnectionIfLost = false;
218
+ this._bleScanner.scanningStop();
219
+
220
+ // Now connecting
221
+ this.emit(RaftConnEvent.CONN_CONNECTING, { deviceId: discoveredDevice.id });
222
+
223
+ // Connect
224
+ this._deviceToConnectTo = discoveredDevice;
225
+ const connOk = await this._configDeviceConnection();
226
+
227
+ // Check if ok
228
+ if (!connOk) {
229
+ // Emit failure
230
+ this.emit(RaftConnEvent.CONN_CONNECTION_FAILED);
231
+ return false;
232
+ }
233
+
234
+ // Emit success
235
+ this.emit(RaftConnEvent.CONN_CONNECTED, {
236
+ deviceId: this._deviceToConnectTo.id,
237
+ name: this._deviceToConnectTo.name,
238
+ });
239
+ return true;
240
+ }
241
+
242
+ /**
243
+ * Disconnect from RIC
244
+ *
245
+ * @returns None
246
+ *
247
+ */
248
+ async disconnect(): Promise<void> {
249
+ RaftLog.debug('BLEChannel disconnect requested');
250
+ this._retryConnectionIfLost = false;
251
+ RaftLog.debug(`this._ricToConnectTo ${this._deviceToConnectTo}`);
252
+ const connectedRIC = this._deviceToConnectTo;
253
+ this._deviceToConnectTo = null;
254
+
255
+ // this._invalidateConnectionInfo(); // //
256
+
257
+ // Remove disconnect subscription so it doesn't try to reconnect
258
+ if (this._bleSubscrOnDisconnect) {
259
+ this._bleSubscrOnDisconnect.remove();
260
+ this._bleSubscrOnDisconnect = null;
261
+ }
262
+ // Disconnect from the connected device
263
+ const connMarties = await _bleManager.connectedDevices(
264
+ this._serviceUUIDs
265
+ );
266
+ if (connMarties.length == 0) {
267
+ RaftLog.debug('BLEChannel disconnect - no devices connected');
268
+ } else {
269
+ for (const connRIC of connMarties) {
270
+ RaftLog.debug(`Found connected device ${connRIC.id}`);
271
+ RaftLog.debug(`ID to disconnect ${connectedRIC?.id}`);
272
+ if (connectedRIC?.id === connRIC.id) {
273
+ await _bleManager.cancelDeviceConnection(connRIC.id);
274
+ }
275
+ }
276
+ }
277
+
278
+ // Emit disconnected event
279
+ this.emit(RaftConnEvent.CONN_DISCONNECTED);
280
+ RaftLog.debug('BLEChannel disconnect clearing connected device');
281
+ this._bleDevice = null;
282
+ }
283
+
284
+ /**
285
+ * Configure device connection
286
+ *
287
+ * @returns None
288
+ *
289
+ */
290
+ async _configDeviceConnection(): Promise<boolean> {
291
+ // Check there is a RIC to connect to
292
+ if (this._deviceToConnectTo === null) {
293
+ return false;
294
+ }
295
+
296
+ let deviceConnected: Device | null = null;
297
+ for (let connRetry = 0; connRetry < 5; connRetry++) {
298
+ try {
299
+ deviceConnected = await _bleManager.connectToDevice(
300
+ this._deviceToConnectTo.id,
301
+ {
302
+ timeout: 3000,
303
+ },
304
+ );
305
+ // this.handleLostDevice(); // //
306
+ break;
307
+ } catch (error) {
308
+ RaftLog.debug(
309
+ `BLEChannel configDeviceConnection failed at attempt ${connRetry + 1
310
+ } error ${error}`,
311
+ );
312
+ deviceConnected = null;
313
+ }
314
+ }
315
+ if (deviceConnected === null) {
316
+ return false;
317
+ }
318
+
319
+ // Increase MTU size
320
+ try {
321
+ if (deviceConnected) {
322
+ const updatedDevice = await deviceConnected.requestMTU(this.MTU_SIZE_TO_REQUEST);
323
+ RaftLog.debug(
324
+ `BLEChannel configDeviceConnection requestMTU ${this.MTU_SIZE_TO_REQUEST}, actualMTU ${updatedDevice.mtu}`,
325
+ );
326
+ }
327
+ } catch (error) {
328
+ RaftLog.debug(
329
+ `BLEChannel configDeviceConnection requestMTU failed error ${error}`,
330
+ );
331
+ return false;
332
+ }
333
+
334
+ // Request high-priority connection
335
+ try {
336
+ await _bleManager.requestConnectionPriorityForDevice(
337
+ this._deviceToConnectTo.id,
338
+ ConnectionPriority.High,
339
+ );
340
+ RaftLog.debug(
341
+ `BLEChannel configDeviceConnection request ConnPriority.High`,
342
+ );
343
+ } catch (error) {
344
+ RaftLog.debug(
345
+ `BLEChannel configDeviceConnection requestConnectionPriorityForDevice failed ${error}`,
346
+ );
347
+ return false;
348
+ }
349
+
350
+ // Discover services and characteristics
351
+ try {
352
+ if (deviceConnected) {
353
+ this._bleDevice =
354
+ await deviceConnected.discoverAllServicesAndCharacteristics();
355
+ }
356
+ } catch (error) {
357
+ RaftLog.debug(
358
+ `BLEChannel configDeviceConnection discoverAllServicesAndCharacteristics failed error ${error}`,
359
+ );
360
+ return false;
361
+ }
362
+ // Monitor the inbound characteristic
363
+ try {
364
+ if (this._bleDevice) {
365
+ if (!this._connectedDeviceServiceUUID) {
366
+ RaftLog.warn('BLEChannel _configDeviceConnection - no connected device service UUID');
367
+ return false;
368
+ }
369
+ this._bleSubscrOnRx = this._bleDevice.monitorCharacteristicForService(
370
+ this._connectedDeviceServiceUUID,
371
+ this._respUUID,
372
+ (error: BleError | null, characteristic: Characteristic | null) => {
373
+ this._onMsgRx(error, characteristic);
374
+ },
375
+ );
376
+ }
377
+ } catch (error) {
378
+ RaftLog.debug(
379
+ `BLEChannel configDeviceConnection monitorCharacteristicForService failed ${error}`,
380
+ );
381
+ return false;
382
+ }
383
+
384
+ // Deal with future disconnections
385
+ this._handleLostConnections();
386
+
387
+ return true;
388
+ }
389
+
390
+ /**
391
+ * Handle lost connections
392
+ *
393
+ * @returns None
394
+ *
395
+ */
396
+ _handleLostConnections(): void {
397
+ // Check device ok
398
+ if (this._bleDevice === null) {
399
+ return;
400
+ }
401
+
402
+ // Attach a disconnected listener
403
+ this._bleSubscrOnDisconnect = _bleManager.onDeviceDisconnected(
404
+ this._bleDevice.id,
405
+ async () => {
406
+ // this._storeConnectionInfo(); // //
407
+ // this._invalidateConnectionInfo(); // //
408
+ RaftLog.warn(`onDeviceDisconnected BLEManager says device disconnected`);
409
+ // this.emit(RaftConnEvent.CONN_ISSUE_DETECTED);
410
+ this.emit(RaftConnEvent.CONN_DISCONNECTED);
411
+ try {
412
+ if (this._bleSubscrOnRx) {
413
+ this._bleSubscrOnRx.remove();
414
+ this._bleSubscrOnRx = null;
415
+ }
416
+
417
+ if (this._bleSubscrOnDisconnect) {
418
+ this._bleSubscrOnDisconnect.remove();
419
+ this._bleSubscrOnDisconnect = null;
420
+ }
421
+
422
+ // Debug
423
+ RaftLog.debug(`connection subscriptions removed`);
424
+
425
+ // Device now null
426
+ RaftLog.debug(`onDisconnect clearing connected device`);
427
+ // this._ghostBleDevice = this._bleDevice; // //
428
+ this._bleDevice = null;
429
+ } catch (error) {
430
+ RaftLog.debug(`Error in onDisconnected ${error}`);
431
+ }
432
+
433
+ // Attempt reconnection
434
+ for (
435
+ let reconnAttempt = 0;
436
+ reconnAttempt < this.RECONNECT_ATTEMPTS_AFTER_CONN_LOST;
437
+ reconnAttempt++
438
+ ) {
439
+ // Check if scan in progress - and stop reconn attempts if so
440
+ const scanInProgress = this._bleScanner.isScanInProgress();
441
+ RaftLog.debug(
442
+ `onDeviceDisconnected considering reconnection RICToConnectTo ${this._deviceToConnectTo?.name} scanInProgress ${scanInProgress} retryConnectionIfLost ${this._retryConnectionIfLost}`,
443
+ );
444
+ if (
445
+ !this._retryConnectionIfLost ||
446
+ scanInProgress ||
447
+ !this._deviceToConnectTo
448
+ ) {
449
+ RaftLog.debug(
450
+ `onDeviceDisconnected DISCONNECTED_RIC RICToConnectTo ${this._deviceToConnectTo?.name} scanInProgress ${scanInProgress} retryConnectionIfLost ${this._retryConnectionIfLost}`,
451
+ );
452
+ if (this._retryConnectionIfLost) {
453
+ // this.emit(RaftConnEvent.BLE_DISCONNECTED_RIC);
454
+ } else {
455
+ // this.emit(RaftConnEvent.BLE_CONNECTING_RIC_FAIL);
456
+ }
457
+ break;
458
+ }
459
+ if (await this._configDeviceConnection()) {
460
+ RaftLog.debug(
461
+ `onDeviceDisconnected successful reconn RICToConnectTo ${this._deviceToConnectTo?.name}`,
462
+ );
463
+
464
+ // Indicate connection issue resolved
465
+ // this.emit(RaftConnEvent.CONN_ISSUE_RESOLVED);
466
+
467
+ // await this.ricConnector.retrieveMartySystemInfo();
468
+ return;
469
+ }
470
+ RaftLog.debug(
471
+ `onDeviceDisconnected retrying reconn RICToConnectTo ${this._deviceToConnectTo?.name}`,
472
+ );
473
+ }
474
+ },
475
+ );
476
+ }
477
+
478
+
479
+ getMTU() {
480
+ return this._bleDevice?.mtu;
481
+ }
482
+
483
+ emit(event: RaftConnEvent, data?: any): void {
484
+ if (this._onConnEvent) {
485
+ this._onConnEvent(event, data);
486
+ }
487
+ }
488
+
489
+ _onMsgRx(error: BleError | null, characteristic: Characteristic | null) {
490
+ if (error) {
491
+ // this.emit(maybe dont want to emit here - just add to comms stats?);
492
+ // this.reportError(error.message);
493
+ return;
494
+ }
495
+
496
+ // Extract message
497
+ const msgFrameBase64 = characteristic!.value;
498
+
499
+ const rxFrame = RaftUtils.atob(msgFrameBase64!);
500
+
501
+ // Debug
502
+ // RaftLog.debug('_onMsgRx from BLE ' + RaftUtils.bufferToHex(rxFrame));
503
+
504
+ // Send
505
+ if (rxFrame !== null && this._raftMsgHandler) {
506
+ this._raftMsgHandler.handleNewRxMsg(rxFrame);
507
+ }
508
+ }
509
+
510
+ async scanningEvent(event: RaftConnEvent, data?: any): Promise<void> {
511
+ if (this._onConnEvent) {
512
+ this._onConnEvent(event, data);
513
+ }
514
+ }
515
+
516
+ async sendTxMsg(
517
+ msg: Uint8Array,
518
+ // sendWithResponse: boolean,
519
+ ): Promise<boolean> {
520
+ // Check valid
521
+ if (this._bleDevice === null) {
522
+ return false;
523
+ }
524
+
525
+ for (let retryIdx = 0; retryIdx < this.maxRetries; retryIdx++) {
526
+
527
+ // Check for min time between messages
528
+ while (Date.now() - this._msgTxTimeLast < this._msgTxMinTimeBetweenMs) {
529
+ await new Promise(resolve => setTimeout(resolve, 5));
530
+ }
531
+ this._msgTxTimeLast = Date.now();
532
+
533
+ // Convert to Base64
534
+ const msgFrameBase64 = RaftUtils.btoa(msg);
535
+
536
+ try {
537
+ if (!this._connectedDeviceServiceUUID) {
538
+ RaftLog.warn('BLEChannel sendTxMsg - no connected device service UUID');
539
+ return false;
540
+ }
541
+ await this._bleDevice!.writeCharacteristicWithoutResponseForService(
542
+ this._connectedDeviceServiceUUID,
543
+ this._cmdUUID,
544
+ msgFrameBase64!,
545
+ );
546
+ return true;
547
+ } catch {
548
+ if (retryIdx === this.maxRetries - 1) {
549
+ RaftLog.debug(`sendTxMsg failed after ${this.maxRetries} attempts`);
550
+ return false;
551
+ }
552
+ RaftLog.debug(`sendTxMsg failed, retrying`);
553
+ }
554
+ }
555
+ return false;
556
+ }
557
+
558
+ async sendTxMsgNoAwait(
559
+ msg: Uint8Array,
560
+ // sendWithResponse: boolean,
561
+ ): Promise<boolean> {
562
+ // Check valid
563
+ if (this._bleDevice === null) {
564
+ return false;
565
+ }
566
+
567
+ // Retry upto maxRetries
568
+ for (let retryIdx = 0; retryIdx < this.maxRetries; retryIdx++) {
569
+
570
+ // Check for min time between messages
571
+ while (Date.now() - this._msgTxTimeLast < this._msgTxMinTimeBetweenMs) {
572
+ await new Promise(resolve => setTimeout(resolve, 5));
573
+ }
574
+ this._msgTxTimeLast = Date.now();
575
+
576
+ // Convert to Base64
577
+ const msgFrameBase64 = RaftUtils.btoa(msg);
578
+
579
+ try {
580
+ if (!this._connectedDeviceServiceUUID) {
581
+ RaftLog.warn('BLEChannel sendTxMsgNoAwait - no connected device service UUID');
582
+ return false;
583
+ }
584
+ this._bleDevice!.writeCharacteristicWithoutResponseForService(
585
+ this._connectedDeviceServiceUUID,
586
+ this._cmdUUID,
587
+ msgFrameBase64!,
588
+ );
589
+ return true;
590
+ } catch {
591
+ if (retryIdx === this.maxRetries - 1) {
592
+ RaftLog.debug(`sendTxMsgNoAwait failed after ${this.maxRetries} attempts`);
593
+ return false;
594
+ }
595
+ RaftLog.debug(`sendTxMsgNoAwait failed, retrying`);
596
+ }
597
+ }
598
+ return false;
599
+ }
600
+
601
+ // RICREST command before disconnect
602
+ ricRestCmdBeforeDisconnect(): string | null {
603
+ return "bledisconnect";
604
+ }
605
+
606
+ // Method used for testing and simulation should never be called
607
+ sendTxMsgRaw(): boolean {
608
+ RaftLog.debug(`sendTxMsgRaw - not implemented`);
609
+ return false;
610
+ }
611
+
612
+ // Method used for testing and simulation should never be called
613
+ sendTxMsgRawAndWaitForReply<T>(): T {
614
+ RaftLog.debug(`sendTxMsgRawAndWaitForReply - not implemented`);
615
+ return null as T;
616
+ }
617
+ }