@ovok/native 0.4.11 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/LICENSE +667 -8
  2. package/lib/commonjs/modules/bt-management/services/bt-manager.js +13 -15
  3. package/lib/commonjs/modules/bt-management/services/bt-manager.js.map +1 -1
  4. package/lib/commonjs/modules/bt-management/services/device-creator.js +1 -7
  5. package/lib/commonjs/modules/bt-management/services/device-creator.js.map +1 -1
  6. package/lib/commonjs/modules/bt-management/services/devices/bc01/bc01.device.js +51 -113
  7. package/lib/commonjs/modules/bt-management/services/devices/bc01/bc01.device.js.map +1 -1
  8. package/lib/commonjs/modules/bt-management/services/devices/bc01/bc01.main-services.js +77 -41
  9. package/lib/commonjs/modules/bt-management/services/devices/bc01/bc01.main-services.js.map +1 -1
  10. package/lib/commonjs/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.js +12 -24
  11. package/lib/commonjs/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.js.map +1 -1
  12. package/lib/module/modules/bt-management/services/bt-manager.js +13 -15
  13. package/lib/module/modules/bt-management/services/bt-manager.js.map +1 -1
  14. package/lib/module/modules/bt-management/services/device-creator.js +1 -7
  15. package/lib/module/modules/bt-management/services/device-creator.js.map +1 -1
  16. package/lib/module/modules/bt-management/services/devices/bc01/bc01.device.js +51 -113
  17. package/lib/module/modules/bt-management/services/devices/bc01/bc01.device.js.map +1 -1
  18. package/lib/module/modules/bt-management/services/devices/bc01/bc01.main-services.js +77 -41
  19. package/lib/module/modules/bt-management/services/devices/bc01/bc01.main-services.js.map +1 -1
  20. package/lib/module/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.js +12 -24
  21. package/lib/module/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.js.map +1 -1
  22. package/lib/typescript/commonjs/src/modules/bt-management/services/bt-manager.d.ts +1 -0
  23. package/lib/typescript/commonjs/src/modules/bt-management/services/bt-manager.d.ts.map +1 -1
  24. package/lib/typescript/commonjs/src/modules/bt-management/services/device-creator.d.ts.map +1 -1
  25. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bc01/bc01.device.d.ts +13 -33
  26. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bc01/bc01.device.d.ts.map +1 -1
  27. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bc01/bc01.main-services.d.ts +17 -11
  28. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bc01/bc01.main-services.d.ts.map +1 -1
  29. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.d.ts +25 -0
  30. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.d.ts.map +1 -1
  31. package/lib/typescript/module/src/modules/bt-management/services/bt-manager.d.ts +1 -0
  32. package/lib/typescript/module/src/modules/bt-management/services/bt-manager.d.ts.map +1 -1
  33. package/lib/typescript/module/src/modules/bt-management/services/device-creator.d.ts.map +1 -1
  34. package/lib/typescript/module/src/modules/bt-management/services/devices/bc01/bc01.device.d.ts +13 -33
  35. package/lib/typescript/module/src/modules/bt-management/services/devices/bc01/bc01.device.d.ts.map +1 -1
  36. package/lib/typescript/module/src/modules/bt-management/services/devices/bc01/bc01.main-services.d.ts +17 -11
  37. package/lib/typescript/module/src/modules/bt-management/services/devices/bc01/bc01.main-services.d.ts.map +1 -1
  38. package/lib/typescript/module/src/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.d.ts +25 -0
  39. package/lib/typescript/module/src/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.d.ts.map +1 -1
  40. package/package.json +13 -12
  41. package/lib/commonjs/modules/bt-management/services/devices/bc01/bc01-command-sequencer.js +0 -184
  42. package/lib/commonjs/modules/bt-management/services/devices/bc01/bc01-command-sequencer.js.map +0 -1
  43. package/lib/commonjs/modules/bt-management/services/devices/bc01/bc01-frame-parser.js +0 -114
  44. package/lib/commonjs/modules/bt-management/services/devices/bc01/bc01-frame-parser.js.map +0 -1
  45. package/lib/module/modules/bt-management/services/devices/bc01/bc01-command-sequencer.js +0 -180
  46. package/lib/module/modules/bt-management/services/devices/bc01/bc01-command-sequencer.js.map +0 -1
  47. package/lib/module/modules/bt-management/services/devices/bc01/bc01-frame-parser.js +0 -110
  48. package/lib/module/modules/bt-management/services/devices/bc01/bc01-frame-parser.js.map +0 -1
  49. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bc01/bc01-command-sequencer.d.ts +0 -53
  50. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bc01/bc01-command-sequencer.d.ts.map +0 -1
  51. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bc01/bc01-frame-parser.d.ts +0 -53
  52. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bc01/bc01-frame-parser.d.ts.map +0 -1
  53. package/lib/typescript/module/src/modules/bt-management/services/devices/bc01/bc01-command-sequencer.d.ts +0 -53
  54. package/lib/typescript/module/src/modules/bt-management/services/devices/bc01/bc01-command-sequencer.d.ts.map +0 -1
  55. package/lib/typescript/module/src/modules/bt-management/services/devices/bc01/bc01-frame-parser.d.ts +0 -53
  56. package/lib/typescript/module/src/modules/bt-management/services/devices/bc01/bc01-frame-parser.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"device-creator.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/bt-management/services/device-creator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAMrD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6D9D,qBAAa,aAAa,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE;IAKhD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAJhD,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAO;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsC;gBAEvC,mBAAmB,EAAE,CAAC;IAI5C,aAAa,GAAI,WAAW,MAAM,KAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAkBpE;IAEK,YAAY,CAAC,CAAC,SAAS,SAAS,EACrC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC5B,eAAe,CAAC,CAAC,CAAC;IAwCd,OAAO,aAEZ;IAEF;;;OAGG;IACH,OAAO,CAAC,eAAe,CAmBrB;IAEF,OAAO,CAAC,eAAe;CAexB"}
