@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,362 @@
1
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // RaftChannelBLE
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 { RaftConnEvent, RaftConnEventFn } from "./RaftConnEvents";
13
+ import RaftLog from "./RaftLog";
14
+ import RaftMsgHandler from "./RaftMsgHandler";
15
+ import { ConnectorOptions } from "./RaftSystemType";
16
+ import RaftUtils from "./RaftUtils";
17
+
18
+ export default class RaftChannelBLE implements RaftChannel {
19
+ // BLE UUIDS
20
+ public static RICServiceUUID = "aa76677e-9cfd-4626-a510-0d305be57c8d";
21
+ public static CogServiceUUID = "da903f65-d5c2-4f4d-a065-d1aade7af874";
22
+ public static CmdUUID = "aa76677e-9cfd-4626-a510-0d305be57c8e";
23
+ public static RespUUID = "aa76677e-9cfd-4626-a510-0d305be57c8f";
24
+
25
+ // Device and characteristics
26
+ private _bleDevice: BluetoothDevice | null = null;
27
+ private _characteristicTx: BluetoothRemoteGATTCharacteristic | null = null;
28
+ private _characteristicRx: BluetoothRemoteGATTCharacteristic | null = null;
29
+
30
+ // Message handler
31
+ private _raftMsgHandler: RaftMsgHandler | null = null;
32
+
33
+ // Conn event fn
34
+ private _onConnEvent: RaftConnEventFn | null = null;
35
+
36
+ // Last message tx time
37
+ private _msgTxTimeLast = Date.now();
38
+ private _msgTxMinTimeBetweenMs = 1;
39
+ private readonly maxRetries = 1;
40
+
41
+ // Connected flag and retries
42
+ private _isConnected = false;
43
+ private readonly _maxConnRetries = 3;
44
+
45
+ // Event listener fn
46
+ private _eventListenerFn: ((event: Event) => void) | null = null;
47
+
48
+ // File Handler parameters
49
+ private _requestedBatchAckSize = 10;
50
+ private _requestedFileBlockSize = 500;
51
+
52
+ fhBatchAckSize(): number {
53
+ return this._requestedBatchAckSize;
54
+ }
55
+ fhFileBlockSize(): number {
56
+ return this._requestedFileBlockSize;
57
+ }
58
+
59
+ // Set message handler
60
+ setMsgHandler(raftMsgHandler: RaftMsgHandler): void {
61
+ this._raftMsgHandler = raftMsgHandler;
62
+ }
63
+
64
+ requiresSubscription(): boolean {
65
+ return true;
66
+ }
67
+
68
+ // RICREST command before disconnect
69
+ ricRestCmdBeforeDisconnect(): string | null {
70
+ // NT: Sending blerestart *before* disconnecting results in timeout issues as the device is no longer connected when we try to actually disconnect
71
+ // suggested fix: allow callaback command to be sent after disconnect on the fw side
72
+ // return "blerestart";
73
+ return null;
74
+ }
75
+
76
+ // isEnabled
77
+ isEnabled() {
78
+ if (navigator.bluetooth) {
79
+ RaftLog.error("Web Bluetooth is supported in your browser.");
80
+ return true;
81
+ } else {
82
+ window.alert(
83
+ "Web Bluetooth API is not available.\n" +
84
+ 'Please make sure the "Experimental Web Platform features" flag is enabled.'
85
+ );
86
+ return false;
87
+ }
88
+ }
89
+
90
+ // isConnected
91
+ isConnected(): boolean {
92
+ return this._bleDevice !== null && this._isConnected;
93
+ }
94
+
95
+ // Set onConnEvent handler
96
+ setOnConnEvent(connEventFn: RaftConnEventFn): void {
97
+ this._onConnEvent = connEventFn;
98
+ }
99
+
100
+ // Disconnection event
101
+ onDisconnected(event: Event): void {
102
+ const device = event.target as BluetoothDevice;
103
+ RaftLog.debug(`RaftChannelBLE.onDisconnected ${device.name}`);
104
+ if (this._bleDevice) {
105
+ this._bleDevice.removeEventListener(
106
+ "gattserverdisconnected",
107
+ this._eventListenerFn
108
+ );
109
+ }
110
+ this._isConnected = false;
111
+ if (this._onConnEvent) {
112
+ this._onConnEvent(RaftConnEvent.CONN_DISCONNECTED);
113
+ }
114
+ }
115
+
116
+ // Get connected locator
117
+ getConnectedLocator(): string | object {
118
+ return this._bleDevice || "";
119
+ }
120
+
121
+ // Connect to a device
122
+ async connect(locator: string | object, _connectorOptions: ConnectorOptions): Promise<boolean> {
123
+ // RaftLog.debug(`Selected device: ${deviceID}`);
124
+ this._bleDevice = locator as BluetoothDevice;
125
+ if (this._bleDevice && this._bleDevice.gatt) {
126
+ try {
127
+ // Connect
128
+ for (let connRetry = 0; connRetry < this._maxConnRetries; connRetry++) {
129
+ // Connect
130
+ const connTimeoutMs = _connectorOptions.connTimeoutMs || 5000;
131
+ await RaftUtils.withTimeout(connTimeoutMs, this._bleDevice.gatt.connect());
132
+ RaftLog.debug(
133
+ `RaftChannelBLE.connect - ${this._bleDevice.gatt.connected ? "OK" : "FAILED"
134
+ } attempt ${connRetry + 1} connection to device ${this._bleDevice.name}`
135
+ );
136
+
137
+ if (this._bleDevice.gatt.connected) {
138
+
139
+ // Delay a bit
140
+ await new Promise(resolve => setTimeout(resolve, 100));
141
+
142
+ // Get service
143
+ try {
144
+ let service: BluetoothRemoteGATTService | null = null;
145
+ // iterate over known services
146
+ for (const serviceUUID of [RaftChannelBLE.CogServiceUUID, RaftChannelBLE.RICServiceUUID]) {
147
+ try {
148
+ service = await this._bleDevice.gatt.getPrimaryService(serviceUUID);
149
+ if (service) {
150
+ break;
151
+ }
152
+ } catch (error) {
153
+ RaftLog.warn(
154
+ `RaftChannelBLE.connect - cannot get primary service ${error}`
155
+ );
156
+ }
157
+ }
158
+
159
+ if (!service) {
160
+ RaftLog.error(
161
+ `RaftChannelBLE.connect - cannot get primary service - giving up`
162
+ );
163
+ return false;
164
+ }
165
+ RaftLog.debug(
166
+ `RaftChannelBLE.connect - found service: ${service.uuid}`
167
+ );
168
+
169
+ try {
170
+ // Get Tx and Rx characteristics
171
+ this._characteristicTx = await service.getCharacteristic(
172
+ RaftChannelBLE.CmdUUID
173
+ );
174
+ RaftLog.debug(
175
+ `RaftChannelBLE.connect - found char ${this._characteristicTx.uuid}`
176
+ );
177
+ this._characteristicRx = await service.getCharacteristic(
178
+ RaftChannelBLE.RespUUID
179
+ );
180
+ RaftLog.debug(
181
+ `RaftChannelBLE.connect - found char ${this._characteristicRx.uuid}`
182
+ );
183
+
184
+ // Notifications of received messages
185
+ try {
186
+ await this._characteristicRx.startNotifications();
187
+ RaftLog.debug(
188
+ "RaftChannelBLE.connect - notifications started"
189
+ );
190
+ this._characteristicRx.addEventListener(
191
+ "characteristicvaluechanged",
192
+ this._onMsgRx.bind(this)
193
+ );
194
+ } catch (error) {
195
+ RaftLog.debug(
196
+ "RaftChannelBLE.connnect - addEventListener failed " + error
197
+ );
198
+ }
199
+
200
+ // Connected ok
201
+ RaftLog.debug(`RaftChannelBLE.connect ${this._bleDevice.name}`);
202
+
203
+ // Add disconnect listener
204
+ this._eventListenerFn = this.onDisconnected.bind(this);
205
+ this._bleDevice.addEventListener(
206
+ "gattserverdisconnected",
207
+ this._eventListenerFn
208
+ );
209
+
210
+ // Connected
211
+ this._isConnected = true;
212
+ return true;
213
+ } catch (error) {
214
+ RaftLog.error(
215
+ `RaftChannelBLE.connect - cannot find characteristic: ${error}`
216
+ );
217
+ }
218
+ } catch (error) {
219
+ if (connRetry === this._maxConnRetries - 1) {
220
+ RaftLog.error(
221
+ `RaftChannelBLE.connect - cannot get primary service ${error} - attempt #${connRetry + 1} - giving up`
222
+ );
223
+ } else {
224
+ RaftLog.debug(
225
+ `RaftChannelBLE.connect - cannot get primary service - attempt #${connRetry + 1} ${error}`
226
+ );
227
+ }
228
+ }
229
+ }
230
+ }
231
+ } catch (error: unknown) {
232
+ RaftLog.warn(`RaftChannelBLE.connect - cannot connect ${error}`);
233
+ }
234
+
235
+ // Disconnect
236
+ if (
237
+ this._bleDevice &&
238
+ this._bleDevice.gatt &&
239
+ this._bleDevice.gatt.connected
240
+ ) {
241
+ try {
242
+ await this._bleDevice.gatt.disconnect();
243
+ } catch (error) {
244
+ RaftLog.warn(`RaftChannelBLE.connect - cannot disconnect ${error}`);
245
+ }
246
+ }
247
+ }
248
+
249
+ return false;
250
+ }
251
+
252
+ // Disconnect
253
+ async disconnect(): Promise<void> {
254
+ if (this._bleDevice && this._bleDevice.gatt) {
255
+ try {
256
+ RaftLog.debug(`RaftChannelBLE.disconnect GATT`);
257
+ await this._bleDevice.gatt.disconnect();
258
+ } catch (error) {
259
+ RaftLog.debug(`RaftChannelBLE.disconnect ${error}`);
260
+ }
261
+ }
262
+ }
263
+
264
+ pauseConnection(pause: boolean): void {
265
+ RaftLog.verbose(
266
+ `pauseConnection ${pause} - no effect for this channel type`
267
+ );
268
+ return;
269
+ }
270
+
271
+ // Handle notifications
272
+ _onMsgRx(event: Event): void {
273
+ // Get characteristic
274
+ const characteristic = event.target as BluetoothRemoteGATTCharacteristic;
275
+
276
+ // Get value
277
+ const value = characteristic.value;
278
+ if (value !== undefined) {
279
+ const msg = new Uint8Array(value.buffer);
280
+
281
+ // Handle message
282
+ if (this._raftMsgHandler) {
283
+ try {
284
+ this._raftMsgHandler.handleNewRxMsg(msg);
285
+ } catch (error) {
286
+ RaftLog.debug(`RaftChannelBLE.onMsgRx ${error}`);
287
+ }
288
+ }
289
+ }
290
+ }
291
+
292
+ // Send a message
293
+ async sendTxMsg(
294
+ msg: Uint8Array
295
+ // _sendWithResponse: boolean
296
+ ): Promise<boolean> {
297
+ // Check valid
298
+ if (this._bleDevice === null) {
299
+ return false;
300
+ }
301
+
302
+ // Retry upto maxRetries
303
+ for (let retryIdx = 0; retryIdx < this.maxRetries; retryIdx++) {
304
+ // Check for min time between messages
305
+ while (Date.now() - this._msgTxTimeLast < this._msgTxMinTimeBetweenMs) {
306
+ await new Promise((resolve) => setTimeout(resolve, 5));
307
+ }
308
+ this._msgTxTimeLast = Date.now();
309
+
310
+ // Write to the characteristic
311
+ try {
312
+ if (this._characteristicTx) {
313
+ if (this._characteristicTx.writeValueWithoutResponse) {
314
+ await this._characteristicTx.writeValueWithoutResponse(msg);
315
+ } else if (this._characteristicTx.writeValue) {
316
+ await this._characteristicTx.writeValue(msg);
317
+ } else if (this._characteristicTx.writeValueWithResponse) {
318
+ await this._characteristicTx.writeValueWithResponse(msg);
319
+ }
320
+ }
321
+ break;
322
+ } catch (error) {
323
+ if (retryIdx === this.maxRetries - 1) {
324
+ RaftLog.info(
325
+ `RaftChannelBLE.sendTxMsg ${error} retried ${retryIdx} times`
326
+ );
327
+ }
328
+ }
329
+ }
330
+ return true;
331
+ }
332
+
333
+ // Send message without awaiting response
334
+ async sendTxMsgNoAwait(
335
+ msg: Uint8Array
336
+ // _sendWithResponse: boolean
337
+ ): Promise<boolean> {
338
+ // Check valid
339
+ if (this._bleDevice === null) {
340
+ return false;
341
+ }
342
+
343
+ // Check for min time between messages
344
+ while (Date.now() - this._msgTxTimeLast < this._msgTxMinTimeBetweenMs) {
345
+ await new Promise((resolve) => setTimeout(resolve, 5));
346
+ }
347
+ this._msgTxTimeLast = Date.now();
348
+
349
+ // Write to the characteristic
350
+ if (this._characteristicTx) {
351
+ if (this._characteristicTx.writeValueWithoutResponse) {
352
+ this._characteristicTx.writeValueWithoutResponse(msg);
353
+ } else if (this._characteristicTx.writeValue) {
354
+ this._characteristicTx.writeValue(msg);
355
+ } else if (this._characteristicTx.writeValueWithResponse) {
356
+ this._characteristicTx.writeValueWithResponse(msg);
357
+ }
358
+ return true;
359
+ }
360
+ return false;
361
+ }
362
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @description
3
+ * This file is used to create a new instance of the RaftChannelBLE class.
4
+ * RaftChannelBLE exists in 2 files: RaftChannelBLE.native.ts and RaftChannelBLE.web.ts
5
+ * each of these files contains the same class but with different implementations (native and web).
6
+ * The import statement at the top of the file will import the correct implementation based on the platform
7
+ * (depending on the build configuration).
8
+ */
9
+ import RaftChannelBLE from './RaftChannelBLE';
10
+
11
+ export function createBLEChannel() {
12
+ return RaftChannelBLE;
13
+ }
@@ -0,0 +1,190 @@
1
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // RICBLEScanner
4
+ // Communications Connector for RIC V2
5
+ //
6
+ // RIC V2
7
+ // Rob Dobson 2022
8
+ // (C) Robotical 2022
9
+ //
10
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11
+
12
+ import {
13
+ BleManager,
14
+ Device,
15
+ BleError,
16
+ } from 'react-native-ble-plx';
17
+ import { DiscoveredRIC } from './RaftTypes';
18
+ import RaftLog from './RaftLog';
19
+ import { RaftConnEvent, RaftConnEventFn } from './RaftConnEvents';
20
+
21
+ export default class RICBLEScanner {
22
+
23
+ // BleManager
24
+ _bleManager: BleManager;
25
+
26
+ // Services to scan for
27
+ _uuidsOfServicesToScanFor: Array<string> = [];
28
+
29
+ // Scanned devices found on BLE
30
+ _discoveredRICs: DiscoveredRIC[] = [];
31
+ static _scanInProgress = false;
32
+
33
+ // Time to scan for
34
+ _discoveryTimeMs = 10000;
35
+
36
+ // Event callback
37
+ _eventCallback: RaftConnEventFn;
38
+
39
+ constructor(bleManager: BleManager, uuidsOfServicesToScanFor: Array<string>, eventCallback: RaftConnEventFn) {
40
+ this._bleManager = bleManager;
41
+ this._uuidsOfServicesToScanFor = uuidsOfServicesToScanFor;
42
+ this._eventCallback = eventCallback;
43
+ }
44
+
45
+ // Get discovered RICs
46
+ getDiscoveredRICs(): DiscoveredRIC[] {
47
+ return this._discoveredRICs;
48
+ }
49
+
50
+ // Check is a scan is in progress
51
+ isScanInProgress(): boolean {
52
+ return RICBLEScanner._scanInProgress;
53
+ }
54
+
55
+ async scanningStart(uuid?: string): Promise<boolean> {
56
+ let uuidsOfServicesToScanFor: string[] = [];
57
+ if (uuid) {
58
+ uuidsOfServicesToScanFor.push(uuid);
59
+ } else {
60
+ uuidsOfServicesToScanFor = this._uuidsOfServicesToScanFor;
61
+ }
62
+ // Handle discovery
63
+ RaftLog.debug('Starting Scanning...');
64
+
65
+ // Clear list
66
+ this._discoveredRICs = [];
67
+
68
+ // Disconnect any connections
69
+ RICBLEScanner._scanInProgress = true;
70
+
71
+ // Start scan
72
+ try {
73
+ this._bleManager.startDeviceScan(
74
+ uuidsOfServicesToScanFor,
75
+ { allowDuplicates: true },
76
+ (error: BleError | null, device: Device | null) => {
77
+ // RaftLog.debug(`discoveryFoundCB error ${error}`);
78
+ this._discoveryFoundCB(error, device);
79
+ },
80
+ );
81
+ } catch (e) {
82
+ RaftLog.warn(`Error starting scan ${e}`);
83
+ return false;
84
+ }
85
+
86
+ // Set a time limit
87
+ this._discoverySetTimeLimit(this._discoveryTimeMs);
88
+ return true;
89
+ }
90
+
91
+ scanningStop(): void {
92
+
93
+ RaftLog.debug('scanningStop');
94
+
95
+ // Emit finished if we were scanning
96
+ RaftLog.debug(`IS SCANNING IN PROGRESS: ${RICBLEScanner._scanInProgress}`);
97
+ if (RICBLEScanner._scanInProgress) {
98
+ RaftLog.debug(`sending BLE_SCANNING_FINISHED event`);
99
+ this._eventCallback(RaftConnEvent.BLE_SCANNING_FINISHED, { discoveredRICs: this._discoveredRICs });
100
+ }
101
+
102
+ // Cancel scanning
103
+ this._bleManager.stopDeviceScan();
104
+ RICBLEScanner._scanInProgress = false;
105
+ }
106
+
107
+ // Callback from BLE-PLX library on device discovered
108
+ _discoveryFoundCB(
109
+ error: BleError | null,
110
+ scannedDevice: Device | null,
111
+ ): void {
112
+ if (error) {
113
+ //RaftLog.warn(`⚠️ Scan Error >> ${error.toString()}`);
114
+ RaftLog.warn(`⚠️ Scan Error >> ${JSON.stringify(error)}`);
115
+ // Event if we were scanning
116
+ if (RICBLEScanner._scanInProgress) {
117
+ this._eventCallback(RaftConnEvent.BLE_SCANNING_FINISHED, {
118
+ discoveredRICs: this._discoveredRICs,
119
+ });
120
+ RICBLEScanner._scanInProgress = false;
121
+ }
122
+ return;
123
+ }
124
+
125
+ // See if already in the list
126
+ const ricAlreadyFound = this._discoveredRICs.find(
127
+ item => item.id === scannedDevice!.id,
128
+ );
129
+
130
+ RaftLog.debug(`✅ Scanning... >> ${scannedDevice}`);
131
+
132
+ if (ricAlreadyFound) {
133
+ // update the rssi value if it's not 127
134
+ if (scannedDevice!.rssi !== null && scannedDevice!.rssi !== 127) {
135
+ ricAlreadyFound._rssi = scannedDevice!.rssi;
136
+ this._eventCallback(RaftConnEvent.BLE_DEVICE_FOUND, {
137
+ discoveredRIC: ricAlreadyFound
138
+ });
139
+ }
140
+ return;
141
+ }
142
+
143
+ if (scannedDevice !== null) {
144
+ if (!scannedDevice.localName) {
145
+ // if the name of the device is null, don't add this device
146
+ // the first time round. Second time this device comes up
147
+ // will have all the needed info
148
+ return;
149
+ }
150
+ const newDiscoveredRic = new DiscoveredRIC(
151
+ scannedDevice.localName !== null ? scannedDevice.localName : '',
152
+ scannedDevice.name !== null ? scannedDevice.name : '',
153
+ scannedDevice.id,
154
+ scannedDevice.rssi !== null ? scannedDevice.rssi : -150,
155
+ );
156
+ this._discoveredRICs.push(newDiscoveredRic);
157
+ // send the newly found ric to the state so it can pop-up on the front-end
158
+ this._eventCallback(RaftConnEvent.BLE_DEVICE_FOUND, {
159
+ discoveredRIC: newDiscoveredRic
160
+ });
161
+ }
162
+ RaftLog.debug(`🤖 Scanned RICs >> ${this._discoveredRICs}`);
163
+ }
164
+
165
+ // Time-limit on device scanning
166
+ _discoverySetTimeLimit(timeLimitMs: number) {
167
+ setTimeout(() => {
168
+ // Stop scanning
169
+ this._bleManager.stopDeviceScan();
170
+
171
+ // Check we were scanning
172
+ if (RICBLEScanner._scanInProgress) {
173
+ // Sort by signal strength
174
+ // this._discoveredRICs.sort((a, b) => {
175
+ // return b!.rssi! - a!.rssi!;
176
+ // });
177
+
178
+ // Debug
179
+ const msg = `🤖 ${this._discoveredRICs.length} RICs found! Choose one to connect`;
180
+ RaftLog.debug(msg);
181
+
182
+ // Finished event
183
+ this._eventCallback(RaftConnEvent.BLE_SCANNING_FINISHED, {
184
+ discoveredRICs: this._discoveredRICs,
185
+ });
186
+ }
187
+ RICBLEScanner._scanInProgress = false;
188
+ }, timeLimitMs);
189
+ }
190
+ }