@ovok/native 1.16.1-dev.2175 → 1.16.1-dev.2179
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/commonjs/modules/bt-management/services/devices/bp2/bp2.device.js +16 -6
- package/lib/commonjs/modules/bt-management/services/devices/bp2/bp2.device.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/bp2/bp2.frame-reader.js +2 -2
- package/lib/commonjs/modules/bt-management/services/devices/bp2/bp2.frame-reader.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/custom/custom-lepu-sequencer.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/custom/custom.device.js +33 -12
- package/lib/commonjs/modules/bt-management/services/devices/custom/custom.device.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.advertisement.js +19 -2
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.advertisement.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.ecg-transfer.js +18 -3
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.ecg-transfer.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.encryption-handshake.js +103 -0
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.encryption-handshake.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.frame-reader.js +4 -2
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.frame-reader.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.session.js +49 -0
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.session.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/lepu/lepu.transports.js +4 -4
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom.bp-monitors.js +0 -1
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom.bp-monitors.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom.ecg-recorders.js +19 -8
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom.ecg-recorders.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/bp2/bp2.device.js +16 -6
- package/lib/module/modules/bt-management/services/devices/bp2/bp2.device.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/bp2/bp2.frame-reader.js +2 -3
- package/lib/module/modules/bt-management/services/devices/bp2/bp2.frame-reader.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/custom/custom-lepu-sequencer.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/custom/custom.device.js +33 -12
- package/lib/module/modules/bt-management/services/devices/custom/custom.device.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.advertisement.js +17 -1
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.advertisement.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.ecg-transfer.js +18 -3
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.ecg-transfer.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.encryption-handshake.js +99 -0
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.encryption-handshake.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.frame-reader.js +4 -2
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.frame-reader.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.session.js +45 -0
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.session.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/lepu/lepu.transports.js +4 -4
- package/lib/module/modules/bt-management/services/devices/viatom/viatom.bp-monitors.js +0 -1
- package/lib/module/modules/bt-management/services/devices/viatom/viatom.bp-monitors.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/viatom/viatom.ecg-recorders.js +19 -8
- package/lib/module/modules/bt-management/services/devices/viatom/viatom.ecg-recorders.js.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.frame-reader.d.ts +2 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.frame-reader.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/custom/custom-lepu-sequencer.d.ts +2 -2
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/custom/custom-lepu-sequencer.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/custom/custom.device.d.ts +6 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/custom/custom.device.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.advertisement.d.ts +8 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.advertisement.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.ecg-transfer.d.ts +2 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.ecg-transfer.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.encryption-handshake.d.ts +20 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.encryption-handshake.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.frame-reader.d.ts +3 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.frame-reader.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.session.d.ts +17 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/lepu/lepu.session.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom.bp-monitors.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom.ecg-recorders.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/types/custom-lepu-spec.d.ts +4 -1
- package/lib/typescript/commonjs/src/modules/bt-management/types/custom-lepu-spec.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/bp2/bp2.frame-reader.d.ts +2 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/bp2/bp2.frame-reader.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/custom/custom-lepu-sequencer.d.ts +2 -2
- package/lib/typescript/module/src/modules/bt-management/services/devices/custom/custom-lepu-sequencer.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/custom/custom.device.d.ts +6 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/custom/custom.device.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.advertisement.d.ts +8 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.advertisement.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.ecg-transfer.d.ts +2 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.ecg-transfer.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.encryption-handshake.d.ts +20 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.encryption-handshake.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.frame-reader.d.ts +3 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.frame-reader.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.session.d.ts +17 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/lepu/lepu.session.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom.bp-monitors.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom.ecg-recorders.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/types/custom-lepu-spec.d.ts +4 -1
- package/lib/typescript/module/src/modules/bt-management/types/custom-lepu-spec.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -4,8 +4,12 @@ import { base64ToHex } from "../../../utils/base-64-to-hex.js";
|
|
|
4
4
|
import { hexToByte } from "../../../utils/hex-to-byte.js";
|
|
5
5
|
const PROTOCOL_MASK = 0x0f;
|
|
6
6
|
const ENCRYPTION_MASK = 0xf0;
|
|
7
|
+
const ENCRYPTION_OPTIONAL = 0x10;
|
|
7
8
|
const ENCRYPTION_REQUIRED = 0x20;
|
|
8
9
|
const VIATOM_OXYGEN_V2_BYTES = [3, 4];
|
|
10
|
+
const LEPU_FLAG_BYTES = [4, 3];
|
|
11
|
+
const LEPU_PROTOCOLS = [1, 2];
|
|
12
|
+
const ENCRYPTION_LEVELS = [ENCRYPTION_OPTIONAL, ENCRYPTION_REQUIRED];
|
|
9
13
|
const manufacturerBytes = manufacturerData => {
|
|
10
14
|
if (!manufacturerData) {
|
|
11
15
|
return [];
|
|
@@ -21,7 +25,19 @@ const manufacturerByte = (manufacturerData, index) => manufacturerBytes(manufact
|
|
|
21
25
|
/** Returns true when the advertised byte says that only encrypted traffic is accepted. */
|
|
22
26
|
const advertisementRequiresEncryption = (manufacturerData, byteIndexes = []) => byteIndexes.some(index => ((manufacturerByte(manufacturerData, index) ?? 0) & ENCRYPTION_MASK) === ENCRYPTION_REQUIRED);
|
|
23
27
|
|
|
28
|
+
/**
|
|
29
|
+
* True when the advertisement offers or requires the encryption handshake.
|
|
30
|
+
*
|
|
31
|
+
* Byte 4 describes the second service and wins when it names a protocol; otherwise byte 3
|
|
32
|
+
* does. A level of 1 (optional) or 2 (required) is a handshake for the vendor's own client.
|
|
33
|
+
*/
|
|
34
|
+
const advertisesLepuEncryption = manufacturerData => {
|
|
35
|
+
const bytes = manufacturerBytes(manufacturerData);
|
|
36
|
+
const flag = LEPU_FLAG_BYTES.map(index => bytes[index] ?? 0).find(value => LEPU_PROTOCOLS.includes(value & PROTOCOL_MASK));
|
|
37
|
+
return flag !== undefined && ENCRYPTION_LEVELS.includes(flag & ENCRYPTION_MASK);
|
|
38
|
+
};
|
|
39
|
+
|
|
24
40
|
/** The vendor uses the low nibble of byte 3 or 4 to select the OxyII service. */
|
|
25
41
|
const viatomOxygenUsesV2 = manufacturerData => VIATOM_OXYGEN_V2_BYTES.some(index => ((manufacturerByte(manufacturerData, index) ?? 0) & PROTOCOL_MASK) === 2);
|
|
26
|
-
export { advertisementRequiresEncryption, manufacturerBytes, viatomOxygenUsesV2 };
|
|
42
|
+
export { advertisementRequiresEncryption, advertisesLepuEncryption, manufacturerBytes, viatomOxygenUsesV2 };
|
|
27
43
|
//# sourceMappingURL=lepu.advertisement.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["base64ToHex","hexToByte","PROTOCOL_MASK","ENCRYPTION_MASK","ENCRYPTION_REQUIRED","VIATOM_OXYGEN_V2_BYTES","manufacturerBytes","manufacturerData","map","manufacturerByte","index","advertisementRequiresEncryption","byteIndexes","some","viatomOxygenUsesV2"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/lepu/lepu.advertisement.ts"],"mappings":";;AAAA,SAASA,WAAW,QAAQ,kCAA+B;AAC3D,SAASC,SAAS,QAAQ,+BAA4B;AAEtD,MAAMC,aAAa,GAAG,IAAI;AAC1B,MAAMC,eAAe,GAAG,IAAI;AAC5B,MAAMC,mBAAmB,GAAG,IAAI;AAChC,MAAMC,sBAAsB,GAAG,CAAC,CAAC,EAAE,CAAC,CAAU;
|
|
1
|
+
{"version":3,"names":["base64ToHex","hexToByte","PROTOCOL_MASK","ENCRYPTION_MASK","ENCRYPTION_OPTIONAL","ENCRYPTION_REQUIRED","VIATOM_OXYGEN_V2_BYTES","LEPU_FLAG_BYTES","LEPU_PROTOCOLS","ENCRYPTION_LEVELS","manufacturerBytes","manufacturerData","map","manufacturerByte","index","advertisementRequiresEncryption","byteIndexes","some","advertisesLepuEncryption","bytes","flag","find","value","includes","undefined","viatomOxygenUsesV2"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/lepu/lepu.advertisement.ts"],"mappings":";;AAAA,SAASA,WAAW,QAAQ,kCAA+B;AAC3D,SAASC,SAAS,QAAQ,+BAA4B;AAEtD,MAAMC,aAAa,GAAG,IAAI;AAC1B,MAAMC,eAAe,GAAG,IAAI;AAC5B,MAAMC,mBAAmB,GAAG,IAAI;AAChC,MAAMC,mBAAmB,GAAG,IAAI;AAChC,MAAMC,sBAAsB,GAAG,CAAC,CAAC,EAAE,CAAC,CAAU;AAC9C,MAAMC,eAAe,GAAG,CAAC,CAAC,EAAE,CAAC,CAAU;AACvC,MAAMC,cAAc,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AAC7B,MAAMC,iBAAiB,GAAG,CAACL,mBAAmB,EAAEC,mBAAmB,CAAC;AAEpE,MAAMK,iBAAiB,GAAIC,gBAAyB,IAAe;EACjE,IAAI,CAACA,gBAAgB,EAAE;IACrB,OAAO,EAAE;EACX;EAEA,IAAI;IACF,OAAOX,WAAW,CAACW,gBAAgB,CAAC,CAACC,GAAG,CAACX,SAAS,CAAC;EACrD,CAAC,CAAC,MAAM;IACN,OAAO,EAAE;EACX;AACF,CAAC;AAED,MAAMY,gBAAgB,GAAGA,CACvBF,gBAAoC,EACpCG,KAAa,KACUJ,iBAAiB,CAACC,gBAAgB,CAAC,CAACG,KAAK,CAAC;;AAEnE;AACA,MAAMC,+BAA+B,GAAGA,CACtCJ,gBAAoC,EACpCK,WAA8B,GAAG,EAAE,KAEnCA,WAAW,CAACC,IAAI,CACbH,KAAK,IACJ,CAAC,CAACD,gBAAgB,CAACF,gBAAgB,EAAEG,KAAK,CAAC,IAAI,CAAC,IAAIX,eAAe,MACnEE,mBACJ,CAAC;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,MAAMa,wBAAwB,GAAIP,gBAAyB,IAAc;EACvE,MAAMQ,KAAK,GAAGT,iBAAiB,CAACC,gBAAgB,CAAC;EAEjD,MAAMS,IAAI,GAAGb,eAAe,CAACK,GAAG,CAAEE,KAAK,IAAKK,KAAK,CAACL,KAAK,CAAC,IAAI,CAAC,CAAC,CAACO,IAAI,CAChEC,KAAK,IAAKd,cAAc,CAACe,QAAQ,CAACD,KAAK,GAAGpB,aAAa,CAC1D,CAAC;EAED,OAAOkB,IAAI,KAAKI,SAAS,IAAIf,iBAAiB,CAACc,QAAQ,CAACH,IAAI,GAAGjB,eAAe,CAAC;AACjF,CAAC;;AAED;AACA,MAAMsB,kBAAkB,GAAId,gBAAyB,IACnDL,sBAAsB,CAACW,IAAI,CACxBH,KAAK,IACJ,CAAC,CAACD,gBAAgB,CAACF,gBAAgB,EAAEG,KAAK,CAAC,IAAI,CAAC,IAAIZ,aAAa,MAAM,CAC3E,CAAC;AAEH,SACEa,+BAA+B,EAC/BG,wBAAwB,EACxBR,iBAAiB,EACjBe,kBAAkB","ignoreList":[]}
|
|
@@ -7,6 +7,12 @@ import { LepuFileTransfer } from "./lepu.file-transfer.js";
|
|
|
7
7
|
import { lepuCommandOf } from "./lepu.frame.js";
|
|
8
8
|
import { LepuIdentityGate } from "./lepu.identity-gate.js";
|
|
9
9
|
import { describeLepuResponseType, isLepuSuccess } from "./lepu.response-type.js";
|
|
10
|
+
/** How long past its delay a poll may go unanswered before it is sent again. */
|
|
11
|
+
const POLL_ANSWER_GRACE_MS = 1_000;
|
|
12
|
+
|
|
13
|
+
/** Lets a device finish writing a record before its file list is read. */
|
|
14
|
+
const FILE_LIST_DELAY_MS = 3_000;
|
|
15
|
+
|
|
10
16
|
/** Identifies a recorder, sets its local clock, then downloads its stored files. */
|
|
11
17
|
class LepuEcgTransferSequencer {
|
|
12
18
|
phase = "identity";
|
|
@@ -30,6 +36,9 @@ class LepuEcgTransferSequencer {
|
|
|
30
36
|
if (this.phase === "identity") {
|
|
31
37
|
return this.identity.commandTimeoutMs();
|
|
32
38
|
}
|
|
39
|
+
if (this.phase === "polling" && this.params.pollIntervalMs !== undefined) {
|
|
40
|
+
return this.params.pollIntervalMs + POLL_ANSWER_GRACE_MS;
|
|
41
|
+
}
|
|
33
42
|
return this.phase === "clock" ? LEPU_CONNECT_REPLY_TIMEOUT_MS : undefined;
|
|
34
43
|
};
|
|
35
44
|
|
|
@@ -38,6 +47,11 @@ class LepuEcgTransferSequencer {
|
|
|
38
47
|
if (this.phase === "identity") {
|
|
39
48
|
return this.identity.onCommandTimeout();
|
|
40
49
|
}
|
|
50
|
+
if (this.phase === "polling") {
|
|
51
|
+
return {
|
|
52
|
+
commands: [this.pollCommand()]
|
|
53
|
+
};
|
|
54
|
+
}
|
|
41
55
|
if (this.phase !== "clock") {
|
|
42
56
|
return {};
|
|
43
57
|
}
|
|
@@ -49,7 +63,8 @@ class LepuEcgTransferSequencer {
|
|
|
49
63
|
if (this.phase === "identity") {
|
|
50
64
|
return this.identity.commandProgress(frame);
|
|
51
65
|
}
|
|
52
|
-
|
|
66
|
+
const awaited = this.phase === "clock" ? LepuCommand.SET_TIME : this.phase === "polling" ? this.params.pollCommand : undefined;
|
|
67
|
+
return awaited !== undefined && lepuCommandOf(frame) !== awaited ? "ignored" : "complete";
|
|
53
68
|
};
|
|
54
69
|
nextCommand = frame => {
|
|
55
70
|
if (this.phase === "identity") {
|
|
@@ -62,7 +77,7 @@ class LepuEcgTransferSequencer {
|
|
|
62
77
|
if (this.params.pollCommand === undefined || lepuCommandOf(frame) !== this.params.pollCommand) {
|
|
63
78
|
return undefined;
|
|
64
79
|
}
|
|
65
|
-
return this.startTransfer(
|
|
80
|
+
return this.params.shouldStartTransfer?.() ?? true ? this.startTransfer(FILE_LIST_DELAY_MS) : [this.pollCommand()];
|
|
66
81
|
}
|
|
67
82
|
return this.transfer?.nextCommand(frame);
|
|
68
83
|
};
|
|
@@ -107,7 +122,7 @@ class LepuEcgTransferSequencer {
|
|
|
107
122
|
this.phase = "polling";
|
|
108
123
|
return [this.pollCommand()];
|
|
109
124
|
}
|
|
110
|
-
return
|
|
125
|
+
return [];
|
|
111
126
|
};
|
|
112
127
|
pollCommand = () => ({
|
|
113
128
|
...this.params.write,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["getClockParts","isClockSyncEnabled","LepuCommand","LEPU_CONNECT_REPLY_TIMEOUT_MS","LepuConnectRetry","LepuFileTransfer","lepuCommandOf","LepuIdentityGate","describeLepuResponseType","isLepuSuccess","LepuEcgTransferSequencer","phase","clockRetry","constructor","params","identity","write","builder","expectedDeviceTypes","manufacturerData","rejectEncryptionAtBytes","onIdentified","onRefused","onAdmitted","startClockOrTransfer","initialCommands","isHistoryTransfer","commandTimeoutMs","undefined","onCommandTimeout","commands","mayRetry","setTimeCommand","startTransfer","commandProgress","frame","SET_TIME","nextCommand","finishClock","
|
|
1
|
+
{"version":3,"names":["getClockParts","isClockSyncEnabled","LepuCommand","LEPU_CONNECT_REPLY_TIMEOUT_MS","LepuConnectRetry","LepuFileTransfer","lepuCommandOf","LepuIdentityGate","describeLepuResponseType","isLepuSuccess","POLL_ANSWER_GRACE_MS","FILE_LIST_DELAY_MS","LepuEcgTransferSequencer","phase","clockRetry","constructor","params","identity","write","builder","expectedDeviceTypes","manufacturerData","rejectEncryptionAtBytes","onIdentified","onRefused","onAdmitted","startClockOrTransfer","initialCommands","isHistoryTransfer","commandTimeoutMs","pollIntervalMs","undefined","onCommandTimeout","commands","pollCommand","mayRetry","setTimeCommand","startTransfer","commandProgress","frame","awaited","SET_TIME","nextCommand","finishClock","shouldStartTransfer","transfer","clockSync","started","build","clockPayload","onError","delayBeforeWriteMs","onFile","skipFiles","acceptFile","afterTransfer","finishTransfer","onProgress","parts","now","Date","timezone","year","month","day","hours","minutes","seconds"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/lepu/lepu.ecg-transfer.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { hexToByte } from "../../../utils/hex-to-byte.js";
|
|
4
|
+
import { createLepuAccessToken, decryptLepuHandshake, parseLepuSessionKey } from "../viatom/viatom-lepu-crypto.js";
|
|
5
|
+
import { advertisesLepuEncryption } from "./lepu.advertisement.js";
|
|
6
|
+
import { LepuCommandBuilder } from "./lepu.command-builder.js";
|
|
7
|
+
import { LEPU_CONNECT_REPLY_TIMEOUT_MS, LepuConnectRetry } from "./lepu.connect-retry.js";
|
|
8
|
+
import { lepuCommandOf, lepuPayloadOf } from "./lepu.frame.js";
|
|
9
|
+
import { isLepuSuccess } from "./lepu.response-type.js";
|
|
10
|
+
const LEPU_ENCRYPT_COMMAND = 0xff;
|
|
11
|
+
/**
|
|
12
|
+
* Runs the vendor's encryption handshake before a standard Lepu exchange, when the
|
|
13
|
+
* advertisement asks for one.
|
|
14
|
+
*
|
|
15
|
+
* The access token goes out in plain text; the reply carries the session key, and from then
|
|
16
|
+
* on every request is encrypted here and every reply is decrypted by the frame reader that
|
|
17
|
+
* shares the session. Without the flag the exchange runs exactly as it did before.
|
|
18
|
+
*/
|
|
19
|
+
class LepuEncryptionHandshake {
|
|
20
|
+
state = "awaiting-key";
|
|
21
|
+
retry = new LepuConnectRetry();
|
|
22
|
+
constructor(inner, params) {
|
|
23
|
+
this.inner = inner;
|
|
24
|
+
this.params = params;
|
|
25
|
+
}
|
|
26
|
+
initialCommands = () => {
|
|
27
|
+
this.retry.started();
|
|
28
|
+
return [this.tokenCommand()];
|
|
29
|
+
};
|
|
30
|
+
nextCommand = (frame, characteristicUuid) => {
|
|
31
|
+
if (this.state === "done") {
|
|
32
|
+
return this.encrypted(this.inner.nextCommand(frame, characteristicUuid));
|
|
33
|
+
}
|
|
34
|
+
if (this.state === "refused" || lepuCommandOf(frame) !== LEPU_ENCRYPT_COMMAND) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return this.acceptKey(frame);
|
|
38
|
+
};
|
|
39
|
+
commandTimeoutMs = () => this.state === "awaiting-key" ? LEPU_CONNECT_REPLY_TIMEOUT_MS : this.state === "done" ? this.inner.commandTimeoutMs?.() : undefined;
|
|
40
|
+
|
|
41
|
+
/** A device just woken can drop the token, so it is sent once more before giving up. */
|
|
42
|
+
onCommandTimeout = () => {
|
|
43
|
+
if (this.state === "done") {
|
|
44
|
+
const result = this.inner.onCommandTimeout?.() ?? {};
|
|
45
|
+
return {
|
|
46
|
+
...result,
|
|
47
|
+
commands: this.encrypted(result.commands)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (this.state === "refused") {
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
return this.retry.mayRetry() ? {
|
|
54
|
+
commands: [this.tokenCommand()]
|
|
55
|
+
} : {
|
|
56
|
+
terminal: true
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
commandProgress = frame => {
|
|
60
|
+
if (this.state === "done") {
|
|
61
|
+
return this.inner.commandProgress?.(frame) ?? "complete";
|
|
62
|
+
}
|
|
63
|
+
return lepuCommandOf(frame) === LEPU_ENCRYPT_COMMAND ? "complete" : "ignored";
|
|
64
|
+
};
|
|
65
|
+
onServicesDiscovered = serviceUuids => this.inner.onServicesDiscovered?.(serviceUuids);
|
|
66
|
+
isNormalDisconnect = () => this.inner.isNormalDisconnect?.() ?? false;
|
|
67
|
+
isHistoryTransfer = () => this.inner.isHistoryTransfer?.() ?? false;
|
|
68
|
+
acceptKey = frame => {
|
|
69
|
+
const reply = lepuPayloadOf(frame).map(hexToByte);
|
|
70
|
+
const key = isLepuSuccess(frame) ? parseLepuSessionKey(decryptLepuHandshake(reply)) : undefined;
|
|
71
|
+
if (!key) {
|
|
72
|
+
this.state = "refused";
|
|
73
|
+
this.params.onRefused("the device refused the encryption handshake");
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
this.params.session.begin(key);
|
|
77
|
+
this.state = "done";
|
|
78
|
+
return this.encrypted(this.inner.initialCommands());
|
|
79
|
+
};
|
|
80
|
+
tokenCommand = () => ({
|
|
81
|
+
...this.params.write,
|
|
82
|
+
frame: new LepuCommandBuilder(this.params.startByte).build(LEPU_ENCRYPT_COMMAND, createLepuAccessToken())
|
|
83
|
+
});
|
|
84
|
+
encrypted = commands => commands?.map(command => ({
|
|
85
|
+
...command,
|
|
86
|
+
frame: this.params.session.encryptFrame(command.frame)
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The sequencer for one connection: wrapped in the handshake when the advertisement asks
|
|
92
|
+
* for encryption, unchanged otherwise. Either way the session starts without a key.
|
|
93
|
+
*/
|
|
94
|
+
const withLepuEncryption = (inner, params) => {
|
|
95
|
+
params.session.end();
|
|
96
|
+
return advertisesLepuEncryption(params.manufacturerData) ? new LepuEncryptionHandshake(inner, params) : inner;
|
|
97
|
+
};
|
|
98
|
+
export { withLepuEncryption };
|
|
99
|
+
//# sourceMappingURL=lepu.encryption-handshake.js.map
|
package/lib/module/modules/bt-management/services/devices/lepu/lepu.encryption-handshake.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["hexToByte","createLepuAccessToken","decryptLepuHandshake","parseLepuSessionKey","advertisesLepuEncryption","LepuCommandBuilder","LEPU_CONNECT_REPLY_TIMEOUT_MS","LepuConnectRetry","lepuCommandOf","lepuPayloadOf","isLepuSuccess","LEPU_ENCRYPT_COMMAND","LepuEncryptionHandshake","state","retry","constructor","inner","params","initialCommands","started","tokenCommand","nextCommand","frame","characteristicUuid","encrypted","undefined","acceptKey","commandTimeoutMs","onCommandTimeout","result","commands","mayRetry","terminal","commandProgress","onServicesDiscovered","serviceUuids","isNormalDisconnect","isHistoryTransfer","reply","map","key","onRefused","session","begin","write","startByte","build","command","encryptFrame","withLepuEncryption","end","manufacturerData"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/lepu/lepu.encryption-handshake.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -27,8 +27,9 @@ const START_PATTERN_BYTES = 3;
|
|
|
27
27
|
* protocol, which is why it is worth having once rather than once per device.
|
|
28
28
|
*/
|
|
29
29
|
export class LepuFrameReader {
|
|
30
|
-
constructor(startBytes) {
|
|
30
|
+
constructor(startBytes, session) {
|
|
31
31
|
this.startBytes = startBytes;
|
|
32
|
+
this.session = session;
|
|
32
33
|
}
|
|
33
34
|
readFrame(buffer) {
|
|
34
35
|
const start = this.findFrameStart(buffer);
|
|
@@ -44,7 +45,8 @@ export class LepuFrameReader {
|
|
|
44
45
|
if (!this.hasValidChecksum(frame)) {
|
|
45
46
|
return corrupt(start + START_PATTERN_BYTES);
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
const plainFrame = this.session ? this.session.decryptFrame(frame) : frame;
|
|
49
|
+
return plainFrame ? complete(plainFrame, start + frameLength) : corrupt(start + frameLength);
|
|
48
50
|
}
|
|
49
51
|
isFrameStart(buffer, index) {
|
|
50
52
|
if (!this.startBytes.includes((buffer[index] || "").toLowerCase())) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["calculateCrc8","complete","corrupt","incomplete","hexToByte","le16FromHex","COMMAND_INDEX","COMMAND_COMPLEMENT_INDEX","PAYLOAD_LENGTH_INDEX","HEADER_BYTES","CHECKSUM_BYTES","BYTE_MASK","START_PATTERN_BYTES","LepuFrameReader","constructor","startBytes","readFrame","buffer","start","findFrameStart","droppableLeadingBytes","payloadLength","frameLength","length","frame","slice","hasValidChecksum","isFrameStart","index","includes","toLowerCase","command","complement","lastCandidate","Math","max","checksummedBytes","declared"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/lepu/lepu.frame-reader.ts"],"mappings":";;AAEA,SAASA,aAAa,QAAQ,mCAAgC;AAC9D,SAASC,QAAQ,EAAEC,OAAO,EAAEC,UAAU,QAAQ,sCAAmC;AACjF,SAASC,SAAS,QAAQ,+BAA4B;AACtD,SAASC,WAAW,QAAQ,kCAA+B;
|
|
1
|
+
{"version":3,"names":["calculateCrc8","complete","corrupt","incomplete","hexToByte","le16FromHex","COMMAND_INDEX","COMMAND_COMPLEMENT_INDEX","PAYLOAD_LENGTH_INDEX","HEADER_BYTES","CHECKSUM_BYTES","BYTE_MASK","START_PATTERN_BYTES","LepuFrameReader","constructor","startBytes","session","readFrame","buffer","start","findFrameStart","droppableLeadingBytes","payloadLength","frameLength","length","frame","slice","hasValidChecksum","plainFrame","decryptFrame","isFrameStart","index","includes","toLowerCase","command","complement","lastCandidate","Math","max","checksummedBytes","declared"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/lepu/lepu.frame-reader.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { byteToHex } from "../../../utils/bytes-to-hex.js";
|
|
4
|
+
import { calculateCrc8 } from "../../../utils/calculate-crc-8.js";
|
|
5
|
+
import { hexToByte } from "../../../utils/hex-to-byte.js";
|
|
6
|
+
import { decryptLepuPayload, encryptLepuPayload } from "../viatom/viatom-lepu-crypto.js";
|
|
7
|
+
import { lepuPayloadOf } from "./lepu.frame.js";
|
|
8
|
+
const PAYLOAD_LENGTH_INDEX = 5;
|
|
9
|
+
const BITS_PER_BYTE = 8;
|
|
10
|
+
const BYTE_MASK = 0xff;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* One connection's AES key, from the moment the device hands it over in the handshake.
|
|
14
|
+
*
|
|
15
|
+
* Requests leave encrypted and replies reach every parser in plain text. Without a key, and
|
|
16
|
+
* for an empty payload, frames pass through unchanged, as the vendor's own client does.
|
|
17
|
+
*/
|
|
18
|
+
class LepuSession {
|
|
19
|
+
begin = key => {
|
|
20
|
+
this.key = [...key];
|
|
21
|
+
};
|
|
22
|
+
end = () => {
|
|
23
|
+
this.key = undefined;
|
|
24
|
+
};
|
|
25
|
+
encryptFrame = frame => this.withPayload(frame, encryptLepuPayload) ?? [...frame];
|
|
26
|
+
|
|
27
|
+
/** The frame in plain text, or `undefined` when its payload does not decrypt. */
|
|
28
|
+
decryptFrame = frame => this.withPayload(frame, decryptLepuPayload);
|
|
29
|
+
withPayload = (frame, transform) => {
|
|
30
|
+
const payload = lepuPayloadOf(frame).map(hexToByte);
|
|
31
|
+
if (!this.key || payload.length === 0) {
|
|
32
|
+
return [...frame];
|
|
33
|
+
}
|
|
34
|
+
const transformed = transform(payload, this.key);
|
|
35
|
+
return transformed && rebuildFrame(frame, transformed);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** The same header with a new payload, its length and its checksum. */
|
|
40
|
+
const rebuildFrame = (frame, payload) => {
|
|
41
|
+
const body = [...frame.slice(0, PAYLOAD_LENGTH_INDEX), byteToHex(payload.length & BYTE_MASK), byteToHex(payload.length >> BITS_PER_BYTE), ...payload.map(byteToHex)];
|
|
42
|
+
return [...body, byteToHex(calculateCrc8(body, body.length))];
|
|
43
|
+
};
|
|
44
|
+
export { LepuSession };
|
|
45
|
+
//# sourceMappingURL=lepu.session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["byteToHex","calculateCrc8","hexToByte","decryptLepuPayload","encryptLepuPayload","lepuPayloadOf","PAYLOAD_LENGTH_INDEX","BITS_PER_BYTE","BYTE_MASK","LepuSession","begin","key","end","undefined","encryptFrame","frame","withPayload","decryptFrame","transform","payload","map","length","transformed","rebuildFrame","body","slice"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/lepu/lepu.session.ts"],"mappings":";;AAAA,SAASA,SAAS,QAAQ,gCAA6B;AACvD,SAASC,aAAa,QAAQ,mCAAgC;AAC9D,SAASC,SAAS,QAAQ,+BAA4B;AACtD,SACEC,kBAAkB,EAClBC,kBAAkB,QACb,iCAA8B;AAErC,SAASC,aAAa,QAAQ,iBAAc;AAE5C,MAAMC,oBAAoB,GAAG,CAAC;AAC9B,MAAMC,aAAa,GAAG,CAAC;AACvB,MAAMC,SAAS,GAAG,IAAI;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,WAAW,CAAC;EAGTC,KAAK,GAAIC,GAAsB,IAAW;IAC/C,IAAI,CAACA,GAAG,GAAG,CAAC,GAAGA,GAAG,CAAC;EACrB,CAAC;EAEMC,GAAG,GAAGA,CAAA,KAAY;IACvB,IAAI,CAACD,GAAG,GAAGE,SAAS;EACtB,CAAC;EAEMC,YAAY,GAAIC,KAAwB,IAC7C,IAAI,CAACC,WAAW,CAACD,KAAK,EAAEX,kBAAkB,CAAC,IAAI,CAAC,GAAGW,KAAK,CAAC;;EAE3D;EACOE,YAAY,GAAIF,KAAwB,IAC7C,IAAI,CAACC,WAAW,CAACD,KAAK,EAAEZ,kBAAkB,CAAC;EAErCa,WAAW,GAAGA,CACpBD,KAAwB,EACxBG,SAA8E,KACrD;IACzB,MAAMC,OAAO,GAAGd,aAAa,CAACU,KAAK,CAAC,CAACK,GAAG,CAAClB,SAAS,CAAC;IAEnD,IAAI,CAAC,IAAI,CAACS,GAAG,IAAIQ,OAAO,CAACE,MAAM,KAAK,CAAC,EAAE;MACrC,OAAO,CAAC,GAAGN,KAAK,CAAC;IACnB;IAEA,MAAMO,WAAW,GAAGJ,SAAS,CAACC,OAAO,EAAE,IAAI,CAACR,GAAG,CAAC;IAEhD,OAAOW,WAAW,IAAIC,YAAY,CAACR,KAAK,EAAEO,WAAW,CAAC;EACxD,CAAC;AACH;;AAEA;AACA,MAAMC,YAAY,GAAGA,CACnBR,KAAwB,EACxBI,OAA0B,KACb;EACb,MAAMK,IAAI,GAAG,CACX,GAAGT,KAAK,CAACU,KAAK,CAAC,CAAC,EAAEnB,oBAAoB,CAAC,EACvCN,SAAS,CAACmB,OAAO,CAACE,MAAM,GAAGb,SAAS,CAAC,EACrCR,SAAS,CAACmB,OAAO,CAACE,MAAM,IAAId,aAAa,CAAC,EAC1C,GAAGY,OAAO,CAACC,GAAG,CAACpB,SAAS,CAAC,CAC1B;EAED,OAAO,CAAC,GAAGwB,IAAI,EAAExB,SAAS,CAACC,aAAa,CAACuB,IAAI,EAAEA,IAAI,CAACH,MAAM,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,SAASZ,WAAW","ignoreList":[]}
|
|
@@ -24,10 +24,10 @@ import { CHECKME_NOTIFY, CHECKME_SERVICE, CHECKME_WRITE } from "../checkme/check
|
|
|
24
24
|
* - **The payload layout.** Every product decodes differently, and a guessed offset yields
|
|
25
25
|
* a plausible wrong reading rather than an error. Declared cases are the caller's.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
27
|
+
* A product whose advertisement offers or requires encryption gets the vendor's handshake on
|
|
28
|
+
* the standard protocol first (`withLepuEncryption`); the rest speak it in cleartext, as the
|
|
29
|
+
* BP2 does in production. The oxygen protocol has no handshake, so its declarations refuse an
|
|
30
|
+
* advertisement that requires one (`rejectEncryptionAtBytes`).
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
/**
|
|
@@ -66,7 +66,6 @@ const viatomBpMonitor = (advertisedName, params) => {
|
|
|
66
66
|
clockSync: "supported",
|
|
67
67
|
clockSyncProtocol: BP3_MODEL_NAMES.includes(advertisedName) ? "bp3" : "bp2",
|
|
68
68
|
fileTransfer: BP3_MODEL_NAMES.includes(advertisedName) ? "bp3" : "bp2",
|
|
69
|
-
rejectEncryptionAtBytes: [4],
|
|
70
69
|
pollCommand: RT_DATA,
|
|
71
70
|
pollIntervalMs: 200,
|
|
72
71
|
minLengthBytes: MIN_LENGTH_BYTES,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["le32FromHex","defineCustomDevice","recordedAtFromLocalSeconds","lepuNameMatch","lepuDevice","createTmbBloodPressureFrameHandler","createViatomFrameHandler","BP2_CASES","BP2_ECG_CASES","BP3_CASES","BP3_ECG_CASES","RT_DATA","CASE_SELECTOR_BYTES","MIN_LENGTH_BYTES","RESULT_CODE_INDEX","DEVICE_TIME_INDEX","rejectFailedResult","reading","frame","resultCode","Number","parseInt","Error","toString","padStart","recordedAt","length","undefined","viatomBpMonitor","advertisedName","params","isBp3","BP3_MODEL_NAMES","includes","hasEcg","id","toLowerCase","replace","nameMatch","clockSync","clockSyncProtocol","fileTransfer","
|
|
1
|
+
{"version":3,"names":["le32FromHex","defineCustomDevice","recordedAtFromLocalSeconds","lepuNameMatch","lepuDevice","createTmbBloodPressureFrameHandler","createViatomFrameHandler","BP2_CASES","BP2_ECG_CASES","BP3_CASES","BP3_ECG_CASES","RT_DATA","CASE_SELECTOR_BYTES","MIN_LENGTH_BYTES","RESULT_CODE_INDEX","DEVICE_TIME_INDEX","rejectFailedResult","reading","frame","resultCode","Number","parseInt","Error","toString","padStart","recordedAt","length","undefined","viatomBpMonitor","advertisedName","params","isBp3","BP3_MODEL_NAMES","includes","hasEcg","id","toLowerCase","replace","nameMatch","clockSync","clockSyncProtocol","fileTransfer","pollCommand","pollIntervalMs","minLengthBytes","caseSelectorBytes","cases","map","each","decorateReading","createFrameHandler","expectedDeviceTypes","bp2aMonitor","bp2tMonitor","bp2wMonitor","bp2vMonitor","lpBp2wMonitor","TMB_SERVICE","TMB_WRITE","TMB_ACK","TMB_NOTIFY","TMB_INDICATE","tmbBpMonitor","stuckDataTimeoutMs","preferredMtu","tmb","serviceUuid","writeUuid","ackUuid","services","uuid","monitor","selector","kind","TMB_MODEL_NAMES"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/viatom/viatom.bp-monitors.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -38,16 +38,22 @@ const RT_DATA = 0x03;
|
|
|
38
38
|
/** The ER3 answers its realtime data on a different opcode from the rest of the range. */
|
|
39
39
|
const ER3_RT_DATA = 0x06;
|
|
40
40
|
const HEART_RATE_UNIT = "bpm";
|
|
41
|
+
|
|
42
|
+
/** The vendor's own client polls realtime at this pace. */
|
|
43
|
+
const POLL_INTERVAL_MS = 500;
|
|
44
|
+
|
|
45
|
+
/** The run status: the current state in the low nibble, the previous one above it. */
|
|
46
|
+
const RUN_STATUS_BYTE = 15;
|
|
47
|
+
const RECORDING = "2";
|
|
41
48
|
/** ER1, ER2 and ER3 share one parameter block: the heart rate opens it. */
|
|
42
49
|
const ER_HEART_RATE_BYTES = [7, 8];
|
|
43
50
|
/**
|
|
44
|
-
* Declares one recorder, reporting the heart rate from its realtime frame.
|
|
51
|
+
* Declares one recorder, reporting the heart rate from its realtime frame while it records.
|
|
45
52
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* status byte, which a declaration cannot select on, so a recorder left connected and unworn
|
|
49
|
-
* reports a decoding failure on each poll. Reading those bits quietly needs a device class.
|
|
53
|
+
* Every other run status - idle, preparing, saving, lead off - leaves the device connected
|
|
54
|
+
* rather than measuring, so an unworn recorder is never shown as taking a reading.
|
|
50
55
|
*/
|
|
56
|
+
const byteHex = value => value.toString(16).padStart(2, "0");
|
|
51
57
|
const declareRecorder = (advertisedName, profile, params) => lepuDevice({
|
|
52
58
|
id: params.id ?? `viatom-${advertisedName.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`,
|
|
53
59
|
nameMatch: params.nameMatch ?? lepuNameMatch(advertisedName),
|
|
@@ -58,10 +64,11 @@ const declareRecorder = (advertisedName, profile, params) => lepuDevice({
|
|
|
58
64
|
emit: "none"
|
|
59
65
|
},
|
|
60
66
|
pollCommand: profile.pollCommand,
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
pollIntervalMs: POLL_INTERVAL_MS,
|
|
68
|
+
minLengthBytes: RUN_STATUS_BYTE + 1,
|
|
69
|
+
caseSelectorBytes: [1, RUN_STATUS_BYTE],
|
|
63
70
|
cases: [{
|
|
64
|
-
selector: profile.pollCommand
|
|
71
|
+
selector: `${byteHex(profile.pollCommand)}?${RECORDING}`,
|
|
65
72
|
kind: "result",
|
|
66
73
|
measurementTypeKey: MeasurementTypeKey.heartRate,
|
|
67
74
|
description: "Realtime parameters and waveform",
|
|
@@ -72,6 +79,10 @@ const declareRecorder = (advertisedName, profile, params) => lepuDevice({
|
|
|
72
79
|
encoding: "uint",
|
|
73
80
|
unit: HEART_RATE_UNIT
|
|
74
81
|
}]
|
|
82
|
+
}, {
|
|
83
|
+
selector: `${byteHex(profile.pollCommand)}??`,
|
|
84
|
+
kind: "idle",
|
|
85
|
+
description: "Realtime frame while not recording"
|
|
75
86
|
}],
|
|
76
87
|
...(params.expectedDeviceTypes ? {
|
|
77
88
|
expectedDeviceTypes: params.expectedDeviceTypes
|
package/lib/module/modules/bt-management/services/devices/viatom/viatom.ecg-recorders.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["MeasurementTypeKey","lepuNameMatch","lepuDevice","RT_DATA","ER3_RT_DATA","HEART_RATE_UNIT","ER_HEART_RATE_BYTES","declareRecorder","advertisedName","profile","params","id","toLowerCase","replace","nameMatch","transport","clockSync","sessionPolicy","minSamples","emit","pollCommand","
|
|
1
|
+
{"version":3,"names":["MeasurementTypeKey","lepuNameMatch","lepuDevice","RT_DATA","ER3_RT_DATA","HEART_RATE_UNIT","POLL_INTERVAL_MS","RUN_STATUS_BYTE","RECORDING","ER_HEART_RATE_BYTES","byteHex","value","toString","padStart","declareRecorder","advertisedName","profile","params","id","toLowerCase","replace","nameMatch","transport","clockSync","sessionPolicy","minSamples","emit","pollCommand","pollIntervalMs","minLengthBytes","caseSelectorBytes","cases","selector","kind","measurementTypeKey","heartRate","description","fields","name","byteIndexes","heartRateBytes","byteOrder","encoding","unit","expectedDeviceTypes","fileTransfer","undefined","DECODED_ECG_MODEL_NAMES","has","ecgFileDecoder","er1Recorder","er2Recorder","er3Recorder","ER1_MODEL_NAMES","ER2_MODEL_NAMES","Set","ER3_MODEL_NAMES"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/viatom/viatom.ecg-recorders.ts"],"mappings":"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","ignoreList":[]}
|
package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ declare class BP2Device extends BTManagedDevice<IntegratedDevices.BP2> {
|
|
|
29
29
|
constructor(device: Device, params: CreateDeviceParams<IntegratedDevices.BP2>);
|
|
30
30
|
protected onStreamStart: () => void;
|
|
31
31
|
protected createCommandSequencer: () => CommandSequencer;
|
|
32
|
+
private readonly lepuSession;
|
|
32
33
|
protected frameReader: BP2FrameReader;
|
|
33
34
|
protected preferredMtu: number;
|
|
34
35
|
protected handleSuccessResult(successResult: MeasurementWithCaseType<MeasurementTypeForDevices<[IntegratedDevices.BP2]>>, collectedValues: string[]): void | boolean;
|
package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bp2.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bp2/bp2.device.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAQ9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAElF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAKvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"bp2.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bp2/bp2.device.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAQ9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAElF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAKvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD;;;GAGG;AACH,4DAA4D;AAC5D,QAAA,MAAM,4BAA4B,WAAW,CAAC;AAW9C,cAAM,SAAU,SAAQ,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC;IAC5D,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,uBAAuB,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyD;IACnF,OAAO,CAAC,cAAc,CAGlB;IACJ,OAAO,CAAC,iBAAiB,CAAqB;IAE9C,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAmB;IACrD,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAS;gBAGzC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,GAAG,CAAC;IAUnD,SAAS,CAAC,aAAa,EAAE,MAAM,IAAI,CAKjC;IAEF,SAAS,CAAC,sBAAsB,QAAO,gBAAgB,CAmCrD;IAEF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,SAAS,CAAC,WAAW,EAAE,cAAc,CAAwC;IAC7E,SAAS,CAAC,YAAY,EAAE,MAAM,CAAiB;IAE/C,SAAS,CAAC,mBAAmB,CAC3B,aAAa,EAAE,uBAAuB,CACpC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CACnD,EACD,eAAe,EAAE,MAAM,EAAE,GACxB,IAAI,GAAG,OAAO;IA0BjB,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,eAAe;IA2CvB,OAAO,CAAC,yBAAyB;IAwBjC,OAAO,CAAC,kBAAkB,CASxB;IAEF,OAAO,CAAC,+BAA+B;IAiDvC,OAAO,CAAC,kBAAkB,CAYxB;IAEF,OAAO,CAAC,YAAY,CAiBF;IAElB,OAAO,CAAC,iBAAiB,CA6CvB;IAEF,OAAO,CAAC,oBAAoB,CAwB1B;IAEF,OAAO,CAAC,kBAAkB,CAIxB;IAEF,OAAO,CAAC,oBAAoB,CAO1B;IAEF,OAAO,CAAC,qBAAqB;CAmD9B;AAED,OAAO,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAAC"}
|
package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.frame-reader.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LepuFrameReader } from "../lepu/lepu.frame-reader";
|
|
2
|
+
import { LepuSession } from "../lepu/lepu.session";
|
|
2
3
|
/**
|
|
3
4
|
* Reads Lepu protocol frames as used by the BP2.
|
|
4
5
|
*
|
|
@@ -6,6 +7,6 @@ import { LepuFrameReader } from "../lepu/lepu.frame-reader";
|
|
|
6
7
|
* thing that makes it a BP2 is which start byte it accepts.
|
|
7
8
|
*/
|
|
8
9
|
export declare class BP2FrameReader extends LepuFrameReader {
|
|
9
|
-
constructor();
|
|
10
|
+
constructor(session?: LepuSession);
|
|
10
11
|
}
|
|
11
12
|
//# sourceMappingURL=bp2.frame-reader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bp2.frame-reader.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bp2/bp2.frame-reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"bp2.frame-reader.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bp2/bp2.frame-reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAKnD;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,eAAe;gBAC9B,OAAO,CAAC,EAAE,WAAW;CAGzC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ClockSyncOptions } from "../../../types/clock-sync";
|
|
2
|
-
import { CommandSequencer } from "../../../types/command-sequencer";
|
|
3
2
|
import { CustomLepuSpec } from "../../../types/custom-lepu-spec";
|
|
4
3
|
import { DeviceData } from "../../../types/device-data";
|
|
5
4
|
import { LepuDeviceInfo } from "../lepu/lepu.device-info";
|
|
5
|
+
import { LepuIdentityGate } from "../lepu/lepu.identity-gate";
|
|
6
6
|
interface IdentityReport {
|
|
7
7
|
onIdentified: (info: LepuDeviceInfo) => void;
|
|
8
8
|
onRefused: (reason: string) => void;
|
|
@@ -26,7 +26,7 @@ declare const recordLepuIdentity: (deviceData: DeviceData, info: LepuDeviceInfo)
|
|
|
26
26
|
* answers on the one it is addressed with, so the list matters for reading and its head for
|
|
27
27
|
* writing.
|
|
28
28
|
*/
|
|
29
|
-
declare const createLepuSequencer: (lepu: CustomLepuSpec, report: IdentityReport, clockSync?: ClockSyncOptions, manufacturerData?: string) =>
|
|
29
|
+
declare const createLepuSequencer: (lepu: CustomLepuSpec, report: IdentityReport, clockSync?: ClockSyncOptions, manufacturerData?: string) => LepuIdentityGate;
|
|
30
30
|
declare const selectLepu: (lepu: CustomLepuSpec, manufacturerData?: string) => CustomLepuSpec;
|
|
31
31
|
export { createLepuSequencer, recordLepuIdentity, selectLepu };
|
|
32
32
|
//# sourceMappingURL=custom-lepu-sequencer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-lepu-sequencer.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/custom/custom-lepu-sequencer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"custom-lepu-sequencer.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/custom/custom-lepu-sequencer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAM9D,UAAU,cAAc;IACtB,YAAY,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED;;;;;;GAMG;AACH,QAAA,MAAM,kBAAkB,GACtB,YAAY,UAAU,EACtB,MAAM,cAAc,KACnB,IAOF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,QAAA,MAAM,mBAAmB,GACvB,MAAM,cAAc,EACpB,QAAQ,cAAc,EACtB,YAAY,gBAAgB,EAC5B,mBAAmB,MAAM,KACxB,gBA6BF,CAAC;AAEF,QAAA,MAAM,UAAU,GACd,MAAM,cAAc,EACpB,mBAAmB,MAAM,KACxB,cAuBF,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,UAAU,EAAE,CAAC"}
|
package/lib/typescript/commonjs/src/modules/bt-management/services/devices/custom/custom.device.d.ts
CHANGED
|
@@ -25,9 +25,11 @@ export declare class CustomDevice extends BTManagedDevice<CustomDeviceId> {
|
|
|
25
25
|
private readonly frameHandler;
|
|
26
26
|
private readonly deliveredFileNames;
|
|
27
27
|
private reportedHistoryIds;
|
|
28
|
+
private recordingEnded;
|
|
28
29
|
private readonly validators;
|
|
29
30
|
private readonly sessionPolicy;
|
|
30
31
|
private readonly sessionAggregates;
|
|
32
|
+
private readonly lepuSession;
|
|
31
33
|
private sessionStartedAt;
|
|
32
34
|
constructor(device: Device, params: CreateDeviceParams<CustomDeviceId>, definition: CustomDeviceDefinition);
|
|
33
35
|
/** Gives a declaration that computes its commands at connect time the context it needs to do so. */
|
|
@@ -42,6 +44,8 @@ export declare class CustomDevice extends BTManagedDevice<CustomDeviceId> {
|
|
|
42
44
|
* gate would poll hardware it had not identified, which is the case the gate exists for.
|
|
43
45
|
*/
|
|
44
46
|
private declareLepuProtocol;
|
|
47
|
+
/** The standard family runs the vendor's encryption handshake first when it advertises one. */
|
|
48
|
+
private withEncryption;
|
|
45
49
|
private reportViatomEcgFile;
|
|
46
50
|
private reportViatomBp2File;
|
|
47
51
|
private reportViatomBp3File;
|
|
@@ -64,6 +68,8 @@ export declare class CustomDevice extends BTManagedDevice<CustomDeviceId> {
|
|
|
64
68
|
*/
|
|
65
69
|
protected handleSuccessResult(successResult: CustomResult, collectedValues: string[]): void | boolean;
|
|
66
70
|
private handleFrame;
|
|
71
|
+
/** True once after a measurement ends, when the device may have stored a new record. */
|
|
72
|
+
private takeRecordingEnded;
|
|
67
73
|
/** Emits a completed session before the state machine returns to CONNECTED. */
|
|
68
74
|
protected handleMeasurementEnd(): void;
|
|
69
75
|
private sessionAverage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/custom/custom.device.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"custom.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/custom/custom.device.ts"],"names":[],"mappings":"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"}
|