1
+ {"version":3,"file":"device-creator.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/bt-management/services/device-creator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAMrD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6D9D,qBAAa,aAAa,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE;IAKhD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAJhD,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAO;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsC;gBAEvC,mBAAmB,EAAE,CAAC;IAI5C,aAAa,GAAI,WAAW,MAAM,KAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAkBpE;IAEK,YAAY,CAAC,CAAC,SAAS,SAAS,EACrC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC5B,eAAe,CAAC,CAAC,CAAC;IAmCd,OAAO,aAEZ;IAEF;;;OAGG;IACH,OAAO,CAAC,eAAe,CAmBrB;IAEF,OAAO,CAAC,eAAe;CAexB"}
@@ -1,53 +1,33 @@
1
- import { Device } from "react-native-ble-plx";
2
- import { CreateDeviceParams } from "../../../types/create-device-params";
3
- import { DependentResultHandlerParams } from "../../../types/dependent-result-handler-params";
4
1
  import { MeasurementTypeForDevices } from "../../../types/device-measurement-map";
5
2
  import { IntegratedDevices } from "../../../types/integrated-devices";
3
+ import { MeasurementWithCaseType } from "../../../types/measurement-with-case-type";
6
4
  import { IService } from "../../../types/service.type";
7
5
  import { BTManagedDevice } from "../bt-managed-device";
8
6
  /**
9
7
  * Contec BC401 (BC01) urine analyzer driver.
10
8
  *
11
- * The BC401 is a memory device, not a live stream: every measurement the
12
- * patient takes is written to onboard 500-slot flash the moment the strip
13
- * finishes reacting, and the app pulls stored records over BLE only after the
14
- * host walks the reset → version → set-time → count → get-records handshake
15
- * documented in `bc01-command-sequencer.ts`. Every record arrives as one
16
- * 16-byte E1/E2 frame on 0xFF02.
9
+ * The BC401 is a single-shot device: the patient dips a URS-7 strip, presses
10
+ * the button, and the device pushes exactly one result frame on 0xFF01. There
11
+ * is no streaming state, no per-tick updates, and no measurement session to
12
+ * open — the device auto-starts on button press.
17
13
  */
18
14
  export declare class BC01Device extends BTManagedDevice<IntegratedDevices.BC01> {
19
15
  protected onStreamStart: () => void;
20
16
  protected mainServices: IService[];
21
17
  /**
22
18
  * 90 s covers the maximum firmware-side reagent-pad settle time on a URS-7
23
- * strip and leaves headroom for a bulk memory dump of every stored record.
24
- * If the device does not push a frame within that window the data processor
25
- * times out and the driver surfaces "device unreachable".
19
+ * strip. If the device does not push a result frame within that window the
20
+ * data-processor times out and the driver surfaces "device unreachable".
26
21
  */
27
22
  protected stuckDataTimeout: number;
28
- constructor(device: Device, params: CreateDeviceParams<IntegratedDevices.BC01>);
29
- /**
30
- * Returns true once the notification buffer holds a complete BC401 frame,
31
- * classified by its opening opcode. Anything else — a heartbeat opcode we
32
- * do not recognise, or a partial buffer — is held back until enough bytes
33
- * arrive to make sense of it. There is no aa55 header on this hardware.
34
- */
35
23
  protected validatePackage: (pkg: string[]) => boolean;
24
+ protected handleSuccessResult(successResult: MeasurementWithCaseType<MeasurementTypeForDevices<[IntegratedDevices.BC01]>>): void | boolean;
25
+ private handleUrinalysisResult;
36
26
  /**
37
- * The parsing model declares every E1/E2 frame as `DEPENDENT`, so this hook
38
- * runs for each record. We decode the raw bytes here — the packed 3-bits-per
39
- * -pad layout is not expressible in the declaration parser — and report the
40
- * reading directly through `onResult`. The frame is then handed back as
41
- * `OTHER` so the state machine does not report it a second time and does
42
- * not dedupe consecutive records that happen to share the same opcode.
43
- */
44
- protected handleDependentResult: (data: DependentResultHandlerParams<MeasurementTypeForDevices<[IntegratedDevices.BC01]>>) => DependentResultHandlerParams<MeasurementTypeForDevices<[IntegratedDevices.BC01]>>;
45
- /**
46
- * Nothing to do here for the BC401. Every reading arrives through the
47
- * dependent-result path, and the state machine sees only the `OTHER`-typed
48
- * echo we return from `handleDependentResult`.
27
+ * A well-formed frame with all analyte fields still undefined means the
28
+ * device produced an empty read — typically a strip inserted upside down or
29
+ * removed before the reagent-pad timer completed.
49
30
  */
50
- protected handleSuccessResult(): void | boolean;
51
- private reportUrsRecord;
31
+ private checkIfHasError;
52
32
  }
53
33
  //# sourceMappingURL=bc01.device.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bc01.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bc01/bc01.device.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAI9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,gDAAgD,CAAC;AAC9F,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAmBvD;;;;;;;;;GASG;AACH,qBAAa,UAAW,SAAQ,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC;IACrE,SAAS,CAAC,aAAa,EAAE,MAAM,IAAI,CAAY;IAE/C,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAoB;IAEtD;;;;;OAKG;IACH,SAAS,CAAC,gBAAgB,SAAU;gBAExB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,IAAI,CAAC;IAqB9E;;;;;OAKG;IACH,SAAS,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,OAAO,CAanD;IAEF;;;;;;;OAOG;IACH,SAAS,CAAC,qBAAqB,GAC7B,MAAM,4BAA4B,CAChC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CACpD,KACA,4BAA4B,CAC7B,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CACpD,CASC;IAEF;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI,GAAG,OAAO;IAI/C,OAAO,CAAC,eAAe;CAqCxB"}
