@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.
- package/.editorconfig +14 -0
- package/.gitattributes +11 -0
- package/.nvmrc +1 -0
- package/TODO.md +1 -0
- package/dist/react-native/RaftAttributeHandler.d.ts +14 -0
- package/dist/react-native/RaftAttributeHandler.js +375 -0
- package/dist/react-native/RaftAttributeHandler.js.map +1 -0
- package/dist/react-native/RaftChannel.d.ts +20 -0
- package/dist/react-native/RaftChannel.js +12 -0
- package/dist/react-native/RaftChannel.js.map +1 -0
- package/dist/react-native/RaftChannelBLE.native.d.ts +95 -0
- package/dist/react-native/RaftChannelBLE.native.js +483 -0
- package/dist/react-native/RaftChannelBLE.native.js.map +1 -0
- package/dist/react-native/RaftChannelBLE.web.d.ts +40 -0
- package/dist/react-native/RaftChannelBLE.web.js +302 -0
- package/dist/react-native/RaftChannelBLE.web.js.map +1 -0
- package/dist/react-native/RaftChannelBLEFactory.d.ts +10 -0
- package/dist/react-native/RaftChannelBLEFactory.js +17 -0
- package/dist/react-native/RaftChannelBLEFactory.js.map +1 -0
- package/dist/react-native/RaftChannelBLEScanner.native.d.ts +18 -0
- package/dist/react-native/RaftChannelBLEScanner.native.js +138 -0
- package/dist/react-native/RaftChannelBLEScanner.native.js.map +1 -0
- package/dist/react-native/RaftChannelSimulated.d.ts +42 -0
- package/dist/react-native/RaftChannelSimulated.js +1001 -0
- package/dist/react-native/RaftChannelSimulated.js.map +1 -0
- package/dist/react-native/RaftChannelWebSerial.d.ts +39 -0
- package/dist/react-native/RaftChannelWebSerial.js +329 -0
- package/dist/react-native/RaftChannelWebSerial.js.map +1 -0
- package/dist/react-native/RaftChannelWebSocket.d.ts +30 -0
- package/dist/react-native/RaftChannelWebSocket.js +222 -0
- package/dist/react-native/RaftChannelWebSocket.js.map +1 -0
- package/dist/react-native/RaftCommsStats.d.ts +39 -0
- package/dist/react-native/RaftCommsStats.js +128 -0
- package/dist/react-native/RaftCommsStats.js.map +1 -0
- package/dist/react-native/RaftConnEvents.d.ts +39 -0
- package/dist/react-native/RaftConnEvents.js +54 -0
- package/dist/react-native/RaftConnEvents.js.map +1 -0
- package/dist/react-native/RaftConnector.d.ts +257 -0
- package/dist/react-native/RaftConnector.js +671 -0
- package/dist/react-native/RaftConnector.js.map +1 -0
- package/dist/react-native/RaftCustomAttrHandler.d.ts +6 -0
- package/dist/react-native/RaftCustomAttrHandler.js +93 -0
- package/dist/react-native/RaftCustomAttrHandler.js.map +1 -0
- package/dist/react-native/RaftDeviceInfo.d.ts +71 -0
- package/dist/react-native/RaftDeviceInfo.js +50 -0
- package/dist/react-native/RaftDeviceInfo.js.map +1 -0
- package/dist/react-native/RaftDeviceManager.d.ts +73 -0
- package/dist/react-native/RaftDeviceManager.js +812 -0
- package/dist/react-native/RaftDeviceManager.js.map +1 -0
- package/dist/react-native/RaftDeviceMgrIF.d.ts +19 -0
- package/dist/react-native/RaftDeviceMgrIF.js +11 -0
- package/dist/react-native/RaftDeviceMgrIF.js.map +1 -0
- package/dist/react-native/RaftDeviceMsg.d.ts +9 -0
- package/dist/react-native/RaftDeviceMsg.js +11 -0
- package/dist/react-native/RaftDeviceMsg.js.map +1 -0
- package/dist/react-native/RaftDeviceStates.d.ts +55 -0
- package/dist/react-native/RaftDeviceStates.js +81 -0
- package/dist/react-native/RaftDeviceStates.js.map +1 -0
- package/dist/react-native/RaftFileHandler.d.ts +52 -0
- package/dist/react-native/RaftFileHandler.js +502 -0
- package/dist/react-native/RaftFileHandler.js.map +1 -0
- package/dist/react-native/RaftLog.d.ts +22 -0
- package/dist/react-native/RaftLog.js +63 -0
- package/dist/react-native/RaftLog.js.map +1 -0
- package/dist/react-native/RaftMiniHDLC.d.ts +18 -0
- package/dist/react-native/RaftMiniHDLC.js +383 -0
- package/dist/react-native/RaftMiniHDLC.js.map +1 -0
- package/dist/react-native/RaftMsgHandler.d.ts +62 -0
- package/dist/react-native/RaftMsgHandler.js +511 -0
- package/dist/react-native/RaftMsgHandler.js.map +1 -0
- package/dist/react-native/RaftMsgTrackInfo.d.ts +17 -0
- package/dist/react-native/RaftMsgTrackInfo.js +42 -0
- package/dist/react-native/RaftMsgTrackInfo.js.map +1 -0
- package/dist/react-native/RaftProtocolDefs.d.ts +30 -0
- package/dist/react-native/RaftProtocolDefs.js +48 -0
- package/dist/react-native/RaftProtocolDefs.js.map +1 -0
- package/dist/react-native/RaftPublish.d.ts +2 -0
- package/dist/react-native/RaftPublish.js +81 -0
- package/dist/react-native/RaftPublish.js.map +1 -0
- package/dist/react-native/RaftStreamHandler.d.ts +49 -0
- package/dist/react-native/RaftStreamHandler.js +324 -0
- package/dist/react-native/RaftStreamHandler.js.map +1 -0
- package/dist/react-native/RaftStruct.d.ts +3 -0
- package/dist/react-native/RaftStruct.js +258 -0
- package/dist/react-native/RaftStruct.js.map +1 -0
- package/dist/react-native/RaftSysTypeManager.d.ts +16 -0
- package/dist/react-native/RaftSysTypeManager.js +78 -0
- package/dist/react-native/RaftSysTypeManager.js.map +1 -0
- package/dist/react-native/RaftSystemType.d.ts +30 -0
- package/dist/react-native/RaftSystemType.js +3 -0
- package/dist/react-native/RaftSystemType.js.map +1 -0
- package/dist/react-native/RaftSystemUtils.d.ts +152 -0
- package/dist/react-native/RaftSystemUtils.js +463 -0
- package/dist/react-native/RaftSystemUtils.js.map +1 -0
- package/dist/react-native/RaftTypes.d.ts +216 -0
- package/dist/react-native/RaftTypes.js +153 -0
- package/dist/react-native/RaftTypes.js.map +1 -0
- package/dist/react-native/RaftUpdateEvents.d.ts +33 -0
- package/dist/react-native/RaftUpdateEvents.js +46 -0
- package/dist/react-native/RaftUpdateEvents.js.map +1 -0
- package/dist/react-native/RaftUpdateManager.d.ts +61 -0
- package/dist/react-native/RaftUpdateManager.js +621 -0
- package/dist/react-native/RaftUpdateManager.js.map +1 -0
- package/dist/react-native/RaftUtils.d.ts +128 -0
- package/dist/react-native/RaftUtils.js +487 -0
- package/dist/react-native/RaftUtils.js.map +1 -0
- package/dist/react-native/RaftWifiTypes.d.ts +23 -0
- package/dist/react-native/RaftWifiTypes.js +43 -0
- package/dist/react-native/RaftWifiTypes.js.map +1 -0
- package/dist/react-native/main.d.ts +27 -0
- package/dist/react-native/main.js +52 -0
- package/dist/react-native/main.js.map +1 -0
- package/dist/web/RaftAttributeHandler.js +1 -1
- package/dist/web/RaftAttributeHandler.js.map +1 -1
- package/dist/web/RaftChannelBLE.web.js +8 -6
- package/dist/web/RaftChannelBLE.web.js.map +1 -1
- package/dist/web/RaftChannelSimulated.d.ts +10 -0
- package/dist/web/RaftChannelSimulated.js +665 -82
- package/dist/web/RaftChannelSimulated.js.map +1 -1
- package/dist/web/RaftChannelWebSerial.js +2 -2
- package/dist/web/RaftChannelWebSerial.js.map +1 -1
- package/dist/web/RaftChannelWebSocket.js +16 -1
- package/dist/web/RaftChannelWebSocket.js.map +1 -1
- package/dist/web/RaftConnector.d.ts +12 -1
- package/dist/web/RaftConnector.js +45 -9
- package/dist/web/RaftConnector.js.map +1 -1
- package/dist/web/RaftCustomAttrHandler.d.ts +2 -0
- package/dist/web/RaftCustomAttrHandler.js +54 -26
- package/dist/web/RaftCustomAttrHandler.js.map +1 -1
- package/dist/web/RaftDeviceInfo.d.ts +3 -1
- package/dist/web/RaftDeviceInfo.js +17 -3
- package/dist/web/RaftDeviceInfo.js.map +1 -1
- package/dist/web/RaftDeviceManager.d.ts +32 -2
- package/dist/web/RaftDeviceManager.js +307 -74
- package/dist/web/RaftDeviceManager.js.map +1 -1
- package/dist/web/RaftDeviceMgrIF.d.ts +5 -1
- package/dist/web/RaftDeviceStates.d.ts +20 -2
- package/dist/web/RaftDeviceStates.js +25 -4
- package/dist/web/RaftDeviceStates.js.map +1 -1
- package/dist/web/RaftMsgHandler.js.map +1 -1
- package/dist/web/RaftPublish.d.ts +2 -0
- package/dist/web/RaftPublish.js +81 -0
- package/dist/web/RaftPublish.js.map +1 -0
- package/dist/web/RaftStreamHandler.d.ts +11 -0
- package/dist/web/RaftStreamHandler.js +68 -1
- package/dist/web/RaftStreamHandler.js.map +1 -1
- package/dist/web/RaftStruct.js +197 -147
- package/dist/web/RaftStruct.js.map +1 -1
- package/dist/web/RaftSystemUtils.d.ts +17 -1
- package/dist/web/RaftSystemUtils.js +51 -0
- package/dist/web/RaftSystemUtils.js.map +1 -1
- package/dist/web/RaftTypes.d.ts +21 -0
- package/dist/web/RaftTypes.js.map +1 -1
- package/dist/web/RaftUpdateManager.js +1 -1
- package/dist/web/RaftUpdateManager.js.map +1 -1
- package/dist/web/RaftUtils.d.ts +2 -0
- package/dist/web/RaftUtils.js +20 -0
- package/dist/web/RaftUtils.js.map +1 -1
- package/dist/web/main.d.ts +2 -0
- package/dist/web/main.js +1 -0
- package/dist/web/main.js.map +1 -1
- package/eslint.config.mjs +33 -0
- package/examples/dashboard/package.json +36 -0
- package/examples/dashboard/src/CommandPanel.tsx +147 -0
- package/examples/dashboard/src/ConnManager.ts +166 -0
- package/examples/dashboard/src/DeviceActionsForm.tsx +133 -0
- package/examples/dashboard/src/DeviceAttrsForm.tsx +49 -0
- package/examples/dashboard/src/DeviceLineChart.tsx +163 -0
- package/examples/dashboard/src/DevicePanel.tsx +247 -0
- package/examples/dashboard/src/DeviceStatsPanel.tsx +65 -0
- package/examples/dashboard/src/DevicesPanel.tsx +69 -0
- package/examples/dashboard/src/DispLedGrid.tsx +110 -0
- package/examples/dashboard/src/DispOneLed.tsx +20 -0
- package/examples/dashboard/src/LatencyTest.ts +130 -0
- package/examples/dashboard/src/LatencyTestPanel.tsx +92 -0
- package/examples/dashboard/src/Main.tsx +234 -0
- package/examples/dashboard/src/SettingsManager.ts +67 -0
- package/examples/dashboard/src/SettingsScreen.tsx +179 -0
- package/examples/dashboard/src/StatusPanel.tsx +71 -0
- package/examples/dashboard/src/SystemTypeCog/CogStateInfo.ts +170 -0
- package/examples/dashboard/src/SystemTypeCog/SystemTypeCog.ts +125 -0
- package/examples/dashboard/src/SystemTypeGeneric/StateInfoGeneric.ts +38 -0
- package/examples/dashboard/src/SystemTypeGeneric/SystemTypeGeneric.ts +125 -0
- package/examples/dashboard/src/SystemTypeMarty/RICAddOn.ts +70 -0
- package/examples/dashboard/src/SystemTypeMarty/RICAddOnBase.ts +33 -0
- package/examples/dashboard/src/SystemTypeMarty/RICAddOnManager.ts +342 -0
- package/examples/dashboard/src/SystemTypeMarty/RICCommsStats.ts +170 -0
- package/examples/dashboard/src/SystemTypeMarty/RICHWElem.ts +123 -0
- package/examples/dashboard/src/SystemTypeMarty/RICLEDPatternChecker.ts +207 -0
- package/examples/dashboard/src/SystemTypeMarty/RICROSSerial.ts +464 -0
- package/examples/dashboard/src/SystemTypeMarty/RICServoFaultDetector.ts +146 -0
- package/examples/dashboard/src/SystemTypeMarty/RICStateInfo.ts +105 -0
- package/examples/dashboard/src/SystemTypeMarty/RICSystemUtils.ts +371 -0
- package/examples/dashboard/src/SystemTypeMarty/RICTypes.ts +20 -0
- package/examples/dashboard/src/SystemTypeMarty/SystemTypeMarty.ts +119 -0
- package/examples/dashboard/src/index.html +15 -0
- package/examples/dashboard/src/index.tsx +13 -0
- package/examples/dashboard/src/styles.css +570 -0
- package/examples/dashboard/tsconfig.json +18 -0
- package/jest.config.js +11 -0
- package/package.json +49 -52
- package/src/RaftAttributeHandler.ts +450 -0
- package/src/RaftChannel.ts +32 -0
- package/src/RaftChannelBLE.native.ts +617 -0
- package/src/RaftChannelBLE.web.ts +374 -0
- package/src/RaftChannelBLEFactory.ts +13 -0
- package/src/RaftChannelBLEScanner.native.ts +184 -0
- package/src/RaftChannelSimulated.ts +1177 -0
- package/src/RaftChannelWebSerial.ts +420 -0
- package/src/RaftChannelWebSocket.ts +272 -0
- package/src/RaftCommsStats.ts +142 -0
- package/src/RaftConnEvents.ts +58 -0
- package/src/RaftConnector.ts +806 -0
- package/src/RaftCustomAttrHandler.ts +117 -0
- package/src/RaftDeviceInfo.ts +125 -0
- package/src/RaftDeviceManager.ts +1014 -0
- package/src/RaftDeviceMgrIF.ts +37 -0
- package/src/RaftDeviceMsg.ts +20 -0
- package/src/RaftDeviceStates.ts +122 -0
- package/src/RaftFileHandler.ts +668 -0
- package/src/RaftLog.ts +70 -0
- package/src/RaftMiniHDLC.ts +396 -0
- package/src/RaftMsgHandler.ts +812 -0
- package/src/RaftMsgTrackInfo.ts +51 -0
- package/src/RaftProtocolDefs.ts +46 -0
- package/src/RaftPublish.ts +92 -0
- package/src/RaftStreamHandler.ts +412 -0
- package/src/RaftStruct.ts +282 -0
- package/src/RaftSysTypeManager.ts +87 -0
- package/src/RaftSystemType.ts +34 -0
- package/src/RaftSystemUtils.ts +548 -0
- package/src/RaftTypes.ts +306 -0
- package/src/RaftUpdateEvents.ts +48 -0
- package/src/RaftUpdateManager.ts +781 -0
- package/src/RaftUtils.ts +514 -0
- package/src/RaftWifiTypes.ts +36 -0
- package/src/main.ts +40 -0
- package/testdata/TestDeviceTypeRecs.json +492 -0
- package/tsconfig.json +30 -0
- 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
|
+
}
|