incyclist-devices 2.3.0-beta.1 → 2.3.0-beta.11
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/lib/base/adpater.d.ts +4 -0
- package/lib/base/adpater.js +16 -2
- package/lib/ble/base/adapter.d.ts +4 -1
- package/lib/ble/base/adapter.js +79 -47
- package/lib/ble/base/interface.d.ts +11 -5
- package/lib/ble/base/interface.js +84 -53
- package/lib/ble/base/peripheral.d.ts +1 -0
- package/lib/ble/base/peripheral.js +33 -8
- package/lib/ble/base/sensor.d.ts +1 -1
- package/lib/ble/base/sensor.js +17 -3
- package/lib/ble/fm/adapter.d.ts +3 -2
- package/lib/ble/fm/adapter.js +22 -27
- package/lib/ble/fm/sensor.js +6 -5
- package/lib/ble/tacx/sensor.js +8 -2
- package/lib/ble/types.d.ts +7 -1
- package/lib/ble/utils.js +10 -1
- package/lib/direct-connect/base/interface.d.ts +1 -1
- package/lib/direct-connect/base/interface.js +5 -5
- package/lib/direct-connect/base/peripheral.d.ts +4 -4
- package/lib/direct-connect/base/peripheral.js +181 -68
- package/lib/direct-connect/messages/message.d.ts +1 -0
- package/lib/direct-connect/messages/message.js +16 -1
- package/lib/modes/ant-fe-adv-st-mode.d.ts +1 -1
- package/lib/modes/ant-fe-adv-st-mode.js +5 -3
- package/lib/types/adapter.d.ts +3 -0
- package/lib/utils/task.d.ts +3 -0
- package/lib/utils/task.js +12 -0
- package/package.json +1 -1
|
@@ -108,10 +108,10 @@ class DirectConnectInterface extends events_1.default {
|
|
|
108
108
|
if (!reconnect)
|
|
109
109
|
this.logEvent({ message: 'starting multicast DNS scan ..' });
|
|
110
110
|
this.getBinding().mdns.find(null, (service) => {
|
|
111
|
-
this.addService(service);
|
|
111
|
+
this.addService(service, 'unfiltered');
|
|
112
112
|
});
|
|
113
113
|
this.getBinding().mdns.find({ type: DC_TYPE }, (service) => {
|
|
114
|
-
this.addService(service);
|
|
114
|
+
this.addService(service, DC_TYPE);
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
catch (err) {
|
|
@@ -228,7 +228,7 @@ class DirectConnectInterface extends events_1.default {
|
|
|
228
228
|
buildDeviceSettings(matching = []) {
|
|
229
229
|
return matching.map((name) => ({ interface: DirectConnectInterface.INTERFACE_NAME, name }));
|
|
230
230
|
}
|
|
231
|
-
addService(service) {
|
|
231
|
+
addService(service, source) {
|
|
232
232
|
var _a, _b;
|
|
233
233
|
try {
|
|
234
234
|
service.transport = this.getName();
|
|
@@ -238,9 +238,9 @@ class DirectConnectInterface extends events_1.default {
|
|
|
238
238
|
this.services[idx] = { ts: Date.now(), service };
|
|
239
239
|
}
|
|
240
240
|
else {
|
|
241
|
-
this.logEvent({ message: 'device announced', device: service.name, announcement: service });
|
|
241
|
+
this.logEvent({ message: 'device announced', device: service.name, announcement: service, source });
|
|
242
242
|
this.services.push({ ts: Date.now(), service });
|
|
243
|
-
if (
|
|
243
|
+
if (!((_a = service.serviceUUIDs) === null || _a === void 0 ? void 0 : _a.length))
|
|
244
244
|
return;
|
|
245
245
|
this.emitDevice(service);
|
|
246
246
|
(_b = this.matching) === null || _b === void 0 ? void 0 : _b.push(service.name);
|
|
@@ -21,24 +21,24 @@ export declare class DirectConnectPeripheral implements IBlePeripheral {
|
|
|
21
21
|
constructor(announcement: MulticastDnsAnnouncement);
|
|
22
22
|
get services(): BleService[];
|
|
23
23
|
connect(): Promise<boolean>;
|
|
24
|
-
disconnect(): Promise<boolean>;
|
|
24
|
+
disconnect(connectionLost?: boolean): Promise<boolean>;
|
|
25
25
|
isConnected(): boolean;
|
|
26
26
|
isConnecting(): boolean;
|
|
27
27
|
onDisconnect(callback: () => void): void;
|
|
28
28
|
discoverServices(): Promise<string[]>;
|
|
29
29
|
discoverCharacteristics(serviceUUID: string): Promise<BleCharacteristic[]>;
|
|
30
|
-
subscribe(characteristicUUID: string, callback
|
|
30
|
+
subscribe(characteristicUUID: string, callback?: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
|
|
31
31
|
unsubscribe(characteristicUUID: string): Promise<boolean>;
|
|
32
32
|
subscribeAll(callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
|
|
33
33
|
subscribeSelected(characteristics: string[], callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
|
|
34
|
-
unsubscribeAll(): Promise<
|
|
34
|
+
unsubscribeAll(connectionLost?: boolean): Promise<void>;
|
|
35
35
|
read(characteristicUUID: string): Promise<Buffer>;
|
|
36
36
|
write(characteristicUUID: string, data: Buffer, options?: BleWriteProps): Promise<Buffer>;
|
|
37
37
|
protected startConnection(): Promise<boolean>;
|
|
38
38
|
protected onPortError(err: Error): void;
|
|
39
39
|
protected onPortClose(): Promise<void>;
|
|
40
40
|
protected getPath(): string;
|
|
41
|
-
protected stopConnection(): Promise<boolean>;
|
|
41
|
+
protected stopConnection(connectionLost?: boolean): Promise<boolean>;
|
|
42
42
|
protected getNextSeqNo(): number;
|
|
43
43
|
protected send(seqNo: number, data: Buffer): Promise<Buffer>;
|
|
44
44
|
protected getNextMessage(data: Buffer): Buffer;
|
|
@@ -55,10 +55,10 @@ class DirectConnectPeripheral {
|
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
disconnect() {
|
|
58
|
-
return __awaiter(this,
|
|
58
|
+
return __awaiter(this, arguments, void 0, function* (connectionLost = false) {
|
|
59
59
|
try {
|
|
60
60
|
yield this.connectTask.stop();
|
|
61
|
-
yield this.stopConnection();
|
|
61
|
+
yield this.stopConnection(connectionLost);
|
|
62
62
|
delete this.socket;
|
|
63
63
|
}
|
|
64
64
|
catch (err) {
|
|
@@ -79,68 +79,126 @@ class DirectConnectPeripheral {
|
|
|
79
79
|
}
|
|
80
80
|
discoverServices() {
|
|
81
81
|
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
var _a, _b;
|
|
82
83
|
const seqNo = this.getNextSeqNo();
|
|
83
84
|
const message = new messages_1.DiscoverServiceMessage();
|
|
84
85
|
const request = message.createRequest(seqNo, {});
|
|
86
|
+
let response;
|
|
85
87
|
this.logEvent({ message: 'DiscoverServices request', path: this.getPath(), raw: request.toString('hex') });
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
try {
|
|
89
|
+
response = yield this.send(seqNo, request);
|
|
90
|
+
const res = message.parseResponse(response);
|
|
91
|
+
const uuids = res.body.serviceDefinitions.map(s => (0, utils_1.beautifyUUID)(s.serviceUUID));
|
|
92
|
+
const rc = (0, messages_1.RC)((_a = res === null || res === void 0 ? void 0 : res.header) === null || _a === void 0 ? void 0 : _a.respCode);
|
|
93
|
+
if (((_b = res === null || res === void 0 ? void 0 : res.header) === null || _b === void 0 ? void 0 : _b.respCode) !== consts_1.DC_RC_REQUEST_COMPLETED_SUCCESSFULLY) {
|
|
94
|
+
this.logEvent({ message: 'DiscoverServices failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: rc });
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
this.logEvent({ message: 'DiscoverServices response', path: this.getPath(), rc, uuids, raw: response.toString('hex') });
|
|
98
|
+
return res.body.serviceDefinitions.map(s => s.serviceUUID);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
this.logEvent({ message: 'DiscoverServices failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: err.message });
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
91
104
|
});
|
|
92
105
|
}
|
|
93
106
|
discoverCharacteristics(serviceUUID) {
|
|
94
107
|
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
var _a, _b;
|
|
95
109
|
const seqNo = this.getNextSeqNo();
|
|
96
110
|
const message = new messages_1.DiscoverCharacteristicsMessage();
|
|
97
111
|
const request = message.createRequest(seqNo, { serviceUUID: (0, utils_1.parseUUID)(serviceUUID) });
|
|
112
|
+
let response;
|
|
98
113
|
this.logEvent({ message: 'DiscoverCharacteritics request', path: this.getPath(), service: (0, utils_1.beautifyUUID)(serviceUUID), raw: request.toString('hex') });
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
114
|
+
try {
|
|
115
|
+
response = yield this.send(seqNo, request);
|
|
116
|
+
const res = message.parseResponse(response);
|
|
117
|
+
const rc = (0, messages_1.RC)((_a = res === null || res === void 0 ? void 0 : res.header) === null || _a === void 0 ? void 0 : _a.respCode);
|
|
118
|
+
if (((_b = res === null || res === void 0 ? void 0 : res.header) === null || _b === void 0 ? void 0 : _b.respCode) !== consts_1.DC_RC_REQUEST_COMPLETED_SUCCESSFULLY) {
|
|
119
|
+
this.logEvent({ message: 'DiscoverCharacteritics failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: rc });
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
const service = (0, utils_1.beautifyUUID)(res.body.serviceUUID);
|
|
123
|
+
const characteristics = res.body.characteristicDefinitions.map(cd => `${(0, utils_1.beautifyUUID)(cd.characteristicUUID)}:${cd.properties.join('/')}`);
|
|
124
|
+
this.logEvent({ message: 'DiscoverCharacteritics response', path: this.getPath(), rc, service, characteristics, raw: response.toString('hex') });
|
|
125
|
+
return res.body.characteristicDefinitions.map(c => ({ uuid: c.characteristicUUID, properties: c.properties }));
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
this.logEvent({ message: 'DiscoverCharacteritics failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: err.message });
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
105
131
|
});
|
|
106
132
|
}
|
|
107
133
|
subscribe(characteristicUUID, callback) {
|
|
108
134
|
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
+
var _a, _b;
|
|
136
|
+
const uuid = (0, utils_1.parseUUID)(characteristicUUID);
|
|
137
|
+
if (this.subscribed.includes(uuid)) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
109
140
|
const seqNo = this.getNextSeqNo();
|
|
110
141
|
const message = new messages_1.EnableCharacteristicNotificationsMessage();
|
|
111
142
|
const request = message.createRequest(seqNo, { characteristicUUID: (0, utils_1.parseUUID)(characteristicUUID), enable: true });
|
|
143
|
+
let response;
|
|
112
144
|
this.logEvent({ message: 'EnableCharacteristicNotifications request', path: this.getPath(), characteristic: (0, utils_1.beautifyUUID)(characteristicUUID), enabled: true, raw: request.toString('hex') });
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
});
|
|
122
|
-
|
|
145
|
+
try {
|
|
146
|
+
response = yield this.send(seqNo, request);
|
|
147
|
+
const res = message.parseResponse(response);
|
|
148
|
+
const rc = (0, messages_1.RC)((_a = res === null || res === void 0 ? void 0 : res.header) === null || _a === void 0 ? void 0 : _a.respCode);
|
|
149
|
+
if (((_b = res === null || res === void 0 ? void 0 : res.header) === null || _b === void 0 ? void 0 : _b.respCode) !== consts_1.DC_RC_REQUEST_COMPLETED_SUCCESSFULLY) {
|
|
150
|
+
this.logEvent({ message: 'EnableCharacteristicNotifications failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: rc });
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
this.logEvent({ message: 'EnableCharacteristicNotifications response', path: this.getPath(), rc, characteristic: (0, utils_1.beautifyUUID)(res.body.characteristicUUID), raw: response.toString('hex') });
|
|
154
|
+
const confirmed = res.body.characteristicUUID;
|
|
155
|
+
if ((0, utils_1.parseUUID)(confirmed) === (0, utils_1.parseUUID)(characteristicUUID)) {
|
|
156
|
+
this.subscribed.push((0, utils_1.parseUUID)(characteristicUUID));
|
|
157
|
+
if (callback) {
|
|
158
|
+
this.eventEmitter.on((0, utils_1.parseUUID)(characteristicUUID), (data) => {
|
|
159
|
+
callback(characteristicUUID, data);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
this.logEvent({ message: 'EnableCharacteristicNotifications failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: err.message });
|
|
168
|
+
return false;
|
|
123
169
|
}
|
|
124
|
-
return false;
|
|
125
170
|
});
|
|
126
171
|
}
|
|
127
172
|
unsubscribe(characteristicUUID) {
|
|
128
173
|
return __awaiter(this, void 0, void 0, function* () {
|
|
174
|
+
var _a, _b;
|
|
129
175
|
try {
|
|
130
176
|
const seqNo = this.getNextSeqNo();
|
|
131
177
|
const message = new messages_1.EnableCharacteristicNotificationsMessage();
|
|
132
178
|
const request = message.createRequest(seqNo, { characteristicUUID: (0, utils_1.parseUUID)(characteristicUUID), enable: false });
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
179
|
+
let response;
|
|
180
|
+
try {
|
|
181
|
+
this.logEvent({ message: 'EnableCharacteristicNotifications request', path: this.getPath(), characteristic: (0, utils_1.beautifyUUID)(characteristicUUID), enabled: false, raw: request.toString('hex') });
|
|
182
|
+
response = yield this.send(seqNo, request);
|
|
183
|
+
const res = message.parseResponse(response);
|
|
184
|
+
const rc = (0, messages_1.RC)((_a = res === null || res === void 0 ? void 0 : res.header) === null || _a === void 0 ? void 0 : _a.respCode);
|
|
185
|
+
if (((_b = res === null || res === void 0 ? void 0 : res.header) === null || _b === void 0 ? void 0 : _b.respCode) !== consts_1.DC_RC_REQUEST_COMPLETED_SUCCESSFULLY) {
|
|
186
|
+
this.logEvent({ message: 'EnableCharacteristicNotifications failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: rc });
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
this.logEvent({ message: 'EnableCharacteristicNotifications response', path: this.getPath(), rc, characteristic: (0, utils_1.beautifyUUID)(res.body.characteristicUUID), raw: response.toString('hex') });
|
|
190
|
+
const confirmed = res.body.characteristicUUID;
|
|
191
|
+
if ((0, utils_1.parseUUID)(confirmed) === (0, utils_1.parseUUID)(characteristicUUID)) {
|
|
192
|
+
this.subscribed.splice(this.subscribed.indexOf((0, utils_1.parseUUID)(characteristicUUID)), 1);
|
|
193
|
+
this.eventEmitter.removeAllListeners((0, utils_1.parseUUID)(characteristicUUID));
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
this.logEvent({ message: 'EnableCharacteristicNotifications failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: err.message });
|
|
200
|
+
return false;
|
|
142
201
|
}
|
|
143
|
-
return false;
|
|
144
202
|
}
|
|
145
203
|
catch (err) {
|
|
146
204
|
this.logEvent({ messsage: 'EnableCharacteristicNotifications failed', reason: err.message });
|
|
@@ -158,9 +216,8 @@ class DirectConnectPeripheral {
|
|
|
158
216
|
catch (err) {
|
|
159
217
|
this.logEvent({ message: 'could not discover services', reason: err.message });
|
|
160
218
|
}
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
const service = services[i];
|
|
219
|
+
for (const element of services) {
|
|
220
|
+
const service = element;
|
|
164
221
|
let characteristics = [];
|
|
165
222
|
try {
|
|
166
223
|
characteristics = yield this.discoverCharacteristics(service);
|
|
@@ -171,8 +228,8 @@ class DirectConnectPeripheral {
|
|
|
171
228
|
}
|
|
172
229
|
if (!(characteristics === null || characteristics === void 0 ? void 0 : characteristics.length))
|
|
173
230
|
continue;
|
|
174
|
-
for (
|
|
175
|
-
const characteristic =
|
|
231
|
+
for (const element of characteristics) {
|
|
232
|
+
const characteristic = element;
|
|
176
233
|
if (characteristic.properties.includes('notify'))
|
|
177
234
|
yield this.subscribe(characteristic.uuid, callback);
|
|
178
235
|
}
|
|
@@ -187,69 +244,124 @@ class DirectConnectPeripheral {
|
|
|
187
244
|
}
|
|
188
245
|
subscribeSelected(characteristics, callback) {
|
|
189
246
|
return __awaiter(this, void 0, void 0, function* () {
|
|
247
|
+
let services = [];
|
|
248
|
+
let supported = [];
|
|
249
|
+
try {
|
|
250
|
+
services = yield this.discoverServices();
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
this.logEvent({ message: 'could not discover services', reason: err.message });
|
|
254
|
+
}
|
|
255
|
+
for (const element of services) {
|
|
256
|
+
const service = element;
|
|
257
|
+
try {
|
|
258
|
+
const c = yield this.discoverCharacteristics(service);
|
|
259
|
+
supported = supported.concat(c);
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
this.logEvent({ message: 'could not discover characteristics', service, reason: err.message });
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
190
266
|
const retry = [];
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
267
|
+
this.logEvent({ message: 'characteristics supported', requested: characteristics.map(c => (0, utils_1.beautifyUUID)(c)), supported: supported.map(c => (0, utils_1.beautifyUUID)(c.uuid)) });
|
|
268
|
+
for (const element of characteristics) {
|
|
269
|
+
const uuid = element;
|
|
270
|
+
const found = supported.find(c => (0, utils_1.beautifyUUID)(c.uuid) === (0, utils_1.beautifyUUID)(uuid));
|
|
271
|
+
if (!found) {
|
|
272
|
+
this.logEvent({ message: 'characteristic not supported', requested: (0, utils_1.beautifyUUID)(uuid) });
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
const success = yield this.subscribe(uuid, callback);
|
|
276
|
+
if (!success)
|
|
277
|
+
retry.push(uuid);
|
|
278
|
+
}
|
|
196
279
|
}
|
|
197
|
-
for (
|
|
198
|
-
const c =
|
|
280
|
+
for (const element of retry) {
|
|
281
|
+
const c = element;
|
|
199
282
|
yield this.subscribe(c.uuid, callback);
|
|
200
283
|
}
|
|
201
284
|
return true;
|
|
202
285
|
});
|
|
203
286
|
}
|
|
204
287
|
unsubscribeAll() {
|
|
205
|
-
return __awaiter(this,
|
|
288
|
+
return __awaiter(this, arguments, void 0, function* (connectionLost = false) {
|
|
289
|
+
if (connectionLost) {
|
|
290
|
+
this.subscribed = [];
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
206
293
|
const promises = [];
|
|
207
294
|
this.subscribed.forEach(characteristicUUID => {
|
|
208
|
-
promises.push(this.unsubscribe(characteristicUUID));
|
|
295
|
+
promises.push(this.unsubscribe((0, utils_1.parseUUID)(characteristicUUID)));
|
|
209
296
|
});
|
|
210
297
|
yield Promise.allSettled(promises);
|
|
211
|
-
return true;
|
|
212
298
|
});
|
|
213
299
|
}
|
|
214
300
|
read(characteristicUUID) {
|
|
215
301
|
return __awaiter(this, void 0, void 0, function* () {
|
|
302
|
+
var _a, _b;
|
|
216
303
|
const seqNo = this.getNextSeqNo();
|
|
217
304
|
const message = new messages_1.ReadCharacteristicMessage();
|
|
218
305
|
const request = message.createRequest(seqNo, { characteristicUUID: (0, utils_1.parseUUID)(characteristicUUID) });
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
306
|
+
let response;
|
|
307
|
+
try {
|
|
308
|
+
this.logEvent({ message: 'ReadCharacteristic request', path: this.getPath(), characteristic: (0, utils_1.beautifyUUID)(characteristicUUID), raw: request.toString('hex') });
|
|
309
|
+
response = yield this.send(seqNo, request);
|
|
310
|
+
const res = message.parseResponse(response);
|
|
311
|
+
const rc = (0, messages_1.RC)((_a = res === null || res === void 0 ? void 0 : res.header) === null || _a === void 0 ? void 0 : _a.respCode);
|
|
312
|
+
if (((_b = res === null || res === void 0 ? void 0 : res.header) === null || _b === void 0 ? void 0 : _b.respCode) !== consts_1.DC_RC_REQUEST_COMPLETED_SUCCESSFULLY) {
|
|
313
|
+
this.logEvent({ message: 'ReadCharacteristic failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: rc });
|
|
314
|
+
return Buffer.from([]);
|
|
315
|
+
}
|
|
316
|
+
this.logEvent({ message: 'ReadCharacteristic response', path: this.getPath(), rc, characteristic: (0, utils_1.beautifyUUID)(res.body.characteristicUUID),
|
|
317
|
+
data: Buffer.from(res.body.characteristicData).toString('hex'),
|
|
318
|
+
raw: response.toString('hex') });
|
|
319
|
+
return Buffer.from(res.body.characteristicData);
|
|
320
|
+
}
|
|
321
|
+
catch (err) {
|
|
322
|
+
this.logEvent({ message: 'ReadCharacteristic failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: err.message });
|
|
323
|
+
return Buffer.from([]);
|
|
324
|
+
}
|
|
226
325
|
});
|
|
227
326
|
}
|
|
228
327
|
write(characteristicUUID, data, options) {
|
|
229
328
|
return __awaiter(this, void 0, void 0, function* () {
|
|
230
329
|
return new Promise(resolve => {
|
|
330
|
+
const seqNo = this.getNextSeqNo();
|
|
331
|
+
const message = new messages_1.WriteCharacteristicMessage();
|
|
332
|
+
const request = message.createRequest(seqNo, { characteristicUUID: (0, utils_1.parseUUID)(characteristicUUID), characteristicData: data });
|
|
333
|
+
let response;
|
|
334
|
+
let characteristic = characteristicUUID;
|
|
231
335
|
if (!(options === null || options === void 0 ? void 0 : options.withoutResponse)) {
|
|
336
|
+
this.subscribe(characteristicUUID);
|
|
232
337
|
const uuid = (0, utils_1.parseUUID)(characteristicUUID);
|
|
233
338
|
this.eventEmitter.once(uuid, (data) => {
|
|
234
339
|
resolve(data);
|
|
235
340
|
});
|
|
236
341
|
}
|
|
237
|
-
const seqNo = this.getNextSeqNo();
|
|
238
|
-
const message = new messages_1.WriteCharacteristicMessage();
|
|
239
|
-
const request = message.createRequest(seqNo, { characteristicUUID: (0, utils_1.parseUUID)(characteristicUUID), characteristicData: data });
|
|
240
342
|
this.logEvent({ message: 'WriteCharacteristic request', path: this.getPath(), characteristic: (0, utils_1.beautifyUUID)(characteristicUUID),
|
|
241
343
|
data: data.toString('hex'),
|
|
242
344
|
raw: request.toString('hex') });
|
|
243
|
-
this.send(seqNo, request).then((
|
|
345
|
+
this.send(seqNo, request).then((data) => {
|
|
346
|
+
var _a, _b;
|
|
347
|
+
response = data;
|
|
244
348
|
const res = message.parseResponse(response);
|
|
245
|
-
|
|
246
|
-
|
|
349
|
+
const rc = (0, messages_1.RC)((_a = res === null || res === void 0 ? void 0 : res.header) === null || _a === void 0 ? void 0 : _a.respCode);
|
|
350
|
+
if (((_b = res === null || res === void 0 ? void 0 : res.header) === null || _b === void 0 ? void 0 : _b.respCode) !== consts_1.DC_RC_REQUEST_COMPLETED_SUCCESSFULLY) {
|
|
351
|
+
this.logEvent({ message: 'WriteCharacteristic failed', path: this.getPath(), raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: rc });
|
|
352
|
+
resolve(Buffer.from([]));
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
characteristic = (0, utils_1.beautifyUUID)(res.body.characteristicUUID);
|
|
356
|
+
this.logEvent({ message: 'WriteCharacteristic response', path: this.getPath(), rc, characteristic,
|
|
357
|
+
raw: response.toString('hex') });
|
|
247
358
|
if (options === null || options === void 0 ? void 0 : options.withoutResponse) {
|
|
248
359
|
resolve(Buffer.from([]));
|
|
249
360
|
}
|
|
250
361
|
})
|
|
251
362
|
.catch(err => {
|
|
252
|
-
this.logEvent({ message: 'WriteCharacteristic
|
|
363
|
+
this.logEvent({ message: 'WriteCharacteristic failed', path: this.getPath(), characteristic, raw: response === null || response === void 0 ? void 0 : response.toString('hex'), reason: err.message });
|
|
364
|
+
resolve(Buffer.from([]));
|
|
253
365
|
});
|
|
254
366
|
});
|
|
255
367
|
});
|
|
@@ -288,9 +400,10 @@ class DirectConnectPeripheral {
|
|
|
288
400
|
onPortClose() {
|
|
289
401
|
return __awaiter(this, void 0, void 0, function* () {
|
|
290
402
|
this.socket.removeAllListeners();
|
|
403
|
+
this.socket.on('error', () => { });
|
|
291
404
|
this.logEvent({ message: 'port closed', path: this.getPath() });
|
|
292
405
|
try {
|
|
293
|
-
yield this.disconnect();
|
|
406
|
+
yield this.disconnect(true);
|
|
294
407
|
}
|
|
295
408
|
catch (_a) { }
|
|
296
409
|
if (this.onDisconnectHandler)
|
|
@@ -303,11 +416,11 @@ class DirectConnectPeripheral {
|
|
|
303
416
|
return path;
|
|
304
417
|
}
|
|
305
418
|
stopConnection() {
|
|
306
|
-
return __awaiter(this,
|
|
419
|
+
return __awaiter(this, arguments, void 0, function* (connectionLost = false) {
|
|
307
420
|
this.eventEmitter.removeAllListeners();
|
|
308
421
|
if (!this.isConnected())
|
|
309
422
|
return true;
|
|
310
|
-
yield this.unsubscribeAll();
|
|
423
|
+
yield this.unsubscribeAll(connectionLost);
|
|
311
424
|
this.socket.removeAllListeners();
|
|
312
425
|
return new Promise(done => {
|
|
313
426
|
const onClosed = () => {
|
|
@@ -362,7 +475,7 @@ class DirectConnectPeripheral {
|
|
|
362
475
|
}
|
|
363
476
|
if (incoming.length > header.length + 6) {
|
|
364
477
|
this.remainingBuffer = Buffer.from(incoming.subarray(header.length + 6));
|
|
365
|
-
incoming = incoming.subarray(0, header.length + 6);
|
|
478
|
+
incoming = Buffer.from(incoming.subarray(0, header.length + 6));
|
|
366
479
|
}
|
|
367
480
|
return incoming;
|
|
368
481
|
}
|
|
@@ -386,7 +499,7 @@ class DirectConnectPeripheral {
|
|
|
386
499
|
this.msgSeqNo = notification.header.seqNum;
|
|
387
500
|
const uuid = (0, utils_1.parseUUID)(notification.body.characteristicUUID);
|
|
388
501
|
this.logEvent({ message: 'Characteristic notification', path: this.getPath(), characteristic: (0, utils_1.beautifyUUID)(notification.body.characteristicUUID),
|
|
389
|
-
data: Buffer.from(notification.body.characteristicData).toString('hex') });
|
|
502
|
+
data: Buffer.from(notification.body.characteristicData).toString('hex'), raw: incoming.toString('hex') });
|
|
390
503
|
this.eventEmitter.emit(uuid, notification.body.characteristicData);
|
|
391
504
|
}
|
|
392
505
|
else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseHeader = exports.Message = void 0;
|
|
3
|
+
exports.RC = exports.parseHeader = exports.Message = void 0;
|
|
4
4
|
const consts_1 = require("../consts");
|
|
5
5
|
const error_1 = require("./error");
|
|
6
6
|
class Message {
|
|
@@ -88,3 +88,18 @@ const parseHeader = (buffer) => {
|
|
|
88
88
|
return { msgVersion, msgId, seqNum, respCode, length };
|
|
89
89
|
};
|
|
90
90
|
exports.parseHeader = parseHeader;
|
|
91
|
+
const RC = (code) => {
|
|
92
|
+
switch (code) {
|
|
93
|
+
case consts_1.DC_RC_REQUEST_COMPLETED_SUCCESSFULLY: return 'success';
|
|
94
|
+
case consts_1.DC_RC_UNKNOWN_MESSAGE_TYPE: return 'Unknown Message Type';
|
|
95
|
+
case consts_1.DC_RC_UNEXPECTED_ERROR: return 'Unexpected Error';
|
|
96
|
+
case consts_1.DC_RC_SERVICE_NOT_FOUND: return 'Service Not Found';
|
|
97
|
+
case consts_1.DC_RC_CHARACTERISTIC_NOT_FOUND: return 'Characteristic Not Found';
|
|
98
|
+
case consts_1.DC_RC_CHARACTERISTIC_OPERATION_NOT_SUPPORTED: return 'Characteristic Operation Not Supported';
|
|
99
|
+
case consts_1.DC_RC_CHARACTERISTIC_WRITE_FAILED_INVALID_SIZE: return 'Characteristic Write Failed';
|
|
100
|
+
case consts_1.DC_RC_UNKNOWN_PROTOCOL_VERSION: return 'Unknown Protocol Version';
|
|
101
|
+
default:
|
|
102
|
+
return `Unknown (${code})`;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
exports.RC = RC;
|
|
@@ -3,8 +3,8 @@ import SmartTrainerCyclingMode from "./antble-smarttrainer";
|
|
|
3
3
|
import { UpdateRequest } from "./types";
|
|
4
4
|
export default class AntAdvSimCyclingMode extends SmartTrainerCyclingMode {
|
|
5
5
|
constructor(adapter: IncyclistDeviceAdapter, props?: any);
|
|
6
|
-
getName(): string;
|
|
7
6
|
getDescription(): string;
|
|
7
|
+
getConfig(): import("./types").CyclingModeConfig;
|
|
8
8
|
checkForResetOrEmpty(request: UpdateRequest): UpdateRequest | undefined;
|
|
9
9
|
protected checkForTempPowerAdjustments(request: UpdateRequest, newRequest?: UpdateRequest): void;
|
|
10
10
|
protected checkEmptyRequest(newRequest: UpdateRequest): void;
|
|
@@ -10,12 +10,14 @@ class AntAdvSimCyclingMode extends antble_smarttrainer_1.default {
|
|
|
10
10
|
super(adapter, props);
|
|
11
11
|
this.initLogger('AdvmartTrainerMode');
|
|
12
12
|
}
|
|
13
|
-
getName() {
|
|
14
|
-
return 'Advanced Smart Trainer';
|
|
15
|
-
}
|
|
16
13
|
getDescription() {
|
|
17
14
|
return 'Sends Slope to device. Respects Limits (from workout or settings). Calculates speed based on power and slope. ';
|
|
18
15
|
}
|
|
16
|
+
getConfig() {
|
|
17
|
+
const config = super.getConfig();
|
|
18
|
+
config.name = 'Advanced Smart Trainer';
|
|
19
|
+
return config;
|
|
20
|
+
}
|
|
19
21
|
checkForResetOrEmpty(request) {
|
|
20
22
|
if (!request || request.reset) {
|
|
21
23
|
this.prevRequest = {};
|
package/lib/types/adapter.d.ts
CHANGED
|
@@ -46,5 +46,8 @@ export interface IAdapter extends EventEmitter, IBike, ISensor {
|
|
|
46
46
|
resume(): Promise<boolean>;
|
|
47
47
|
connect(): Promise<boolean>;
|
|
48
48
|
close(): Promise<boolean>;
|
|
49
|
+
resetData(): void;
|
|
50
|
+
onScanStart(): void;
|
|
51
|
+
onScanStop(): void;
|
|
49
52
|
onData(callback: OnDeviceDataCallback): any;
|
|
50
53
|
}
|
package/lib/utils/task.d.ts
CHANGED
|
@@ -30,15 +30,18 @@ export declare class InteruptableTask<T extends TaskState, P> {
|
|
|
30
30
|
protected props?: TaskProps<T, P>;
|
|
31
31
|
protected internalEvents: EventEmitter<[never]>;
|
|
32
32
|
protected promise?: Promise<P>;
|
|
33
|
+
protected onStopNotifiers: Array<() => void>;
|
|
33
34
|
constructor(promise: Promise<any>, props?: TaskProps<T, P>);
|
|
34
35
|
getPromise(): Promise<P>;
|
|
35
36
|
getState(): T;
|
|
36
37
|
run(): Promise<P>;
|
|
38
|
+
notifyOnStop(cb: () => void): void;
|
|
37
39
|
start(): void;
|
|
38
40
|
stop(): Promise<boolean>;
|
|
39
41
|
isRunning(): boolean;
|
|
40
42
|
protected clearTimeout(): void;
|
|
41
43
|
protected onTimeout(): void;
|
|
44
|
+
protected sendStopNotification(): void;
|
|
42
45
|
protected logEvent(event: any): void;
|
|
43
46
|
}
|
|
44
47
|
export {};
|
package/lib/utils/task.js
CHANGED
|
@@ -20,6 +20,7 @@ class InteruptableTask {
|
|
|
20
20
|
var _a;
|
|
21
21
|
this.internalState = { isRunning: false };
|
|
22
22
|
this.internalEvents = new events_1.default();
|
|
23
|
+
this.onStopNotifiers = [];
|
|
23
24
|
this.state = ((_a = props === null || props === void 0 ? void 0 : props.state) !== null && _a !== void 0 ? _a : {});
|
|
24
25
|
this.props = props;
|
|
25
26
|
delete this.props.state;
|
|
@@ -39,6 +40,9 @@ class InteruptableTask {
|
|
|
39
40
|
return this.internalState.promise;
|
|
40
41
|
});
|
|
41
42
|
}
|
|
43
|
+
notifyOnStop(cb) {
|
|
44
|
+
this.onStopNotifiers.push(cb);
|
|
45
|
+
}
|
|
42
46
|
start() {
|
|
43
47
|
this.internalState.promise = new Promise((resolve, reject) => {
|
|
44
48
|
var _a;
|
|
@@ -59,8 +63,10 @@ class InteruptableTask {
|
|
|
59
63
|
isRunning: false,
|
|
60
64
|
};
|
|
61
65
|
this.internalEvents.removeAllListeners();
|
|
66
|
+
this.sendStopNotification();
|
|
62
67
|
if (this.getState().result === 'completed' || this.getState().result === 'error')
|
|
63
68
|
return;
|
|
69
|
+
this.getState().result = 'stopped';
|
|
64
70
|
if (this.props.onDone)
|
|
65
71
|
resolve(this.props.onDone(this.getState()));
|
|
66
72
|
else
|
|
@@ -119,6 +125,12 @@ class InteruptableTask {
|
|
|
119
125
|
else
|
|
120
126
|
resolve(null);
|
|
121
127
|
}
|
|
128
|
+
sendStopNotification() {
|
|
129
|
+
this.onStopNotifiers.forEach((cb) => {
|
|
130
|
+
if (typeof cb === 'function')
|
|
131
|
+
cb();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
122
134
|
logEvent(event) {
|
|
123
135
|
if (this.props.log)
|
|
124
136
|
this.props.log(event);
|