1
+ {"version":3,"file":"bc01.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bc01/bc01.device.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAIvD;;;;;;;GAOG;AACH,qBAAa,UAAW,SAAQ,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC;IACrE,SAAS,CAAC,aAAa,EAAE,MAAM,IAAI,CAAY;IAE/C,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAoB;IAEtD;;;;OAIG;IACH,SAAS,CAAC,gBAAgB,SAAU;IAEpC,SAAS,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,OAAO,CAgCnD;IAEF,SAAS,CAAC,mBAAmB,CAC3B,aAAa,EAAE,uBAAuB,CACpC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CACpD,GACA,IAAI,GAAG,OAAO;IAkBjB,OAAO,CAAC,sBAAsB;IAc9B;;;;OAIG;IACH,OAAO,CAAC,eAAe;CA2BxB"}
@@ -2,20 +2,26 @@ import { IService } from "../../../types/service.type";
2
2
  /**
3
3
  * Contec BC401 (a.k.a. BC01) urine analyzer — GATT profile.
4
4
  *
5
- * The BC401 uses Contec's proprietary FF12 service, shared across their
6
- * consumer medical devices. Every stored URS-7 measurement is pushed as a
7
- * 16-byte record on 0xFF02 after the host has walked the handshake documented
8
- * in `bc01-command-sequencer.ts`.
5
+ * The BC401 uses Contec's proprietary FF12 service, shared across their consumer
6
+ * medical devices. A single result notification carries a 7-parameter URS-7
7
+ * strip readout expanded into eleven analyte values on the wire.
9
8
  *
10
9
  * Service 0xFF12
11
- * Notify (result) 0xFF02 — CCCD 0x2902 must be written 01 00 to enable
12
- * Write (command) 0xFF01 — RESET / SET_TIME / GET_COUNT / GET_RECORDS
10
+ * Notify (result) 0xFF01 — CCCD 0x2902 must be written 01 00 to enable
11
+ * Write (command) 0xFF02 — RESET / SET_UNIT / REQUEST_HISTORY
13
12
  *
14
- * On the wire a stored URS record opens with 0xE1 (single) or 0xE2 (paginated).
15
- * The remaining fifteen bytes carry the flags nibble, timestamp, seven bytes of
16
- * packed 3-bit analyte indices, and a checksum. `bc01-frame-parser.ts` decodes
17
- * them; this file just declares the GATT surface and hands every E1/E2 frame
18
- * to the driver's dependent-result path so the parser can run.
13
+ * Wire layout of a result frame (Contec URS-7 firmware ≥ 1.2.x):
14
+ * [0..1] header "aa 55" — Contec sentinel
15
+ * [2] length byte after header
16
+ * [3] command "a1" == RESULT_URS7
17
+ * [4] strip type "07" == 7-panel
18
+ * [5..15] values one byte per analyte, encoding the discrete
19
+ * level index into diagnosticResults[key]
20
+ * [16] checksum xor over [2..15]
21
+ *
22
+ * Byte positions calibrated against PHMS 3.0.03 Android app; older firmware
23
+ * (< 1.2.x) uses a different command byte and is not supported by this driver
24
+ * (the validator will reject those frames).
19
25
  */
20
26
  export declare const bc01MainServices: IService[];
21
27
  //# sourceMappingURL=bc01.main-services.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bc01.main-services.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bc01/bc01.main-services.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,EAgDtC,CAAC"}
1
+ {"version":3,"file":"bc01.main-services.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bc01/bc01.main-services.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,EAuFtC,CAAC"}
@@ -1,5 +1,30 @@
1
1
  import { CustomDeviceDefinition } from "../../../types/custom-device-definition";
2
2
  import { StandardDeviceParams } from "./standard-gatt.profile";
3
+ /**
4
+ * Declarations for the Bluetooth SIG vital-signs profiles.
5
+ *
6
+ * These are the profiles a compliant patient device implements, and their layouts come from
7
+ * the public specification rather than from reading a vendor's app, so they can be written
8
+ * down exactly instead of inferred.
9
+ *
10
+ * The advertised name stays the caller's, because the SDK matches a scan result by name and
11
+ * every vendor names its hardware differently. A product declares the profile and supplies
12
+ * the name its own hardware advertises.
13
+ *
14
+ * Values are little-endian, as the specification requires. Only the layouts using each
15
+ * catalog's canonical unit are declared: a device reporting kPa, Fahrenheit or pounds needs
16
+ * a conversion a declaration cannot express, and leaving those flag values undeclared means
17
+ * such a device yields no reading rather than one that is quietly wrong.
18
+ */
19
+ /**
20
+ * Blood Pressure Service 0x1810, Blood Pressure Measurement 0x2A35.
21
+ *
22
+ * The pressures sit at bytes 1-4 whatever the flags say. The pulse rate sits behind two of
23
+ * them: bit 1 puts a seven-byte timestamp in front of it and bit 2 says whether it is there
24
+ * at all, so it is read at byte 7 in one shape and byte 14 in the other, and each shape
25
+ * declares the length it needs. A device that reports no pulse still decodes, because the
26
+ * flags value it sends selects a case that never looks for one.
27
+ */
3
28
  declare const standardBloodPressureDevice: (params: StandardDeviceParams) => CustomDeviceDefinition;
4
29
  /** Health Thermometer Service 0x1809, Temperature Measurement 0x2A1C. */
5
30
  declare const standardThermometerDevice: (params: StandardDeviceParams) => CustomDeviceDefinition;
