incyclist-devices 2.0.0-beta.1 → 2.0.1
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/README.MD +238 -0
- package/lib/adapters.d.ts +1 -0
- package/lib/adapters.js +19 -0
- package/lib/antv2/adapter-factory.d.ts +8 -7
- package/lib/antv2/adapter-factory.js +4 -2
- package/lib/antv2/adapter.d.ts +3 -2
- package/lib/antv2/adapter.js +15 -4
- package/lib/antv2/ant-interface.d.ts +6 -2
- package/lib/antv2/ant-interface.js +27 -21
- package/lib/antv2/binding.d.ts +1 -1
- package/lib/antv2/binding.js +1 -1
- package/lib/antv2/fe/adapter.d.ts +12 -9
- package/lib/antv2/fe/adapter.js +67 -27
- package/lib/antv2/hr/adapter.d.ts +6 -5
- package/lib/antv2/hr/adapter.js +19 -16
- package/lib/antv2/index.d.ts +2 -2
- package/lib/antv2/pwr/adapter.d.ts +6 -4
- package/lib/antv2/pwr/adapter.js +24 -16
- package/lib/antv2/sensor-factory.d.ts +2 -2
- package/lib/antv2/types.d.ts +5 -2
- package/lib/antv2/types.js +3 -0
- package/lib/antv2/utils.d.ts +3 -0
- package/lib/antv2/utils.js +12 -1
- package/lib/base/adpater.d.ts +14 -2
- package/lib/base/adpater.js +43 -4
- package/lib/ble/adapter-factory.d.ts +18 -16
- package/lib/ble/adapter-factory.js +54 -45
- package/lib/ble/base/adapter.d.ts +53 -0
- package/lib/ble/{adapter.js → base/adapter.js} +111 -9
- package/lib/ble/base/comms-utils.d.ts +7 -0
- package/lib/ble/base/comms-utils.js +91 -0
- package/lib/ble/{ble-comms.d.ts → base/comms.d.ts} +27 -17
- package/lib/ble/{ble-comms.js → base/comms.js} +179 -53
- package/lib/ble/bindings/index.d.ts +2 -0
- package/lib/ble/bindings/index.js +8 -0
- package/lib/ble/bindings/linux.d.ts +15 -0
- package/lib/ble/bindings/linux.js +39 -0
- package/lib/ble/bindings/mock.d.ts +9 -0
- package/lib/ble/bindings/mock.js +108 -0
- package/lib/ble/bindings/types.d.ts +57 -0
- package/lib/ble/bindings/types.js +96 -0
- package/lib/ble/ble-interface.d.ts +34 -46
- package/lib/ble/ble-interface.js +242 -345
- package/lib/ble/ble-peripheral.d.ts +4 -2
- package/lib/ble/ble-peripheral.js +39 -8
- package/lib/ble/consts.d.ts +1 -0
- package/lib/ble/consts.js +2 -1
- package/lib/ble/cp/adapter.d.ts +1 -2
- package/lib/ble/cp/adapter.js +2 -15
- package/lib/ble/cp/comm.d.ts +8 -5
- package/lib/ble/cp/comm.js +12 -27
- package/lib/ble/elite/adapter.d.ts +1 -2
- package/lib/ble/elite/adapter.js +12 -19
- package/lib/ble/elite/comms.d.ts +8 -4
- package/lib/ble/elite/comms.js +12 -25
- package/lib/ble/fm/adapter.d.ts +3 -2
- package/lib/ble/fm/adapter.js +129 -70
- package/lib/ble/fm/comms.d.ts +8 -8
- package/lib/ble/fm/comms.js +33 -55
- package/lib/ble/fm/types.d.ts +5 -0
- package/lib/ble/hr/adapter.d.ts +1 -4
- package/lib/ble/hr/adapter.js +1 -18
- package/lib/ble/hr/comm.d.ts +6 -2
- package/lib/ble/hr/comm.js +6 -2
- package/lib/ble/hr/mock.d.ts +7 -0
- package/lib/ble/hr/mock.js +47 -0
- package/lib/ble/index.d.ts +2 -1
- package/lib/ble/index.js +5 -5
- package/lib/ble/peripheral-cache.d.ts +43 -0
- package/lib/ble/peripheral-cache.js +107 -0
- package/lib/ble/tacx/adapter.d.ts +1 -1
- package/lib/ble/tacx/adapter.js +20 -14
- package/lib/ble/tacx/comms.d.ts +6 -6
- package/lib/ble/tacx/comms.js +10 -43
- package/lib/ble/types.d.ts +54 -27
- package/lib/ble/types.js +0 -17
- package/lib/ble/utils.d.ts +15 -5
- package/lib/ble/utils.js +25 -66
- package/lib/ble/wahoo/adapter.d.ts +1 -1
- package/lib/ble/wahoo/adapter.js +12 -10
- package/lib/ble/wahoo/comms.d.ts +7 -6
- package/lib/ble/wahoo/comms.js +15 -17
- package/lib/index.d.ts +10 -7
- package/lib/index.js +21 -25
- package/lib/interfaces.d.ts +2 -1
- package/lib/interfaces.js +4 -0
- package/lib/modes/power-base.js +4 -0
- package/lib/serial/adapter.d.ts +5 -0
- package/lib/serial/adapter.js +19 -0
- package/lib/serial/bindings/tcp.d.ts +2 -1
- package/lib/serial/bindings/tcp.js +19 -5
- package/lib/serial/daum/DaumAdapter.d.ts +1 -1
- package/lib/serial/daum/DaumAdapter.js +16 -10
- package/lib/serial/daum/premium/adapter.d.ts +1 -0
- package/lib/serial/daum/premium/adapter.js +9 -2
- package/lib/serial/daum/premium/comms.js +10 -3
- package/lib/serial/daum/premium/mock.js +0 -1
- package/lib/serial/index.d.ts +3 -3
- package/lib/serial/index.js +2 -2
- package/lib/serial/kettler/ergo-racer/adapter.d.ts +1 -4
- package/lib/serial/kettler/ergo-racer/adapter.js +15 -39
- package/lib/serial/serial-interface.d.ts +3 -1
- package/lib/serial/serial-interface.js +43 -17
- package/lib/simulator/Simulator.d.ts +2 -0
- package/lib/simulator/Simulator.js +8 -5
- package/lib/types/adapter.d.ts +10 -3
- package/lib/types/device.d.ts +3 -0
- package/lib/types/interface.d.ts +7 -3
- package/package.json +3 -5
- package/lib/ble/adapter.d.ts +0 -41
- package/lib/ble/ble.d.ts +0 -57
- package/lib/ble/ble.js +0 -48
- package/lib/device.d.ts +0 -0
- package/lib/device.js +0 -0
|
@@ -13,17 +13,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.BleComms = void 0;
|
|
16
|
+
const events_1 = __importDefault(require("events"));
|
|
16
17
|
const gd_eventlog_1 = require("gd-eventlog");
|
|
17
|
-
const utils_1 = require("
|
|
18
|
-
const
|
|
19
|
-
const
|
|
18
|
+
const utils_1 = require("../../utils/utils");
|
|
19
|
+
const ble_interface_1 = __importDefault(require("../ble-interface"));
|
|
20
|
+
const utils_2 = require("../utils");
|
|
20
21
|
const CONNECT_WAIT_TIMEOUT = 10000;
|
|
21
22
|
const BLE_TIMEOUT = 1000;
|
|
22
|
-
class BleComms extends
|
|
23
|
+
class BleComms extends events_1.default {
|
|
23
24
|
constructor(props) {
|
|
24
25
|
super();
|
|
25
26
|
this.characteristics = [];
|
|
26
27
|
this.deviceInfo = {};
|
|
28
|
+
this.connectState = { isConnecting: false, isConnected: false, isDisconnecting: false };
|
|
27
29
|
this.id = props.id;
|
|
28
30
|
this.address = props.address;
|
|
29
31
|
this.name = props.name;
|
|
@@ -35,6 +37,7 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
35
37
|
this.writeQueue = [];
|
|
36
38
|
this.workerIv = null;
|
|
37
39
|
this.prevMessages = [];
|
|
40
|
+
this.paused = false;
|
|
38
41
|
if (props.peripheral) {
|
|
39
42
|
const { id, address, advertisement, state } = props.peripheral;
|
|
40
43
|
this.peripheral = props.peripheral;
|
|
@@ -51,16 +54,37 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
51
54
|
this.logger = new gd_eventlog_1.EventLogger('BleDevice');
|
|
52
55
|
}
|
|
53
56
|
}
|
|
57
|
+
getConnectState() {
|
|
58
|
+
return this.connectState;
|
|
59
|
+
}
|
|
60
|
+
isConnected() {
|
|
61
|
+
return this.connectState.isConnected;
|
|
62
|
+
}
|
|
63
|
+
pause() {
|
|
64
|
+
this.paused = true;
|
|
65
|
+
}
|
|
66
|
+
resume() {
|
|
67
|
+
this.paused = false;
|
|
68
|
+
}
|
|
54
69
|
getServiceUUids() {
|
|
55
70
|
throw new Error("Method not implemented.");
|
|
56
71
|
}
|
|
57
72
|
getProfile() {
|
|
58
73
|
throw new Error("Method not implemented.");
|
|
59
74
|
}
|
|
75
|
+
getProtocol() {
|
|
76
|
+
throw new Error("Method not implemented.");
|
|
77
|
+
}
|
|
78
|
+
getSettings() {
|
|
79
|
+
const { id, address, name } = this;
|
|
80
|
+
return { id, name, address, interface: 'ble', protocol: this.getProtocol() };
|
|
81
|
+
}
|
|
60
82
|
getServices() {
|
|
61
83
|
return this.services;
|
|
62
84
|
}
|
|
63
85
|
logEvent(event) {
|
|
86
|
+
if (this.paused)
|
|
87
|
+
return;
|
|
64
88
|
if (this.logger) {
|
|
65
89
|
this.logger.logEvent(event);
|
|
66
90
|
}
|
|
@@ -74,35 +98,49 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
74
98
|
setInterface(ble) {
|
|
75
99
|
this.ble = ble;
|
|
76
100
|
}
|
|
77
|
-
isMatching(characteristics) {
|
|
101
|
+
static isMatching(characteristics) {
|
|
78
102
|
return true;
|
|
79
103
|
}
|
|
80
104
|
reset() {
|
|
105
|
+
if (this.connectState.isConnecting)
|
|
106
|
+
this.ble.stopConnectSensor();
|
|
81
107
|
}
|
|
82
108
|
cleanupListeners() {
|
|
83
109
|
if (this.characteristics === undefined) {
|
|
84
110
|
this.characteristics = [];
|
|
85
111
|
}
|
|
86
112
|
else {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
113
|
+
if (this.peripheral) {
|
|
114
|
+
const connector = this.ble.peripheralCache.getConnector(this.peripheral);
|
|
115
|
+
this.characteristics.forEach(c => {
|
|
116
|
+
connector.removeAllListeners((0, utils_2.uuid)(c.uuid));
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
this.characteristics = [];
|
|
121
|
+
}
|
|
91
122
|
}
|
|
92
123
|
}
|
|
93
124
|
onDisconnect() {
|
|
94
|
-
this
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this.
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
this.logEvent({ message: 'device disconnected', address: this.address, profile: this.getProfile() });
|
|
127
|
+
this.state = "disconnected";
|
|
128
|
+
const wasConnecting = this.connectState.isConnecting;
|
|
98
129
|
this.connectState.isConnecting = false;
|
|
99
130
|
this.connectState.isConnected = false;
|
|
100
|
-
this.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
131
|
+
if (!this.connectState.isDisconnecting) {
|
|
132
|
+
this.peripheral.state = 'disconnected';
|
|
133
|
+
this.cleanupListeners();
|
|
134
|
+
this.subscribedCharacteristics = [];
|
|
135
|
+
this.ble.onDisconnect(this.peripheral);
|
|
136
|
+
if (wasConnecting) {
|
|
137
|
+
this.emit('connection-failed');
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.connect({ reconnect: true });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
});
|
|
106
144
|
}
|
|
107
145
|
waitForConnectFinished(timeout) {
|
|
108
146
|
const waitStart = Date.now();
|
|
@@ -120,13 +158,13 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
120
158
|
}
|
|
121
159
|
}
|
|
122
160
|
catch (err) {
|
|
123
|
-
|
|
161
|
+
this.logEvent({ message: 'error', fn: '', error: err.message, stack: err.stack });
|
|
124
162
|
}
|
|
125
163
|
}, 100);
|
|
126
164
|
});
|
|
127
165
|
}
|
|
128
166
|
hasService(serviceUuid) {
|
|
129
|
-
return this.services && this.services.find(s => s === serviceUuid || (0,
|
|
167
|
+
return this.services && this.services.find(s => s === serviceUuid || (0, utils_2.uuid)(serviceUuid)) !== undefined;
|
|
130
168
|
}
|
|
131
169
|
init() {
|
|
132
170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -145,27 +183,89 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
145
183
|
connectPeripheral(peripheral) {
|
|
146
184
|
return __awaiter(this, void 0, void 0, function* () {
|
|
147
185
|
this.connectState.isConnecting = true;
|
|
186
|
+
let disconnectSignalled = false;
|
|
187
|
+
return new Promise((done) => __awaiter(this, void 0, void 0, function* () {
|
|
188
|
+
try {
|
|
189
|
+
const connector = this.ble.peripheralCache.getConnector(peripheral);
|
|
190
|
+
const disconnectHandler = () => {
|
|
191
|
+
this.logEvent({ message: 'device disconnected', address: this.address, profile: this.getProfile() });
|
|
192
|
+
this.state = "disconnected";
|
|
193
|
+
disconnectSignalled = true;
|
|
194
|
+
this.cleanupListeners();
|
|
195
|
+
this.subscribedCharacteristics = [];
|
|
196
|
+
this.connectState.isConnecting = false;
|
|
197
|
+
this.connectState.isConnected = false;
|
|
198
|
+
this.ble.onDisconnect(this.peripheral);
|
|
199
|
+
done(false);
|
|
200
|
+
};
|
|
201
|
+
connector.removeAllListeners('disconnect');
|
|
202
|
+
connector.once('disconnect', disconnectHandler);
|
|
203
|
+
yield connector.connect();
|
|
204
|
+
if (disconnectSignalled)
|
|
205
|
+
return;
|
|
206
|
+
yield connector.initialize();
|
|
207
|
+
if (disconnectSignalled)
|
|
208
|
+
return;
|
|
209
|
+
yield this.subscribeAll(connector);
|
|
210
|
+
if (disconnectSignalled)
|
|
211
|
+
return;
|
|
212
|
+
this.connectState.isConnected = true;
|
|
213
|
+
this.state = "connected";
|
|
214
|
+
this.emit('connected');
|
|
215
|
+
connector.removeAllListeners('disconnect');
|
|
216
|
+
connector.on('disconnect', this.onDisconnect.bind(this));
|
|
217
|
+
const success = yield this.init();
|
|
218
|
+
done(success);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
this.logEvent({ message: 'Error', fn: 'connectPeripheral()', error: err.message, stack: err.stack });
|
|
223
|
+
}
|
|
224
|
+
this.connectState.isConnecting = false;
|
|
225
|
+
if (disconnectSignalled)
|
|
226
|
+
return;
|
|
227
|
+
done(true);
|
|
228
|
+
}));
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
subscribeMultiple(characteristics, conn) {
|
|
232
|
+
return new Promise(resolve => {
|
|
148
233
|
try {
|
|
149
|
-
const connector = this.ble.getConnector(peripheral);
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
234
|
+
const connector = conn || this.ble.peripheralCache.getConnector(this.peripheral);
|
|
235
|
+
const subscribeSingle = (c) => {
|
|
236
|
+
connector.removeAllListeners(c);
|
|
237
|
+
connector.on(c, (uuid, data) => {
|
|
238
|
+
this.onData(uuid, data);
|
|
239
|
+
});
|
|
240
|
+
return connector.subscribe(c).then(res => {
|
|
241
|
+
this.subscribedCharacteristics.push(c);
|
|
242
|
+
return res;
|
|
243
|
+
}).catch(err => {
|
|
244
|
+
this.logEvent({ message: 'subscription failed', characteristic: c, error: err.message });
|
|
245
|
+
});
|
|
246
|
+
};
|
|
247
|
+
const promises = characteristics
|
|
248
|
+
.filter(c => {
|
|
249
|
+
if (this.characteristics) {
|
|
250
|
+
const existing = this.characteristics.find(rc => rc.uuid === c || (0, utils_2.uuid)(rc.uuid) === c);
|
|
251
|
+
if (!existing)
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
const isAlreadySubscribed = connector.isSubscribed(c);
|
|
255
|
+
return !isAlreadySubscribed;
|
|
256
|
+
})
|
|
257
|
+
.map(c => subscribeSingle(c));
|
|
258
|
+
Promise.all(promises).then(() => resolve());
|
|
158
259
|
}
|
|
159
260
|
catch (err) {
|
|
160
|
-
this.logEvent({ message: 'Error', fn: '
|
|
261
|
+
this.logEvent({ message: 'Error', fn: 'subscribeMultiple()', error: err.message, stack: err.stack });
|
|
161
262
|
}
|
|
162
|
-
this.connectState.isConnecting = false;
|
|
163
263
|
});
|
|
164
264
|
}
|
|
165
265
|
subscribeAll(conn) {
|
|
166
266
|
return __awaiter(this, void 0, void 0, function* () {
|
|
167
267
|
try {
|
|
168
|
-
const connector = conn || this.ble.getConnector(this.peripheral);
|
|
268
|
+
const connector = conn || this.ble.peripheralCache.getConnector(this.peripheral);
|
|
169
269
|
const subscribed = yield connector.subscribeAll((uuid, data) => { this.onData(uuid, data); });
|
|
170
270
|
subscribed.forEach(c => this.subscribedCharacteristics.push(c));
|
|
171
271
|
}
|
|
@@ -174,11 +274,28 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
174
274
|
}
|
|
175
275
|
});
|
|
176
276
|
}
|
|
277
|
+
unsubscribeAll(conn) {
|
|
278
|
+
const connector = conn || this.ble.peripheralCache.getConnector(this.peripheral);
|
|
279
|
+
connector.unsubscribeAll();
|
|
280
|
+
}
|
|
177
281
|
connect(props) {
|
|
178
282
|
return __awaiter(this, void 0, void 0, function* () {
|
|
283
|
+
if (!this.ble.isConnected()) {
|
|
284
|
+
try {
|
|
285
|
+
yield this.ble.connect();
|
|
286
|
+
if (!this.ble.isConnected())
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
yield (0, utils_1.sleep)(Math.random() * 100);
|
|
294
|
+
yield this.ble.waitForSensorConnectionFinish();
|
|
295
|
+
this.ble.startConnectSensor();
|
|
179
296
|
const { reconnect } = props || {};
|
|
180
297
|
try {
|
|
181
|
-
this.logEvent({ message: reconnect ? 'reconnect' : 'connect', address: this.peripheral ? this.peripheral.address : this.address, state: this.connectState });
|
|
298
|
+
this.logEvent({ message: reconnect ? 'reconnect' : 'connect', name: this.name, id: this.id, address: this.peripheral ? this.peripheral.address : this.address, state: this.connectState });
|
|
182
299
|
if (!reconnect && this.connectState.isConnecting) {
|
|
183
300
|
yield this.waitForConnectFinished(CONNECT_WAIT_TIMEOUT);
|
|
184
301
|
}
|
|
@@ -189,27 +306,32 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
189
306
|
}
|
|
190
307
|
catch (err) {
|
|
191
308
|
this.logEvent({ message: 'cannot reconnect', error: err.message || err });
|
|
309
|
+
this.ble.stopConnectSensor();
|
|
192
310
|
return false;
|
|
193
311
|
}
|
|
312
|
+
this.ble.stopConnectSensor();
|
|
194
313
|
return true;
|
|
195
314
|
}
|
|
196
315
|
this.connectState.isConnecting = true;
|
|
197
316
|
if (!this.peripheral) {
|
|
198
317
|
const { id, name, address } = this;
|
|
199
318
|
try {
|
|
200
|
-
this.peripheral = this.ble.
|
|
319
|
+
this.peripheral = this.ble.peripheralCache.getPeripheral({ id, name, address });
|
|
201
320
|
}
|
|
202
321
|
catch (err) {
|
|
203
|
-
|
|
322
|
+
this.logEvent({ message: 'error', fn: 'connect()', error: err.message, stack: err.stack });
|
|
204
323
|
}
|
|
205
324
|
}
|
|
206
325
|
if (this.peripheral) {
|
|
207
326
|
const { id, address, advertisement } = this.peripheral;
|
|
208
327
|
const name = advertisement === null || advertisement === void 0 ? void 0 : advertisement.localName;
|
|
209
328
|
this.logEvent({ message: 'connect requested', mode: 'peripheral', device: { id, name, address: address } });
|
|
210
|
-
yield this.connectPeripheral(this.peripheral);
|
|
211
|
-
this.logEvent({ message: 'connect result:
|
|
212
|
-
|
|
329
|
+
const connected = yield this.connectPeripheral(this.peripheral);
|
|
330
|
+
this.logEvent({ message: 'connect result: ', connected, mode: 'peripheral', device: { id, name, address } });
|
|
331
|
+
this.connectState.isConnecting = false;
|
|
332
|
+
this.connectState.isConnected = connected;
|
|
333
|
+
this.ble.stopConnectSensor();
|
|
334
|
+
return connected;
|
|
213
335
|
}
|
|
214
336
|
else {
|
|
215
337
|
const { id, name, address } = this;
|
|
@@ -220,24 +342,26 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
220
342
|
if (this.ble.isScanning()) {
|
|
221
343
|
yield this.ble.stopScan();
|
|
222
344
|
}
|
|
223
|
-
const
|
|
224
|
-
if (
|
|
225
|
-
this.peripheral =
|
|
226
|
-
yield this.connectPeripheral(this.peripheral);
|
|
227
|
-
this.logEvent({ message: 'connect result:
|
|
345
|
+
const peripheral = yield this.ble.scanForDevice(this, {}).catch(() => null);
|
|
346
|
+
if (peripheral) {
|
|
347
|
+
this.peripheral = peripheral;
|
|
348
|
+
const connected = yield this.connectPeripheral(this.peripheral);
|
|
349
|
+
this.logEvent({ message: 'connect result: ', connected, mode: 'device', device: { id, name, address } });
|
|
228
350
|
this.connectState.isConnecting = false;
|
|
229
|
-
this.connectState.isConnected =
|
|
230
|
-
|
|
351
|
+
this.connectState.isConnected = connected;
|
|
352
|
+
this.ble.stopConnectSensor();
|
|
353
|
+
return connected;
|
|
231
354
|
}
|
|
232
355
|
}
|
|
233
356
|
catch (err) {
|
|
234
|
-
console.log('~~~
|
|
357
|
+
console.log('~~~ ERROR', err);
|
|
235
358
|
error = err;
|
|
236
359
|
}
|
|
237
360
|
}
|
|
238
361
|
this.logEvent({ message: 'connect result: failure', mode: 'device', device: { id, name, address }, error: error.message, stack: error.stack });
|
|
239
362
|
this.connectState.isConnecting = false;
|
|
240
363
|
this.connectState.isConnected = false;
|
|
364
|
+
this.ble.stopConnectSensor();
|
|
241
365
|
return false;
|
|
242
366
|
}
|
|
243
367
|
}
|
|
@@ -245,6 +369,7 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
245
369
|
this.connectState.isConnecting = false;
|
|
246
370
|
this.connectState.isConnected = false;
|
|
247
371
|
this.logEvent({ message: 'connect result: error', error: err.message });
|
|
372
|
+
this.ble.stopConnectSensor();
|
|
248
373
|
return false;
|
|
249
374
|
}
|
|
250
375
|
});
|
|
@@ -273,8 +398,8 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
273
398
|
return true;
|
|
274
399
|
}
|
|
275
400
|
if (this.connectState.isConnected) {
|
|
276
|
-
this.ble.removeConnectedDevice(this);
|
|
277
401
|
this.cleanupListeners();
|
|
402
|
+
this.unsubscribeAll();
|
|
278
403
|
this.logEvent({ message: 'disconnect result: success', device: { id, name, address } });
|
|
279
404
|
this.connectState.isDisconnecting = false;
|
|
280
405
|
this.connectState.isConnecting = false;
|
|
@@ -308,7 +433,7 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
308
433
|
}
|
|
309
434
|
this.logEvent({ message: 'got data', characteristic, data: data.toString('hex'), writeQueue: this.writeQueue.length });
|
|
310
435
|
if (this.writeQueue.length > 0) {
|
|
311
|
-
const writeIdx = this.writeQueue.findIndex(i => (0,
|
|
436
|
+
const writeIdx = this.writeQueue.findIndex(i => (0, utils_2.matches)(i.uuid, characteristic));
|
|
312
437
|
if (writeIdx !== -1) {
|
|
313
438
|
const writeItem = this.writeQueue[writeIdx];
|
|
314
439
|
this.writeQueue.splice(writeIdx, 1);
|
|
@@ -354,13 +479,13 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
354
479
|
throw new Error('not connected');
|
|
355
480
|
try {
|
|
356
481
|
const { withoutResponse, timeout } = props || {};
|
|
357
|
-
const connector = this.ble.getConnector(this.peripheral);
|
|
482
|
+
const connector = this.ble.peripheralCache.getConnector(this.peripheral);
|
|
358
483
|
const isAlreadySubscribed = connector.isSubscribed(characteristicUuid);
|
|
359
484
|
if (!withoutResponse && !this.workerIv) {
|
|
360
485
|
this.startWorker();
|
|
361
486
|
}
|
|
362
487
|
if (!withoutResponse && !isAlreadySubscribed) {
|
|
363
|
-
const connector = this.ble.getConnector(this.peripheral);
|
|
488
|
+
const connector = this.ble.peripheralCache.getConnector(this.peripheral);
|
|
364
489
|
connector.removeAllListeners(characteristicUuid);
|
|
365
490
|
connector.on(characteristicUuid, (uuid, data) => {
|
|
366
491
|
this.onData(uuid, data);
|
|
@@ -370,7 +495,7 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
370
495
|
this.subscribedCharacteristics.push(characteristicUuid);
|
|
371
496
|
}
|
|
372
497
|
return new Promise((resolve, reject) => {
|
|
373
|
-
const characteristic = this.characteristics.find(c => c.uuid === characteristicUuid || (0,
|
|
498
|
+
const characteristic = this.characteristics.find(c => c.uuid === characteristicUuid || (0, utils_2.uuid)(c.uuid) === characteristicUuid);
|
|
374
499
|
if (!characteristic) {
|
|
375
500
|
reject(new Error('Characteristic not found'));
|
|
376
501
|
return;
|
|
@@ -414,7 +539,7 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
414
539
|
return new Promise((resolve, reject) => {
|
|
415
540
|
if (!this.isConnected())
|
|
416
541
|
return reject(new Error('not connected'));
|
|
417
|
-
const characteristic = this.characteristics.find(c => c.uuid === characteristicUuid || (0,
|
|
542
|
+
const characteristic = this.characteristics.find(c => c.uuid === characteristicUuid || (0, utils_2.uuid)(c.uuid) === characteristicUuid);
|
|
418
543
|
if (!characteristic) {
|
|
419
544
|
reject(new Error('Characteristic not found'));
|
|
420
545
|
return;
|
|
@@ -454,3 +579,4 @@ class BleComms extends types_1.BleDeviceCommsClass {
|
|
|
454
579
|
}
|
|
455
580
|
}
|
|
456
581
|
exports.BleComms = BleComms;
|
|
582
|
+
BleComms.services = [];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MockBinding = void 0;
|
|
7
|
+
const mock_1 = __importDefault(require("./mock"));
|
|
8
|
+
exports.MockBinding = mock_1.default;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import EventEmitter from 'events';
|
|
3
|
+
import { BleBinding, BleInterfaceState } from '../types';
|
|
4
|
+
export declare class BleLinuxBinding extends EventEmitter implements BleBinding {
|
|
5
|
+
static _instance: any;
|
|
6
|
+
_bindings: any;
|
|
7
|
+
state: BleInterfaceState;
|
|
8
|
+
constructor();
|
|
9
|
+
static getInstance(): any;
|
|
10
|
+
startScanning(serviceUUIDs?: string[] | undefined, allowDuplicates?: boolean | undefined, callback?: ((error?: Error | undefined) => void) | undefined): void;
|
|
11
|
+
stopScanning(callback?: (() => void) | undefined): void;
|
|
12
|
+
on(eventName: string | symbol, listener: (...args: any[]) => void): this;
|
|
13
|
+
}
|
|
14
|
+
declare const Binding: any;
|
|
15
|
+
export default Binding;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BleLinuxBinding = void 0;
|
|
7
|
+
const events_1 = __importDefault(require("events"));
|
|
8
|
+
class BleLinuxBinding extends events_1.default {
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
this.state = 'unknown';
|
|
12
|
+
this._bindings = this;
|
|
13
|
+
}
|
|
14
|
+
static getInstance() {
|
|
15
|
+
if (!BleLinuxBinding._instance) {
|
|
16
|
+
BleLinuxBinding._instance = new BleLinuxBinding();
|
|
17
|
+
}
|
|
18
|
+
return BleLinuxBinding._instance;
|
|
19
|
+
}
|
|
20
|
+
startScanning(serviceUUIDs, allowDuplicates, callback) {
|
|
21
|
+
throw new Error('Method not implemented.');
|
|
22
|
+
}
|
|
23
|
+
stopScanning(callback) {
|
|
24
|
+
throw new Error('Method not implemented.');
|
|
25
|
+
}
|
|
26
|
+
on(eventName, listener) {
|
|
27
|
+
super.addListener(eventName, listener);
|
|
28
|
+
if (eventName === 'stateChange') {
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
this.state = 'poweredOn';
|
|
31
|
+
this.emit('stateChange', this.state);
|
|
32
|
+
}, 100);
|
|
33
|
+
}
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.BleLinuxBinding = BleLinuxBinding;
|
|
38
|
+
const Binding = BleLinuxBinding.getInstance();
|
|
39
|
+
exports.default = Binding;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const events_1 = __importDefault(require("events"));
|
|
16
|
+
const utils_1 = require("../../utils/utils");
|
|
17
|
+
class Binding extends events_1.default {
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
this._bindings = this;
|
|
21
|
+
this.state = 'unknown';
|
|
22
|
+
this.channelState = 'IDLE';
|
|
23
|
+
this.peripherals = [];
|
|
24
|
+
}
|
|
25
|
+
static getInstance() {
|
|
26
|
+
if (!Binding._instance) {
|
|
27
|
+
Binding._instance = new Binding();
|
|
28
|
+
}
|
|
29
|
+
return Binding._instance;
|
|
30
|
+
}
|
|
31
|
+
init() { }
|
|
32
|
+
addMock(peripheral) {
|
|
33
|
+
this.peripherals.push(peripheral);
|
|
34
|
+
}
|
|
35
|
+
reset() {
|
|
36
|
+
this.peripherals = [];
|
|
37
|
+
this.state = 'unknown';
|
|
38
|
+
this.channelState = 'IDLE';
|
|
39
|
+
}
|
|
40
|
+
on(eventName, listener) {
|
|
41
|
+
super.addListener(eventName, listener);
|
|
42
|
+
if (eventName === 'stateChange') {
|
|
43
|
+
setTimeout(() => {
|
|
44
|
+
this.state = 'poweredOn';
|
|
45
|
+
this.emit('stateChange', this.state);
|
|
46
|
+
}, 100);
|
|
47
|
+
}
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
startScanning(serviceUUIDs, allowDuplicates, callback) {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
this.channelState = 'SCANNING';
|
|
53
|
+
if (callback)
|
|
54
|
+
callback();
|
|
55
|
+
yield (0, utils_1.sleep)(50);
|
|
56
|
+
this.peripherals.forEach(p => {
|
|
57
|
+
this.emit('discover', new MockPeripheral(p));
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
stopScanning(callback) {
|
|
62
|
+
this.channelState = 'IDLE';
|
|
63
|
+
if (callback)
|
|
64
|
+
callback();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
class MockPeripheral extends events_1.default {
|
|
68
|
+
constructor(p) {
|
|
69
|
+
super();
|
|
70
|
+
this.id = p.id;
|
|
71
|
+
this.name = p.name;
|
|
72
|
+
this.address = p.address;
|
|
73
|
+
this.advertisement = {
|
|
74
|
+
localName: p.name,
|
|
75
|
+
serviceUuids: p.services.map(s => s.uuid)
|
|
76
|
+
};
|
|
77
|
+
this.services = p.services;
|
|
78
|
+
}
|
|
79
|
+
connectAsync() {
|
|
80
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
disconnect(cb) {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
this.removeAllListeners();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
discoverSomeServicesAndCharacteristicsAsync(serviceUUIDs, characteristicUUIDs) {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
const characteristics = [];
|
|
91
|
+
this.services.forEach(s => {
|
|
92
|
+
if (serviceUUIDs && serviceUUIDs.length > 0 && !serviceUUIDs.includes(s.uuid))
|
|
93
|
+
return;
|
|
94
|
+
s.characteristics.forEach(c => {
|
|
95
|
+
var _a, _b;
|
|
96
|
+
if (characteristicUUIDs && characteristicUUIDs.length > 0 && !characteristicUUIDs.includes(c.uuid))
|
|
97
|
+
return;
|
|
98
|
+
c._serviceUuid = s.uuid;
|
|
99
|
+
c.name = (_b = (_a = c.descriptors) === null || _a === void 0 ? void 0 : _a.find(d => d.uuid === '2901')) === null || _b === void 0 ? void 0 : _b.value;
|
|
100
|
+
characteristics.push(c);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
return { services: this.services, characteristics };
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const mock = Binding.getInstance();
|
|
108
|
+
exports.default = mock;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
import EventEmitter from "events";
|
|
5
|
+
import { BleCharacteristic } from "../types";
|
|
6
|
+
export type Property = 'read' | 'write' | 'notify' | 'indicate';
|
|
7
|
+
export type Descriptor = {
|
|
8
|
+
uuid: string;
|
|
9
|
+
value: string | Buffer;
|
|
10
|
+
};
|
|
11
|
+
export type Characteristic = {
|
|
12
|
+
uuid: string;
|
|
13
|
+
properties: Property[];
|
|
14
|
+
secure?: boolean;
|
|
15
|
+
value: Buffer;
|
|
16
|
+
descriptors: Descriptor[];
|
|
17
|
+
};
|
|
18
|
+
export declare const RESULT_SUCCESS = 0;
|
|
19
|
+
export declare const RESULT_INVALID_OFFSET = 7;
|
|
20
|
+
export declare const RESULT_ATTR_NOT_LONG = 11;
|
|
21
|
+
export declare const RESULT_INVALID_ATTRIBUTE_LENGTH = 13;
|
|
22
|
+
export declare const RESULT_UNLIKELY_ERROR = 14;
|
|
23
|
+
export declare class MockCharacteristic extends EventEmitter implements BleCharacteristic {
|
|
24
|
+
uuid: string;
|
|
25
|
+
properties: Property[];
|
|
26
|
+
secure?: boolean | undefined;
|
|
27
|
+
value: Buffer;
|
|
28
|
+
descriptors: Descriptor[];
|
|
29
|
+
subscribe(callback: (err: Error | undefined) => void): void;
|
|
30
|
+
unsubscribe(callback: (err: Error | undefined) => void): void;
|
|
31
|
+
read(callback: (err: Error | undefined, data: Buffer) => void): void;
|
|
32
|
+
write(data: Buffer, withoutResponse: boolean, callback?: ((err: Error | undefined) => void) | undefined): void;
|
|
33
|
+
}
|
|
34
|
+
export declare class StaticReadCharacteristic extends MockCharacteristic {
|
|
35
|
+
constructor(uuid: string, description: string, value: any);
|
|
36
|
+
read(callback: (err: Error | undefined, data: Buffer) => void): void;
|
|
37
|
+
}
|
|
38
|
+
export declare class StaticWriteCharacteristic extends MockCharacteristic {
|
|
39
|
+
size: number;
|
|
40
|
+
constructor(uuid: string, description: string, size: number);
|
|
41
|
+
write(data: Buffer, withoutResponse: boolean, callback?: (err?: Error) => void): void;
|
|
42
|
+
}
|
|
43
|
+
export declare abstract class StaticNotifyCharacteristic extends MockCharacteristic {
|
|
44
|
+
cntSubscriptions: number;
|
|
45
|
+
iv: NodeJS.Timer;
|
|
46
|
+
notifyFrequency: number;
|
|
47
|
+
constructor(uuid: string, description: string);
|
|
48
|
+
subscribe(callback: (err: Error | undefined) => void): void;
|
|
49
|
+
unsubscribe(callback: (err: Error | undefined) => void): void;
|
|
50
|
+
abstract notify(): void;
|
|
51
|
+
startNotify(): void;
|
|
52
|
+
stopNotify(): void;
|
|
53
|
+
}
|
|
54
|
+
export type PrimaryService = {
|
|
55
|
+
uuid: string;
|
|
56
|
+
characteristics: Characteristic[];
|
|
57
|
+
};
|