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