@@ -1 +1 @@
1
- {"version":3,"file":"standard-gatt.devices.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAEjF,OAAO,EAGL,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AA2CjC,QAAA,MAAM,2BAA2B,GAC/B,QAAQ,oBAAoB,KAC3B,sBAwCC,CAAC;AAEL,yEAAyE;AACzE,QAAA,MAAM,yBAAyB,GAC7B,QAAQ,oBAAoB,KAC3B,sBAUC,CAAC;AAKL;;;;GAIG;AACH,QAAA,MAAM,yBAAyB,GAC7B,QAAQ,oBAAoB,KAC3B,sBAgBC,CAAC;AAEL;;;;;GAKG;AACH,QAAA,MAAM,2BAA2B,GAC/B,QAAQ,oBAAoB,KAC3B,sBAWC,CAAC;AAEL;;;;;;GAMG;AACH,QAAA,MAAM,uBAAuB,GAC3B,QAAQ,oBAAoB,KAC3B,sBAUC,CAAC;AAEL,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,yBAAyB,GAC1B,CAAC"}
1
+ {"version":3,"file":"standard-gatt.devices.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAEjF,OAAO,EAGL,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;;GAQG;AACH,QAAA,MAAM,2BAA2B,GAC/B,QAAQ,oBAAoB,KAC3B,sBA0BC,CAAC;AAEL,yEAAyE;AACzE,QAAA,MAAM,yBAAyB,GAC7B,QAAQ,oBAAoB,KAC3B,sBAUC,CAAC;AAKL;;;;GAIG;AACH,QAAA,MAAM,yBAAyB,GAC7B,QAAQ,oBAAoB,KAC3B,sBAgBC,CAAC;AAEL;;;;;GAKG;AACH,QAAA,MAAM,2BAA2B,GAC/B,QAAQ,oBAAoB,KAC3B,sBAWC,CAAC;AAEL;;;;;;GAMG;AACH,QAAA,MAAM,uBAAuB,GAC3B,QAAQ,oBAAoB,KAC3B,sBAUC,CAAC;AAEL,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,yBAAyB,GAC1B,CAAC"}
@@ -13,6 +13,7 @@ export declare class BTManager<T extends readonly AcceptedDevice[]> {
13
13
  private stateChangeListener;
14
14
  private eventSubscriptions;
15
15
  private deviceCreator;
16
+ private lastScanTimestamp;
16
17
  constructor(bleManager: BleManager, acceptedDevices: T);
17
18
  destroy: () => void;
18
19
  startScan: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"bt-manager.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/bt-management/services/bt-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,UAAU,EAKX,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,qBAAa,SAAS,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE;IAUtD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAVlC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAM;IACzC,OAAO,CAAC,OAAO,CAAsD;IAErE,OAAO,CAAC,mBAAmB,CAA2B;IACtD,OAAO,CAAC,kBAAkB,CAAsB;IAEhD,OAAO,CAAC,aAAa,CAAmB;gBAGrB,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,CAAC;IAK9B,OAAO,aAuBZ;IAEK,SAAS,aAuDd;IAEK,QAAQ,aAmBb;IAEK,aAAa,GAClB,WAAW,CACT,MAAM,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EACvC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAClB,OAAO,CAAC,IAAI,CAAC,UAIlB;IAEK,OAAO,GAAI,WAAW,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,UAGxD;IAEK,qBAAqB,GAC1B,WAAW,CAAC,IAAI,EAAE,0BAA0B,KAAK,IAAI,UAIrD;IAEK,QAAQ,GACb,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,UAIzD;IAGF,OAAO,CAAC,gBAAgB,CAAC,CAAiD;IAC1E,OAAO,CAAC,eAAe,CAAC,CAAgC;IACxD,OAAO,CAAC,qBAAqB,CAAC,CAGX;IACnB,OAAO,CAAC,6BAA6B,CAAC,CAE5B;IAEV,OAAO,CAAC,YAAY,CA+ElB;IAEF,OAAO,CAAC,8BAA8B,CAUpC;CACH"}
1
+ {"version":3,"file":"bt-manager.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/bt-management/services/bt-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,UAAU,EAKX,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,qBAAa,SAAS,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE;IAWtD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAXlC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAM;IACzC,OAAO,CAAC,OAAO,CAAsD;IAErE,OAAO,CAAC,mBAAmB,CAA2B;IACtD,OAAO,CAAC,kBAAkB,CAAsB;IAEhD,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,iBAAiB,CAAa;gBAGnB,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,CAAC;IAK9B,OAAO,aAyBZ;IAEK,SAAS,aA0Dd;IAEK,QAAQ,aAmBb;IAEK,aAAa,GAClB,WAAW,CACT,MAAM,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EACvC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAClB,OAAO,CAAC,IAAI,CAAC,UAIlB;IAEK,OAAO,GAAI,WAAW,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,UAGxD;IAEK,qBAAqB,GAC1B,WAAW,CAAC,IAAI,EAAE,0BAA0B,KAAK,IAAI,UAIrD;IAEK,QAAQ,GACb,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,UAIzD;IAGF,OAAO,CAAC,gBAAgB,CAAC,CAAiD;IAC1E,OAAO,CAAC,eAAe,CAAC,CAAgC;IACxD,OAAO,CAAC,qBAAqB,CAAC,CAGX;IACnB,OAAO,CAAC,6BAA6B,CAAC,CAE5B;IAEV,OAAO,CAAC,YAAY,CAsElB;IAEF,OAAO,CAAC,8BAA8B,CAUpC;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"device-creator.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/bt-management/services/device-creator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAMrD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6D9D,qBAAa,aAAa,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE;IAKhD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAJhD,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAO;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsC;gBAEvC,mBAAmB,EAAE,CAAC;IAI5C,aAAa,GAAI,WAAW,MAAM,KAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAkBpE;IAEK,YAAY,CAAC,CAAC,SAAS,SAAS,EACrC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC5B,eAAe,CAAC,CAAC,CAAC;IAwCd,OAAO,aAEZ;IAEF;;;OAGG;IACH,OAAO,CAAC,eAAe,CAmBrB;IAEF,OAAO,CAAC,eAAe;CAexB"}
1
+ {"version":3,"file":"device-creator.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/bt-management/services/device-creator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAMrD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6D9D,qBAAa,aAAa,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE;IAKhD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAJhD,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAO;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsC;gBAEvC,mBAAmB,EAAE,CAAC;IAI5C,aAAa,GAAI,WAAW,MAAM,KAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAkBpE;IAEK,YAAY,CAAC,CAAC,SAAS,SAAS,EACrC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC5B,eAAe,CAAC,CAAC,CAAC;IAmCd,OAAO,aAEZ;IAEF;;;OAGG;IACH,OAAO,CAAC,eAAe,CAmBrB;IAEF,OAAO,CAAC,eAAe;CAexB"}
@@ -1,53 +1,33 @@
1
- import { Device } from "react-native-ble-plx";
2
- import { CreateDeviceParams } from "../../../types/create-device-params";
3
- import { DependentResultHandlerParams } from "../../../types/dependent-result-handler-params";
4
1
  import { MeasurementTypeForDevices } from "../../../types/device-measurement-map";
5
2
  import { IntegratedDevices } from "../../../types/integrated-devices";
3
+ import { MeasurementWithCaseType } from "../../../types/measurement-with-case-type";
6
4
  import { IService } from "../../../types/service.type";
7
5
  import { BTManagedDevice } from "../bt-managed-device";
8
6
  /**
9
7
  * Contec BC401 (BC01) urine analyzer driver.
10
8
  *
11
- * The BC401 is a memory device, not a live stream: every measurement the
12
- * patient takes is written to onboard 500-slot flash the moment the strip
13
- * finishes reacting, and the app pulls stored records over BLE only after the
14
- * host walks the reset → version → set-time → count → get-records handshake
15
- * documented in `bc01-command-sequencer.ts`. Every record arrives as one
16
- * 16-byte E1/E2 frame on 0xFF02.
9
+ * The BC401 is a single-shot device: the patient dips a URS-7 strip, presses
10
+ * the button, and the device pushes exactly one result frame on 0xFF01. There
11
+ * is no streaming state, no per-tick updates, and no measurement session to
12
+ * open — the device auto-starts on button press.
17
13
  */
18
14
  export declare class BC01Device extends BTManagedDevice<IntegratedDevices.BC01> {
19
15
  protected onStreamStart: () => void;
20
16
  protected mainServices: IService[];
21
17
  /**
22
18
  * 90 s covers the maximum firmware-side reagent-pad settle time on a URS-7
23
- * strip and leaves headroom for a bulk memory dump of every stored record.
24
- * If the device does not push a frame within that window the data processor
25
- * times out and the driver surfaces "device unreachable".
19
+ * strip. If the device does not push a result frame within that window the
20
+ * data-processor times out and the driver surfaces "device unreachable".
26
21
  */
27
22
  protected stuckDataTimeout: number;
28
- constructor(device: Device, params: CreateDeviceParams<IntegratedDevices.BC01>);
29
- /**
30
- * Returns true once the notification buffer holds a complete BC401 frame,
31
- * classified by its opening opcode. Anything else — a heartbeat opcode we
32
- * do not recognise, or a partial buffer — is held back until enough bytes
33
- * arrive to make sense of it. There is no aa55 header on this hardware.
34
- */
35
23
  protected validatePackage: (pkg: string[]) => boolean;
24
+ protected handleSuccessResult(successResult: MeasurementWithCaseType<MeasurementTypeForDevices<[IntegratedDevices.BC01]>>): void | boolean;
25
+ private handleUrinalysisResult;
36
26
  /**
37
- * The parsing model declares every E1/E2 frame as `DEPENDENT`, so this hook
38
- * runs for each record. We decode the raw bytes here — the packed 3-bits-per
39
- * -pad layout is not expressible in the declaration parser — and report the
40
- * reading directly through `onResult`. The frame is then handed back as
41
- * `OTHER` so the state machine does not report it a second time and does
42
- * not dedupe consecutive records that happen to share the same opcode.
43
- */
44
- protected handleDependentResult: (data: DependentResultHandlerParams<MeasurementTypeForDevices<[IntegratedDevices.BC01]>>) => DependentResultHandlerParams<MeasurementTypeForDevices<[IntegratedDevices.BC01]>>;
45
- /**
46
- * Nothing to do here for the BC401. Every reading arrives through the
47
- * dependent-result path, and the state machine sees only the `OTHER`-typed
48
- * echo we return from `handleDependentResult`.
27
+ * A well-formed frame with all analyte fields still undefined means the
28
+ * device produced an empty read — typically a strip inserted upside down or
29
+ * removed before the reagent-pad timer completed.
49
30
  */
50
- protected handleSuccessResult(): void | boolean;
51
- private reportUrsRecord;
31
+ private checkIfHasError;
52
32
  }
53
33
  //# sourceMappingURL=bc01.device.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bc01.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bc01/bc01.device.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAI9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,gDAAgD,CAAC;AAC9F,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAmBvD;;;;;;;;;GASG;AACH,qBAAa,UAAW,SAAQ,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC;IACrE,SAAS,CAAC,aAAa,EAAE,MAAM,IAAI,CAAY;IAE/C,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAoB;IAEtD;;;;;OAKG;IACH,SAAS,CAAC,gBAAgB,SAAU;gBAExB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,IAAI,CAAC;IAqB9E;;;;;OAKG;IACH,SAAS,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,OAAO,CAanD;IAEF;;;;;;;OAOG;IACH,SAAS,CAAC,qBAAqB,GAC7B,MAAM,4BAA4B,CAChC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CACpD,KACA,4BAA4B,CAC7B,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CACpD,CASC;IAEF;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI,GAAG,OAAO;IAI/C,OAAO,CAAC,eAAe;CAqCxB"}
1
+ {"version":3,"file":"bc01.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bc01/bc01.device.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAIvD;;;;;;;GAOG;AACH,qBAAa,UAAW,SAAQ,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC;IACrE,SAAS,CAAC,aAAa,EAAE,MAAM,IAAI,CAAY;IAE/C,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAoB;IAEtD;;;;OAIG;IACH,SAAS,CAAC,gBAAgB,SAAU;IAEpC,SAAS,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,OAAO,CAgCnD;IAEF,SAAS,CAAC,mBAAmB,CAC3B,aAAa,EAAE,uBAAuB,CACpC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CACpD,GACA,IAAI,GAAG,OAAO;IAkBjB,OAAO,CAAC,sBAAsB;IAc9B;;;;OAIG;IACH,OAAO,CAAC,eAAe;CA2BxB"}
@@ -2,20 +2,26 @@ import { IService } from "../../../types/service.type";
2
2
  /**
3
3
  * Contec BC401 (a.k.a. BC01) urine analyzer — GATT profile.
4
4
  *
5
- * The BC401 uses Contec's proprietary FF12 service, shared across their
6
- * consumer medical devices. Every stored URS-7 measurement is pushed as a
7
- * 16-byte record on 0xFF02 after the host has walked the handshake documented
8
- * in `bc01-command-sequencer.ts`.
5
+ * The BC401 uses Contec's proprietary FF12 service, shared across their consumer
6
+ * medical devices. A single result notification carries a 7-parameter URS-7
7
+ * strip readout expanded into eleven analyte values on the wire.
9
8
  *
10
9
  * Service 0xFF12
11
- * Notify (result) 0xFF02 — CCCD 0x2902 must be written 01 00 to enable
12
- * Write (command) 0xFF01 — RESET / SET_TIME / GET_COUNT / GET_RECORDS
10
+ * Notify (result) 0xFF01 — CCCD 0x2902 must be written 01 00 to enable
11
+ * Write (command) 0xFF02 — RESET / SET_UNIT / REQUEST_HISTORY
13
12
  *
14
- * On the wire a stored URS record opens with 0xE1 (single) or 0xE2 (paginated).
15
- * The remaining fifteen bytes carry the flags nibble, timestamp, seven bytes of
16
- * packed 3-bit analyte indices, and a checksum. `bc01-frame-parser.ts` decodes
17
- * them; this file just declares the GATT surface and hands every E1/E2 frame
18
- * to the driver's dependent-result path so the parser can run.
13
+ * Wire layout of a result frame (Contec URS-7 firmware ≥ 1.2.x):
14
+ * [0..1] header "aa 55" — Contec sentinel
15
+ * [2] length byte after header
16
+ * [3] command "a1" == RESULT_URS7
17
+ * [4] strip type "07" == 7-panel
18
+ * [5..15] values one byte per analyte, encoding the discrete
19
+ * level index into diagnosticResults[key]
20
+ * [16] checksum xor over [2..15]
21
+ *
22
+ * Byte positions calibrated against PHMS 3.0.03 Android app; older firmware
23
+ * (< 1.2.x) uses a different command byte and is not supported by this driver
24
+ * (the validator will reject those frames).
19
25
  */
20
26
  export declare const bc01MainServices: IService[];
21
27
  //# sourceMappingURL=bc01.main-services.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bc01.main-services.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bc01/bc01.main-services.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,EAgDtC,CAAC"}
1
+ {"version":3,"file":"bc01.main-services.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bc01/bc01.main-services.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,EAuFtC,CAAC"}
@@ -1,5 +1,30 @@
1
1
  import { CustomDeviceDefinition } from "../../../types/custom-device-definition";
2
2
  import { StandardDeviceParams } from "./standard-gatt.profile";
3
+ /**
4
+ * Declarations for the Bluetooth SIG vital-signs profiles.
5
+ *
6
+ * These are the profiles a compliant patient device implements, and their layouts come from
7
+ * the public specification rather than from reading a vendor's app, so they can be written
8
+ * down exactly instead of inferred.
9
+ *
10
+ * The advertised name stays the caller's, because the SDK matches a scan result by name and
11
+ * every vendor names its hardware differently. A product declares the profile and supplies
12
+ * the name its own hardware advertises.
13
+ *
14
+ * Values are little-endian, as the specification requires. Only the layouts using each
15
+ * catalog's canonical unit are declared: a device reporting kPa, Fahrenheit or pounds needs
16
+ * a conversion a declaration cannot express, and leaving those flag values undeclared means
17
+ * such a device yields no reading rather than one that is quietly wrong.
18
+ */
19
+ /**
20
+ * Blood Pressure Service 0x1810, Blood Pressure Measurement 0x2A35.
21
+ *
22
+ * The pressures sit at bytes 1-4 whatever the flags say. The pulse rate sits behind two of
23
+ * them: bit 1 puts a seven-byte timestamp in front of it and bit 2 says whether it is there
24
+ * at all, so it is read at byte 7 in one shape and byte 14 in the other, and each shape
25
+ * declares the length it needs. A device that reports no pulse still decodes, because the
26
+ * flags value it sends selects a case that never looks for one.
27
+ */
3
28
  declare const standardBloodPressureDevice: (params: StandardDeviceParams) => CustomDeviceDefinition;
4
29
  /** Health Thermometer Service 0x1809, Temperature Measurement 0x2A1C. */
5
30
  declare const standardThermometerDevice: (params: StandardDeviceParams) => CustomDeviceDefinition;
@@ -1 +1 @@
1
- {"version":3,"file":"standard-gatt.devices.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAEjF,OAAO,EAGL,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AA2CjC,QAAA,MAAM,2BAA2B,GAC/B,QAAQ,oBAAoB,KAC3B,sBAwCC,CAAC;AAEL,yEAAyE;AACzE,QAAA,MAAM,yBAAyB,GAC7B,QAAQ,oBAAoB,KAC3B,sBAUC,CAAC;AAKL;;;;GAIG;AACH,QAAA,MAAM,yBAAyB,GAC7B,QAAQ,oBAAoB,KAC3B,sBAgBC,CAAC;AAEL;;;;;GAKG;AACH,QAAA,MAAM,2BAA2B,GAC/B,QAAQ,oBAAoB,KAC3B,sBAWC,CAAC;AAEL;;;;;;GAMG;AACH,QAAA,MAAM,uBAAuB,GAC3B,QAAQ,oBAAoB,KAC3B,sBAUC,CAAC;AAEL,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,yBAAyB,GAC1B,CAAC"}
1
+ {"version":3,"file":"standard-gatt.devices.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/standard-gatt/standard-gatt.devices.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAEjF,OAAO,EAGL,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;;GAQG;AACH,QAAA,MAAM,2BAA2B,GAC/B,QAAQ,oBAAoB,KAC3B,sBA0BC,CAAC;AAEL,yEAAyE;AACzE,QAAA,MAAM,yBAAyB,GAC7B,QAAQ,oBAAoB,KAC3B,sBAUC,CAAC;AAKL;;;;GAIG;AACH,QAAA,MAAM,yBAAyB,GAC7B,QAAQ,oBAAoB,KAC3B,sBAgBC,CAAC;AAEL;;;;;GAKG;AACH,QAAA,MAAM,2BAA2B,GAC/B,QAAQ,oBAAoB,KAC3B,sBAWC,CAAC;AAEL;;;;;;GAMG;AACH,QAAA,MAAM,uBAAuB,GAC3B,QAAQ,oBAAoB,KAC3B,sBAUC,CAAC;AAEL,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,yBAAyB,GAC1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ovok/native",
3
- "version": "0.4.11",
3
+ "version": "1.0.0",
4
4
  "description": "React native component sdk for OVOK",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/commonjs/index.js",
@@ -68,6 +68,7 @@
68
68
  "@medplum/expo-polyfills": "^3.2.23"
69
69
  },
70
70
  "devDependencies": {
71
+ "@babel/core": "^7.29.0",
71
72
  "@commitlint/config-conventional": "^17.0.2",
72
73
  "@eslint/compat": "^1.2.2",
73
74
  "@eslint/js": "^9.13.0",
@@ -80,9 +81,9 @@
80
81
  "@react-native-community/datetimepicker": "^9.1.0",
81
82
  "@react-native-community/netinfo": "^12.0.1",
82
83
  "@react-native-google-signin/google-signin": "^16.1.2",
83
- "@react-native/babel-preset": "^0.85.0",
84
+ "@react-native/babel-preset": "^0.86.0",
84
85
  "@react-native/eslint-config": "^0.73.1",
85
- "@react-native/jest-preset": "^0.85.0",
86
+ "@react-native/jest-preset": "^0.86.0",
86
87
  "@release-it/conventional-changelog": "^5.0.0",
87
88
  "@sentry/react-native": "~7.11.0",
88
89
  "@shopify/flash-list": "2.0.2",
@@ -106,11 +107,11 @@
106
107
  "eslint-plugin-react-hooks": "^5.0.0",
107
108
  "eslint-plugin-testing-library": "^6.4.0",
108
109
  "eslint-plugin-unused-imports": "^4.1.4",
109
- "expo-apple-authentication": "~56.0.4",
110
+ "expo-apple-authentication": "~57.0.2",
110
111
  "expo-health-connect": "^0.1.1",
111
- "expo-image": "~56.0.11",
112
- "expo-linear-gradient": "~56.0.4",
113
- "expo-web-browser": "~56.0.5",
112
+ "expo-image": "~57.0.5",
113
+ "expo-linear-gradient": "~57.0.2",
114
+ "expo-web-browser": "~57.0.3",
114
115
  "formik": "^2.4.9",
115
116
  "globals": "^15.11.0",
116
117
  "i18next": "^26.3.1",
@@ -122,23 +123,23 @@
122
123
  "react": "19.2.3",
123
124
  "react-dom": "19.2.3",
124
125
  "react-i18next": "^17.0.8",
125
- "react-native": "0.85.3",
126
+ "react-native": "0.86.3",
126
127
  "react-native-ble-plx": "^3.5.1",
127
128
  "react-native-blob-util": "^0.24.9",
128
129
  "react-native-builder-bob": "^0.30.2",
129
130
  "react-native-element-dropdown": "^2.12.2",
130
- "react-native-gesture-handler": "~2.31.2",
131
+ "react-native-gesture-handler": "~2.32.0",
131
132
  "react-native-health-connect": "^3.5.3",
132
- "react-native-keyboard-controller": "^1.21.6",
133
+ "react-native-keyboard-controller": "1.21.9",
133
134
  "react-native-modal-datetime-picker": "^18.0.0",
134
135
  "react-native-paper": "^5.13.1",
135
136
  "react-native-pdf": "^6.7.7",
136
137
  "react-native-permissions": "^5.6.0",
137
- "react-native-reanimated": "~4.3.1",
138
+ "react-native-reanimated": "4.5.1",
138
139
  "react-native-render-html": "^6.3.4",
139
140
  "react-native-safe-area-context": "5.7.0",
140
141
  "react-native-svg": "15.15.4",
141
- "react-native-worklets": "0.8.x",
142
+ "react-native-worklets": "0.10.1",
142
143
  "react-test-renderer": "19.2.3",
143
144
  "release-it": "^19.0.6",
144
145
  "socket.io-client": "^4.8.3",
@@ -1,184 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.bc01CommandSequencerInternals = exports.Bc01CommandSequencer = void 0;
7
- var _hexToByte = require("../../../utils/hex-to-byte.js");
8
- /**
9
- * The FF01/FF02 opcodes the BC401 firmware speaks, as reverse-engineered from
10
- * PHMS 3.0.03 (`I1/b.java` for the switch, `B3/B5.java` for the builders and
11
- * checksum, `L1/f.java` for the reset write).
12
- */
13
- const OP_RESET = 0x80;
14
- const OP_REQUEST_VERSION = 0x82;
15
- const OP_SET_TIME = 0x83;
16
- const OP_REQUEST_COUNT = 0x90;
17
- const OP_REQUEST_RECORDS = 0x92;
18
-
19
- /** Payload byte for `OP_REQUEST_RECORDS` that acknowledges the last record of the set. */
20
- const ACK_LAST_OF_SET = 0x7e;
21
-
22
- /** Payload byte for `OP_REQUEST_COUNT` and the initial `OP_REQUEST_RECORDS`. */
23
- const REQUEST_ALL = 0x00;
24
-
25
- /**
26
- * Device-to-host frame prefixes the FSM keys on. Values are decimal opcodes as
27
- * they appear in the decompiled Java (`switch(bArr[0])`), rendered here as
28
- * their real hex opcodes.
29
- */
30
- const RX = {
31
- ACK: 0xf0,
32
- VERSION_REPLY: 0xf2,
33
- TIME_SYNC_ACK: 0xf3,
34
- COUNT_REPLY: 0xe0,
35
- STORED_RECORD_URS: 0xe1,
36
- STORED_RECORD_PAGED: 0xe2,
37
- FINISH: 0xe3
38
- };
39
-
40
- /** Position in a 16-byte URS record where the flags byte sits; bit 0x40 marks the last of a set. */
41
- const RECORD_FLAGS_INDEX = 1;
42
- const RECORD_LAST_OF_SET_BIT = 0x40;
43
- /**
44
- * Formats one byte as a two-digit lowercase hex string, matching the way the
45
- * SDK's transport already spells raw bytes.
46
- */
47
- const asHex = byte => (byte & 0xff).toString(16).padStart(2, "0");
48
-
49
- /**
50
- * BC401 checksum: sum of the low 7 bits of every byte, folded back into 7 bits.
51
- * Matches `B5.a` in the decompiled Java exactly.
52
- */
53
- const bc401Checksum = bytes => bytes.reduce((acc, byte) => acc + (byte & 0x7f), 0) & 0x7f;
54
-
55
- /**
56
- * Builds a "one payload byte plus checksum" command frame. This is the shape
57
- * of every BC401 host-to-device command that carries an argument: opcode,
58
- * argument, checksum-over-both.
59
- */
60
- const buildCommand = (opcode, arg) => {
61
- const chk = bc401Checksum([opcode, arg]);
62
- return [opcode, arg, chk];
63
- };
64
-
65
- /**
66
- * Builds the two-byte reset frame. It is the one command that does not carry
67
- * an argument or a checksum — PHMS writes it as `[0x80, 0x00]` verbatim
68
- * (`L1/f.java:694`).
69
- */
70
- const buildResetCommand = () => [OP_RESET, 0x00];
71
-
72
- /**
73
- * Builds the request-version reply. The Java sends it as `[0x82, 0x02]` where
74
- * `0x02` doubles as the checksum of `0x82` under the BC401 rule
75
- * (`0x82 & 0x7f = 0x02`), so the same formula that guards every other command
76
- * produces the right byte here.
77
- */
78
- const buildRequestVersionCommand = () => {
79
- const chk = bc401Checksum([OP_REQUEST_VERSION]);
80
- return [OP_REQUEST_VERSION, chk];
81
- };
82
-
83
- /**
84
- * Builds the `SET_TIME` frame for the moment the sequencer receives it. The
85
- * device does not run its own clock across power cycles, so timestamps on
86
- * stored records only make sense once the app tells it what "now" is.
87
- * Millisecond field is written little-endian, matching `I1/b.java`.
88
- */
89
- const buildSetTimeCommand = now => {
90
- const yy = now.getFullYear() - 2000;
91
- const mo = now.getMonth() + 1;
92
- const dd = now.getDate();
93
- const hh = now.getHours();
94
- const mi = now.getMinutes();
95
- const ss = now.getSeconds();
96
- const ms = now.getMilliseconds();
97
- const msLo = ms & 0xff;
98
- const msHi = ms >> 8 & 0xff;
99
- const payload = [OP_SET_TIME, yy, mo, dd, hh, mi, ss, msLo, msHi];
100
- const chk = bc401Checksum(payload);
101
- return [...payload, chk];
102
- };
103
-
104
- /**
105
- * Walks the BC401 through its post-reset handshake and pulls every stored
106
- * record.
107
- *
108
- * The device is self-clocking: it answers each command with a single frame,
109
- * and the first byte of that frame names what it is. So the sequencer keeps
110
- * no counter of its own — it looks at the reply, decides what belongs next,
111
- * and returns that. A frame whose opcode is not part of the handshake is left
112
- * unanswered so the driver's stuck-data watchdog surfaces the stall rather
113
- * than the sequencer sending a command the device did not ask for.
114
- *
115
- * `initialCommands()` returns only the reset. The rest of the handshake -
116
- * VERSION, SET_TIME, GET_COUNT, GET_RECORDS - is driven entirely by the
117
- * device's own replies, because sending them any earlier would race the
118
- * firmware boot the reset triggers.
119
- */
120
- // eslint-disable-next-line import/group-exports
121
- class Bc01CommandSequencer {
122
- isDone = false;
123
-
124
- /** Injectable for tests; production reads `Date.now()`. */
125
-
126
- constructor(params, clock = () => new Date()) {
127
- this.params = params;
128
- this.clock = clock;
129
- }
130
- initialCommands = () => [this.commandFor(buildResetCommand())];
131
- nextCommand = frame => {
132
- if (this.isDone || frame.length === 0) {
133
- return undefined;
134
- }
135
- const opcode = (0, _hexToByte.hexToByte)(frame[0] ?? "0");
136
- switch (opcode) {
137
- case RX.ACK:
138
- return [this.commandFor(buildRequestVersionCommand())];
139
- case RX.VERSION_REPLY:
140
- return [this.commandFor(buildSetTimeCommand(this.clock()))];
141
- case RX.TIME_SYNC_ACK:
142
- return [this.commandFor(buildCommand(OP_REQUEST_COUNT, REQUEST_ALL))];
143
- case RX.COUNT_REPLY:
144
- return [this.commandFor(buildCommand(OP_REQUEST_RECORDS, REQUEST_ALL))];
145
- case RX.STORED_RECORD_URS:
146
- case RX.STORED_RECORD_PAGED:
147
- return this.answerStoredRecord(frame);
148
- case RX.FINISH:
149
- this.isDone = true;
150
- return undefined;
151
- default:
152
- return undefined;
153
- }
154
- };
155
-
156
- /**
157
- * The device pages every record it holds, one 16-byte frame at a time. Only
158
- * the frame whose flags byte carries `0x40` needs an acknowledgement; every
159
- * other page is a status update we let ride while the transfer continues.
160
- */
161
- answerStoredRecord = frame => {
162
- const flags = (0, _hexToByte.hexToByte)(frame[RECORD_FLAGS_INDEX] ?? "0");
163
- if ((flags & RECORD_LAST_OF_SET_BIT) === 0) {
164
- return undefined;
165
- }
166
- return [this.commandFor(buildCommand(OP_REQUEST_RECORDS, ACK_LAST_OF_SET))];
167
- };
168
- commandFor = bytes => ({
169
- ...this.params.write,
170
- frame: bytes.map(asHex),
171
- withoutResponse: true
172
- });
173
- }
174
-
175
- // eslint-disable-next-line import/group-exports
176
- exports.Bc01CommandSequencer = Bc01CommandSequencer;
177
- const bc01CommandSequencerInternals = exports.bc01CommandSequencerInternals = {
178
- bc401Checksum,
179
- buildCommand,
180
- buildResetCommand,
181
- buildRequestVersionCommand,
182
- buildSetTimeCommand
183
- };
184
- //# sourceMappingURL=bc01-command-sequencer.js.map