@ceralive/modem-control 1.0.0 → 1.2.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.
- package/README.md +341 -0
- package/dist/backend/at-lease.d.ts +59 -0
- package/dist/backend/at-lease.js +118 -0
- package/dist/backend/cell-info.d.ts +46 -0
- package/dist/backend/cell-info.js +124 -0
- package/dist/backend/constants.d.ts +24 -0
- package/{src/backend/constants.ts → dist/backend/constants.js} +4 -9
- package/dist/backend/device-classifier.d.ts +46 -0
- package/dist/backend/device-classifier.js +258 -0
- package/dist/backend/enrichment.d.ts +28 -0
- package/dist/backend/enrichment.js +59 -0
- package/dist/backend/features.d.ts +61 -0
- package/dist/backend/features.js +109 -0
- package/dist/backend/identity-ladder.d.ts +57 -0
- package/dist/backend/identity-ladder.js +158 -0
- package/dist/backend/identity-registry.d.ts +51 -0
- package/dist/backend/identity-registry.js +101 -0
- package/dist/backend/index.d.ts +30 -0
- package/dist/backend/index.js +35 -0
- package/dist/backend/lifecycle-interlock.d.ts +25 -0
- package/dist/backend/lifecycle-interlock.js +18 -0
- package/dist/backend/managed-objects.d.ts +39 -0
- package/dist/backend/managed-objects.js +82 -0
- package/dist/backend/mapping.d.ts +11 -0
- package/dist/backend/mapping.js +148 -0
- package/dist/backend/mm-backend.d.ts +44 -0
- package/dist/backend/mm-backend.js +154 -0
- package/dist/backend/mm-location.d.ts +21 -0
- package/dist/backend/mm-location.js +237 -0
- package/dist/backend/mm-mutations.d.ts +42 -0
- package/dist/backend/mm-mutations.js +259 -0
- package/dist/backend/modem-actor.d.ts +41 -0
- package/dist/backend/modem-actor.js +78 -0
- package/dist/backend/nm-auto-apn.d.ts +54 -0
- package/dist/backend/nm-auto-apn.js +124 -0
- package/dist/backend/nm-gsm-fields.d.ts +23 -0
- package/dist/backend/nm-gsm-fields.js +107 -0
- package/dist/backend/nmcli-nm-port.d.ts +28 -0
- package/dist/backend/nmcli-nm-port.js +173 -0
- package/dist/backend/nmcli-runner.d.ts +24 -0
- package/dist/backend/nmcli-runner.js +35 -0
- package/dist/backend/observer.d.ts +37 -0
- package/dist/backend/observer.js +219 -0
- package/dist/backend/power-contract.d.ts +49 -0
- package/dist/backend/power-contract.js +34 -0
- package/dist/backend/recovery-attribution.d.ts +32 -0
- package/dist/backend/recovery-attribution.js +57 -0
- package/dist/backend/recovery-budget.d.ts +45 -0
- package/dist/backend/recovery-budget.js +44 -0
- package/dist/backend/recovery-ladder.d.ts +94 -0
- package/dist/backend/recovery-ladder.js +116 -0
- package/dist/backend/router-ethernet.d.ts +19 -0
- package/dist/backend/router-ethernet.js +66 -0
- package/dist/backend/row-store.d.ts +13 -0
- package/dist/backend/row-store.js +82 -0
- package/dist/backend/signal-setup.d.ts +30 -0
- package/dist/backend/signal-setup.js +92 -0
- package/dist/backend/sim-unlock.d.ts +13 -0
- package/dist/backend/sim-unlock.js +153 -0
- package/dist/backend/transition-preconditions.d.ts +101 -0
- package/dist/backend/transition-preconditions.js +132 -0
- package/dist/backend/usage/accounting.d.ts +39 -0
- package/dist/backend/usage/accounting.js +73 -0
- package/dist/backend/usage/billing-cycle.d.ts +11 -0
- package/dist/backend/usage/billing-cycle.js +39 -0
- package/dist/backend/usage/boot-id.d.ts +6 -0
- package/{src/backend/usage/boot-id.ts → dist/backend/usage/boot-id.js} +7 -7
- package/dist/backend/usage/index.d.ts +8 -0
- package/dist/backend/usage/index.js +11 -0
- package/dist/backend/usage/policy-store.d.ts +50 -0
- package/dist/backend/usage/policy-store.js +161 -0
- package/dist/backend/usage/policy-write.d.ts +65 -0
- package/dist/backend/usage/policy-write.js +112 -0
- package/dist/backend/usage/proc-net-dev.d.ts +18 -0
- package/{src/backend/usage/proc-net-dev.ts → dist/backend/usage/proc-net-dev.js} +39 -47
- package/dist/backend/usage/sampler.d.ts +75 -0
- package/dist/backend/usage/sampler.js +211 -0
- package/dist/backend/usage/store.d.ts +38 -0
- package/dist/backend/usage/store.js +126 -0
- package/dist/backend/usb-device-snapshot.d.ts +31 -0
- package/dist/backend/usb-device-snapshot.js +1 -0
- package/dist/backend/usb-enumerator.d.ts +21 -0
- package/dist/backend/usb-enumerator.js +153 -0
- package/dist/backend/usb-mode-transition.d.ts +29 -0
- package/dist/backend/usb-mode-transition.js +216 -0
- package/dist/band/band-names.d.ts +42 -0
- package/dist/band/band-names.js +150 -0
- package/dist/band/certification.d.ts +84 -0
- package/dist/band/certification.js +127 -0
- package/dist/band/certified-bands.json +4 -0
- package/dist/band/index.d.ts +2 -0
- package/dist/band/index.js +8 -0
- package/dist/capability/detect.d.ts +52 -0
- package/dist/capability/detect.js +86 -0
- package/dist/capability/five-g-preference.d.ts +104 -0
- package/dist/capability/five-g-preference.js +171 -0
- package/dist/capability/index.d.ts +3 -0
- package/dist/capability/index.js +10 -0
- package/dist/capability/support-claim.d.ts +39 -0
- package/dist/capability/support-claim.js +81 -0
- package/dist/domain/brand.d.ts +10 -0
- package/dist/domain/brand.js +21 -0
- package/dist/domain/errors.d.ts +32 -0
- package/dist/domain/errors.js +48 -0
- package/dist/domain/generation.d.ts +8 -0
- package/dist/domain/generation.js +12 -0
- package/dist/domain/guards.d.ts +6 -0
- package/dist/domain/guards.js +127 -0
- package/dist/domain/identity.d.ts +109 -0
- package/dist/domain/identity.js +86 -0
- package/dist/domain/index.d.ts +14 -0
- package/dist/domain/index.js +18 -0
- package/dist/domain/mm-enums.d.ts +12 -0
- package/dist/domain/mm-enums.js +139 -0
- package/dist/domain/modem-presentation.d.ts +10 -0
- package/dist/domain/modem-presentation.js +39 -0
- package/dist/domain/observation.d.ts +39 -0
- package/dist/domain/observation.js +4 -0
- package/dist/domain/operation.d.ts +118 -0
- package/dist/domain/operation.js +85 -0
- package/dist/domain/physical-identity.d.ts +43 -0
- package/dist/domain/physical-identity.js +113 -0
- package/{src/domain/policy.ts → dist/domain/policy.d.ts} +34 -69
- package/dist/domain/policy.js +38 -0
- package/dist/domain/shadow-divergence.d.ts +27 -0
- package/dist/domain/shadow-divergence.js +70 -0
- package/dist/domain/snapshot.d.ts +53 -0
- package/dist/domain/snapshot.js +75 -0
- package/{src/domain/state.ts → dist/domain/state.d.ts} +23 -122
- package/dist/domain/state.js +38 -0
- package/dist/fcc/coverage.d.ts +63 -0
- package/dist/fcc/coverage.js +102 -0
- package/dist/fcc/index.d.ts +3 -0
- package/dist/fcc/index.js +12 -0
- package/dist/fcc/policy-store.d.ts +40 -0
- package/dist/fcc/policy-store.js +146 -0
- package/dist/fcc/policy-write.d.ts +32 -0
- package/dist/fcc/policy-write.js +37 -0
- package/dist/hardware/hilink-protocol.d.ts +39 -0
- package/dist/hardware/hilink-protocol.js +58 -0
- package/dist/hardware/index.d.ts +3 -0
- package/dist/hardware/index.js +15 -0
- package/dist/hardware/router-parsers.d.ts +89 -0
- package/dist/hardware/router-parsers.js +234 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +27 -0
- package/dist/journal/codec.d.ts +44 -0
- package/dist/journal/codec.js +198 -0
- package/dist/journal/engine.d.ts +28 -0
- package/dist/journal/engine.js +68 -0
- package/dist/journal/entry.d.ts +74 -0
- package/dist/journal/entry.js +56 -0
- package/dist/journal/index.d.ts +6 -0
- package/dist/journal/index.js +6 -0
- package/dist/journal/legacy-ceraui.d.ts +73 -0
- package/dist/journal/legacy-ceraui.js +227 -0
- package/dist/journal/recovery.d.ts +58 -0
- package/dist/journal/recovery.js +117 -0
- package/dist/journal/store.d.ts +55 -0
- package/dist/journal/store.js +150 -0
- package/dist/location/fix-state.d.ts +53 -0
- package/dist/location/fix-state.js +75 -0
- package/dist/location/index.d.ts +2 -0
- package/dist/location/index.js +8 -0
- package/dist/location/nmea.d.ts +10 -0
- package/dist/location/nmea.js +89 -0
- package/dist/observations/envelope.d.ts +63 -0
- package/dist/observations/envelope.js +77 -0
- package/dist/observations/freshness.d.ts +28 -0
- package/dist/observations/freshness.js +76 -0
- package/dist/observations/index.d.ts +13 -0
- package/dist/observations/index.js +24 -0
- package/dist/observations/metric.d.ts +61 -0
- package/dist/observations/metric.js +73 -0
- package/dist/observations/model.d.ts +80 -0
- package/dist/observations/model.js +11 -0
- package/dist/observations/provenance.d.ts +94 -0
- package/dist/observations/provenance.js +67 -0
- package/dist/observations/raw.d.ts +42 -0
- package/dist/observations/raw.js +146 -0
- package/dist/observations/reading.d.ts +51 -0
- package/dist/observations/reading.js +65 -0
- package/dist/observations/sources/hilink.d.ts +10 -0
- package/dist/observations/sources/hilink.js +84 -0
- package/dist/observations/sources/modemmanager.d.ts +18 -0
- package/dist/observations/sources/modemmanager.js +239 -0
- package/dist/observations/sources/router-shared.d.ts +29 -0
- package/dist/observations/sources/router-shared.js +68 -0
- package/dist/observations/sources/ufi.d.ts +10 -0
- package/dist/observations/sources/ufi.js +111 -0
- package/dist/observations/sources/zte.d.ts +7 -0
- package/dist/observations/sources/zte.js +71 -0
- package/dist/observations/state-separation.d.ts +64 -0
- package/dist/observations/state-separation.js +52 -0
- package/dist/operation-ids.d.ts +2 -0
- package/dist/operation-ids.js +26 -0
- package/dist/operations/contracts.d.ts +72 -0
- package/dist/operations/contracts.js +1 -0
- package/dist/operations/index.d.ts +1 -0
- package/dist/operations/index.js +1 -0
- package/dist/operations/operation-engine.d.ts +16 -0
- package/dist/operations/operation-engine.js +194 -0
- package/dist/ports/index.d.ts +12 -0
- package/{src/ports/index.ts → dist/ports/index.js} +12 -8
- package/dist/ports/location.d.ts +87 -0
- package/dist/ports/location.js +36 -0
- package/dist/ports/modem-manager.d.ts +89 -0
- package/dist/ports/modem-manager.js +9 -0
- package/dist/ports/mutation-admission.d.ts +27 -0
- package/dist/ports/mutation-admission.js +9 -0
- package/dist/ports/network-manager.d.ts +68 -0
- package/dist/ports/network-manager.js +13 -0
- package/{src/ports/observation.ts → dist/ports/observation.d.ts} +16 -27
- package/dist/ports/observation.js +7 -0
- package/dist/ports/ops.d.ts +44 -0
- package/dist/ports/ops.js +16 -0
- package/{src/ports/receipts.ts → dist/ports/receipts.d.ts} +5 -27
- package/dist/ports/receipts.js +9 -0
- package/dist/ports/reconcile.d.ts +33 -0
- package/dist/ports/reconcile.js +200 -0
- package/dist/ports/resource-ownership.d.ts +29 -0
- package/dist/ports/resource-ownership.js +1 -0
- package/dist/ports/router.d.ts +19 -0
- package/dist/ports/router.js +7 -0
- package/dist/ports/sms.d.ts +64 -0
- package/dist/ports/sms.js +24 -0
- package/dist/ports/uhubctl.d.ts +6 -0
- package/dist/ports/uhubctl.js +1 -0
- package/dist/providers/contracts.d.ts +124 -0
- package/dist/providers/contracts.js +10 -0
- package/dist/providers/huawei-hilink/index.d.ts +2 -0
- package/dist/providers/huawei-hilink/index.js +2 -0
- package/dist/providers/huawei-hilink/operations.d.ts +20 -0
- package/dist/providers/huawei-hilink/operations.js +56 -0
- package/dist/providers/huawei-hilink/provider.d.ts +52 -0
- package/dist/providers/huawei-hilink/provider.js +76 -0
- package/dist/providers/huawei-hilink/runtime.d.ts +22 -0
- package/dist/providers/huawei-hilink/runtime.js +171 -0
- package/dist/providers/huawei-hilink/session.d.ts +28 -0
- package/dist/providers/huawei-hilink/session.js +120 -0
- package/dist/providers/huawei-hilink/transport.d.ts +19 -0
- package/dist/providers/huawei-hilink/transport.js +1 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/matcher.d.ts +3 -0
- package/dist/providers/matcher.js +205 -0
- package/dist/providers/modem-manager/errors.d.ts +7 -0
- package/dist/providers/modem-manager/errors.js +37 -0
- package/dist/providers/modem-manager/generic-operations.d.ts +10 -0
- package/dist/providers/modem-manager/generic-operations.js +209 -0
- package/dist/providers/modem-manager/index.d.ts +4 -0
- package/dist/providers/modem-manager/index.js +4 -0
- package/dist/providers/modem-manager/module-operations.d.ts +21 -0
- package/dist/providers/modem-manager/module-operations.js +118 -0
- package/dist/providers/modem-manager/provider.d.ts +41 -0
- package/dist/providers/modem-manager/provider.js +155 -0
- package/dist/providers/modem-manager/runtime-composition-operation.d.ts +32 -0
- package/dist/providers/modem-manager/runtime-composition-operation.js +151 -0
- package/dist/providers/modem-manager/snapshot.d.ts +5 -0
- package/dist/providers/modem-manager/snapshot.js +204 -0
- package/dist/providers/modem-manager/types.d.ts +137 -0
- package/dist/providers/modem-manager/types.js +1 -0
- package/dist/providers/network-manager/adapter.d.ts +71 -0
- package/dist/providers/network-manager/adapter.js +348 -0
- package/dist/providers/network-manager/index.d.ts +2 -0
- package/dist/providers/network-manager/index.js +2 -0
- package/dist/providers/network-manager/types.d.ts +171 -0
- package/dist/providers/network-manager/types.js +77 -0
- package/dist/providers/registry.d.ts +13 -0
- package/dist/providers/registry.js +33 -0
- package/dist/providers/ufi-himi/index.d.ts +6 -0
- package/dist/providers/ufi-himi/index.js +6 -0
- package/dist/providers/ufi-himi/operations.d.ts +41 -0
- package/dist/providers/ufi-himi/operations.js +66 -0
- package/dist/providers/ufi-himi/prohibitions.d.ts +62 -0
- package/dist/providers/ufi-himi/prohibitions.js +88 -0
- package/dist/providers/ufi-himi/provider.d.ts +41 -0
- package/dist/providers/ufi-himi/provider.js +204 -0
- package/dist/providers/ufi-himi/qualcomm-evidence.d.ts +32 -0
- package/dist/providers/ufi-himi/qualcomm-evidence.js +51 -0
- package/dist/providers/ufi-himi/session.d.ts +46 -0
- package/dist/providers/ufi-himi/session.js +92 -0
- package/dist/providers/ufi-himi/transport.d.ts +29 -0
- package/dist/providers/ufi-himi/transport.js +25 -0
- package/dist/providers/zte-goform/index.d.ts +2 -0
- package/dist/providers/zte-goform/index.js +2 -0
- package/dist/providers/zte-goform/provider.d.ts +56 -0
- package/dist/providers/zte-goform/provider.js +101 -0
- package/dist/providers/zte-goform/session.d.ts +23 -0
- package/dist/providers/zte-goform/session.js +197 -0
- package/dist/providers/zte-goform/transport.d.ts +16 -0
- package/dist/providers/zte-goform/transport.js +1 -0
- package/dist/radio/band-truth.d.ts +50 -0
- package/dist/radio/band-truth.js +92 -0
- package/dist/radio/index.d.ts +3 -0
- package/dist/radio/index.js +10 -0
- package/dist/radio/mode-combinations.d.ts +88 -0
- package/dist/radio/mode-combinations.js +198 -0
- package/dist/radio/mode-truth.d.ts +67 -0
- package/dist/radio/mode-truth.js +112 -0
- package/dist/redact.d.ts +15 -0
- package/dist/redact.js +189 -0
- package/dist/safety/composition-root.d.ts +28 -0
- package/dist/safety/composition-root.js +65 -0
- package/dist/safety/flock-resource-ownership.d.ts +11 -0
- package/dist/safety/flock-resource-ownership.js +138 -0
- package/dist/safety/index.d.ts +2 -0
- package/dist/safety/index.js +2 -0
- package/dist/sms/dbus-messaging.d.ts +17 -0
- package/dist/sms/dbus-messaging.js +185 -0
- package/dist/sms/inbox-store.d.ts +10 -0
- package/dist/sms/inbox-store.js +82 -0
- package/dist/sms/index.d.ts +4 -0
- package/dist/sms/index.js +10 -0
- package/dist/sms/mmcli-parse.d.ts +54 -0
- package/dist/sms/mmcli-parse.js +224 -0
- package/dist/sms/normalize.d.ts +42 -0
- package/dist/sms/normalize.js +95 -0
- package/dist/testing/domain-fakes.d.ts +58 -0
- package/dist/testing/domain-fakes.js +98 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +17 -0
- package/dist/testing/provider-fakes.d.ts +45 -0
- package/dist/testing/provider-fakes.js +64 -0
- package/dist/transport/calls.d.ts +9 -0
- package/dist/transport/calls.js +88 -0
- package/dist/transport/codec.d.ts +3 -0
- package/dist/transport/codec.js +207 -0
- package/dist/transport/dbus-native.d.ts +57 -0
- package/dist/transport/dbus-native.js +17 -0
- package/dist/transport/errors.d.ts +21 -0
- package/{src/transport/errors.ts → dist/transport/errors.js} +34 -46
- package/dist/transport/index.d.ts +4 -0
- package/dist/transport/index.js +9 -0
- package/dist/transport/signals.d.ts +15 -0
- package/dist/transport/signals.js +123 -0
- package/dist/transport/signature.d.ts +7 -0
- package/dist/transport/signature.js +94 -0
- package/dist/transport/transport.d.ts +2 -0
- package/dist/transport/transport.js +202 -0
- package/dist/transport/types.d.ts +61 -0
- package/dist/transport/types.js +19 -0
- package/dist/usb-mode/catalog-schema.d.ts +139 -0
- package/dist/usb-mode/catalog-schema.js +97 -0
- package/dist/usb-mode/catalog.d.ts +21 -0
- package/{src/usb-mode/catalog.ts → dist/usb-mode/catalog.js} +10 -32
- package/dist/usb-mode/certified-catalog.json +67 -0
- package/dist/usb-mode/index.d.ts +6 -0
- package/dist/usb-mode/index.js +16 -0
- package/dist/usb-mode/ingestion.d.ts +111 -0
- package/dist/usb-mode/ingestion.js +187 -0
- package/dist/usb-mode/promotion-review.d.ts +21 -0
- package/dist/usb-mode/promotion-review.js +87 -0
- package/dist/usb-mode/runtime-capability.d.ts +59 -0
- package/dist/usb-mode/runtime-capability.js +157 -0
- package/dist/usb-mode/usb-devices-parse.d.ts +36 -0
- package/dist/usb-mode/usb-devices-parse.js +157 -0
- package/dist/ussd/calls.d.ts +32 -0
- package/dist/ussd/calls.js +96 -0
- package/dist/ussd/index.d.ts +5 -0
- package/dist/ussd/index.js +12 -0
- package/dist/ussd/mm-ussd.d.ts +37 -0
- package/dist/ussd/mm-ussd.js +205 -0
- package/dist/ussd/refusal.d.ts +53 -0
- package/dist/ussd/refusal.js +154 -0
- package/dist/ussd/registration.d.ts +20 -0
- package/dist/ussd/registration.js +101 -0
- package/dist/ussd/session.d.ts +106 -0
- package/dist/ussd/session.js +163 -0
- package/package.json +38 -4
- package/src/backend/at-lease.test.ts +0 -106
- package/src/backend/at-lease.ts +0 -158
- package/src/backend/cell-info.test.ts +0 -154
- package/src/backend/cell-info.ts +0 -160
- package/src/backend/device-classifier.test.ts +0 -168
- package/src/backend/device-classifier.ts +0 -248
- package/src/backend/enrichment.ts +0 -96
- package/src/backend/features.test.ts +0 -162
- package/src/backend/features.ts +0 -179
- package/src/backend/identity-ladder.test.ts +0 -117
- package/src/backend/identity-ladder.ts +0 -221
- package/src/backend/identity-registry.test.ts +0 -89
- package/src/backend/identity-registry.ts +0 -151
- package/src/backend/index.ts +0 -236
- package/src/backend/lifecycle-interlock.ts +0 -38
- package/src/backend/managed-objects.ts +0 -108
- package/src/backend/mapping.ts +0 -160
- package/src/backend/mm-backend.ts +0 -191
- package/src/backend/mm-mutations.ts +0 -228
- package/src/backend/modem-actor.test.ts +0 -95
- package/src/backend/modem-actor.ts +0 -112
- package/src/backend/nm-auto-apn.ts +0 -161
- package/src/backend/nm-gsm-fields.ts +0 -122
- package/src/backend/nmcli-nm-port.ts +0 -228
- package/src/backend/nmcli-runner.ts +0 -52
- package/src/backend/observer.ts +0 -297
- package/src/backend/power-contract.test.ts +0 -40
- package/src/backend/power-contract.ts +0 -83
- package/src/backend/recovery-attribution.test.ts +0 -102
- package/src/backend/recovery-attribution.ts +0 -86
- package/src/backend/recovery-budget.test.ts +0 -64
- package/src/backend/recovery-budget.ts +0 -84
- package/src/backend/recovery-ladder.test.ts +0 -257
- package/src/backend/recovery-ladder.ts +0 -249
- package/src/backend/router-ethernet.test.ts +0 -71
- package/src/backend/router-ethernet.ts +0 -90
- package/src/backend/row-store.ts +0 -105
- package/src/backend/signal-setup.ts +0 -112
- package/src/backend/sim-unlock.ts +0 -193
- package/src/backend/transition-preconditions.ts +0 -149
- package/src/backend/uhubctl-power-hook.test.ts +0 -274
- package/src/backend/uhubctl-power-hook.ts +0 -377
- package/src/backend/usage/accounting.test.ts +0 -147
- package/src/backend/usage/accounting.ts +0 -123
- package/src/backend/usage/billing-cycle.test.ts +0 -62
- package/src/backend/usage/billing-cycle.ts +0 -45
- package/src/backend/usage/index.ts +0 -60
- package/src/backend/usage/policy-store.test.ts +0 -164
- package/src/backend/usage/policy-store.ts +0 -216
- package/src/backend/usage/policy-write.test.ts +0 -198
- package/src/backend/usage/policy-write.ts +0 -207
- package/src/backend/usage/proc-net-dev.test.ts +0 -56
- package/src/backend/usage/sampler.test.ts +0 -327
- package/src/backend/usage/sampler.ts +0 -282
- package/src/backend/usage/store.test.ts +0 -148
- package/src/backend/usage/store.ts +0 -177
- package/src/backend/usb-enumerator.test.ts +0 -87
- package/src/backend/usb-enumerator.ts +0 -181
- package/src/backend/usb-mode-transition.test.ts +0 -323
- package/src/backend/usb-mode-transition.ts +0 -253
- package/src/domain/brand.ts +0 -29
- package/src/domain/errors.ts +0 -77
- package/src/domain/guards.test.ts +0 -218
- package/src/domain/guards.ts +0 -144
- package/src/domain/identity.test.ts +0 -83
- package/src/domain/identity.ts +0 -165
- package/src/domain/index.ts +0 -12
- package/src/domain/snapshot.test.ts +0 -266
- package/src/domain/snapshot.ts +0 -120
- package/src/index.test.ts +0 -6
- package/src/index.ts +0 -15
- package/src/ports/README.md +0 -61
- package/src/ports/forbidden-surface.test.ts +0 -241
- package/src/ports/modem-manager.ts +0 -72
- package/src/ports/network-manager.ts +0 -87
- package/src/ports/ops.ts +0 -60
- package/src/ports/ops.type-test.ts +0 -39
- package/src/ports/receipts.test.ts +0 -153
- package/src/ports/reconcile.test.ts +0 -152
- package/src/ports/reconcile.ts +0 -338
- package/src/ports/router.ts +0 -29
- package/src/redact.test.ts +0 -82
- package/src/redact.ts +0 -73
- package/src/transport/README.md +0 -65
- package/src/transport/calls.ts +0 -113
- package/src/transport/characterization.test.ts +0 -260
- package/src/transport/codec.test.ts +0 -118
- package/src/transport/codec.ts +0 -240
- package/src/transport/conformance-python.test.ts +0 -152
- package/src/transport/conformance-same-lib.test.ts +0 -115
- package/src/transport/dbus-native-lib.d.ts +0 -19
- package/src/transport/dbus-native.ts +0 -85
- package/src/transport/index.ts +0 -30
- package/src/transport/no-library-leak.test.ts +0 -61
- package/src/transport/reliability.test.ts +0 -173
- package/src/transport/signals.ts +0 -150
- package/src/transport/signature.ts +0 -110
- package/src/transport/test-support/fake-service.ts +0 -168
- package/src/transport/test-support/independent-producer.py +0 -110
- package/src/transport/test-support/private-bus.ts +0 -66
- package/src/transport/transport.ts +0 -250
- package/src/transport/types.ts +0 -118
- package/src/usb-mode/catalog-schema.test.ts +0 -181
- package/src/usb-mode/catalog-schema.ts +0 -113
- package/src/usb-mode/certified-catalog.json +0 -67
- package/src/usb-mode/index.ts +0 -58
- package/src/usb-mode/ingestion.test.ts +0 -268
- package/src/usb-mode/ingestion.ts +0 -297
- package/src/usb-mode/promotion-review.ts +0 -117
- package/src/usb-mode/usb-devices-parse.ts +0 -196
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Walkers over a DECODED `GetManagedObjects` / `InterfacesAdded` tree.
|
|
2
|
+
//
|
|
3
|
+
// The transport decodes `a{oa{sa{sv}}}` into nested tuple arrays: a dict `a{sv}`
|
|
4
|
+
// becomes `[key, variant][]` and a variant becomes `{ signature, value }`. These
|
|
5
|
+
// accessors navigate that structure by object path and interface name. They live in
|
|
6
|
+
// `src` (not the A2.3 test fake's `tree.ts`) because the observer that ships must not
|
|
7
|
+
// import test-support — the published package would not contain it.
|
|
8
|
+
import { MM_ROOT_PATH, OBJECT_MANAGER_IFACE } from './constants.js';
|
|
9
|
+
/** Treat a `GetManagedObjects` reply body value as the decoded tree. */
|
|
10
|
+
export function asManagedObjects(value) {
|
|
11
|
+
if (!Array.isArray(value)) {
|
|
12
|
+
throw new TypeError('managed-objects payload is not an array');
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
/** Call `ObjectManager.GetManagedObjects` on `destination` and decode the reply. */
|
|
17
|
+
export async function fetchManagedObjects(transport, destination) {
|
|
18
|
+
const reply = await transport.callMethod({
|
|
19
|
+
destination,
|
|
20
|
+
path: MM_ROOT_PATH,
|
|
21
|
+
interface: OBJECT_MANAGER_IFACE,
|
|
22
|
+
member: 'GetManagedObjects',
|
|
23
|
+
});
|
|
24
|
+
return asManagedObjects(reply.body[0]);
|
|
25
|
+
}
|
|
26
|
+
/** Treat an `InterfacesAdded` body (`[path, interfaces]`) as one decoded object. */
|
|
27
|
+
export function asAddedObject(path, interfaces) {
|
|
28
|
+
if (typeof path !== 'string' || !Array.isArray(interfaces)) {
|
|
29
|
+
throw new TypeError('InterfacesAdded body is not [objectPath, interfaces]');
|
|
30
|
+
}
|
|
31
|
+
return [path, interfaces];
|
|
32
|
+
}
|
|
33
|
+
/** Every object path in the tree, in wire order. */
|
|
34
|
+
export function objectPaths(tree) {
|
|
35
|
+
return tree.map(([path]) => path);
|
|
36
|
+
}
|
|
37
|
+
/** The object at `path`, or `undefined`. */
|
|
38
|
+
export function findObject(tree, path) {
|
|
39
|
+
return tree.find(([objectPath]) => objectPath === path);
|
|
40
|
+
}
|
|
41
|
+
/** The property entries of one interface on one object, or `undefined`. */
|
|
42
|
+
export function findInterface(tree, path, iface) {
|
|
43
|
+
return findObject(tree, path)?.[1].find(([name]) => name === iface)?.[1];
|
|
44
|
+
}
|
|
45
|
+
/** Object paths that carry a given interface. */
|
|
46
|
+
export function pathsWithInterface(tree, iface) {
|
|
47
|
+
return tree
|
|
48
|
+
.filter(([, interfaces]) => interfaces.some(([name]) => name === iface))
|
|
49
|
+
.map(([path]) => path);
|
|
50
|
+
}
|
|
51
|
+
/** Whether an object exposes a given interface. */
|
|
52
|
+
export function hasInterface(tree, path, iface) {
|
|
53
|
+
return findInterface(tree, path, iface) !== undefined;
|
|
54
|
+
}
|
|
55
|
+
/** The inner value of a property (a variant's `.value`), or `undefined`. */
|
|
56
|
+
export function propValue(props, name) {
|
|
57
|
+
return props?.find(([key]) => key === name)?.[1]?.value;
|
|
58
|
+
}
|
|
59
|
+
/** A string-typed property, or `undefined` if absent / not a string. */
|
|
60
|
+
export function stringProp(props, name) {
|
|
61
|
+
const value = propValue(props, name);
|
|
62
|
+
return typeof value === 'string' ? value : undefined;
|
|
63
|
+
}
|
|
64
|
+
/** A number-typed property, or `undefined` if absent / not a number. */
|
|
65
|
+
export function numberProp(props, name) {
|
|
66
|
+
const value = propValue(props, name);
|
|
67
|
+
return typeof value === 'number' ? value : undefined;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A string-array (`as`) property, or `undefined` if absent / not an array. An
|
|
71
|
+
* EMPTY array answers `[]` — the device saying "none", a different fact from an
|
|
72
|
+
* absent property. Non-string members are dropped, never coerced.
|
|
73
|
+
*/
|
|
74
|
+
export function stringArrayProp(props, name) {
|
|
75
|
+
const value = propValue(props, name);
|
|
76
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === 'string') : undefined;
|
|
77
|
+
}
|
|
78
|
+
/** Resolve an object-path property (e.g. a modem's `Sim`) to that object's props. */
|
|
79
|
+
export function followObjectPath(tree, props, propName, iface) {
|
|
80
|
+
const target = propValue(props, propName);
|
|
81
|
+
return typeof target === 'string' ? findInterface(tree, target, iface) : undefined;
|
|
82
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type CellularSnapshot } from '../domain/index.js';
|
|
2
|
+
import { type DecodedManagedObjects } from './managed-objects.js';
|
|
3
|
+
/** The dimensions of a mapped modem, WITHOUT a revision (the observer stamps that). */
|
|
4
|
+
export type MappedModem = Omit<CellularSnapshot, 'revision'>;
|
|
5
|
+
/** Map ONE modem object to its dimensions. The modem must expose `Modem`. */
|
|
6
|
+
export declare function mapModem(tree: DecodedManagedObjects, modemPath: string): MappedModem;
|
|
7
|
+
/** Every modem path in the tree (objects exposing the `Modem` interface), in order. */
|
|
8
|
+
export declare function modemPaths(tree: DecodedManagedObjects): string[];
|
|
9
|
+
/** A stable fingerprint of a mapped modem's meaningful dimensions (ignores revision
|
|
10
|
+
* and source health), used to suppress redundant revision bumps on identical reads. */
|
|
11
|
+
export declare function fingerprint(mapped: MappedModem): string;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// Pure mapping: a decoded ModemManager object tree → a `CellularSnapshot`.
|
|
2
|
+
//
|
|
3
|
+
// A3.1 is lifecycle-only. This mapper is DELIBERATELY conservative: it captures
|
|
4
|
+
// identity, presence, source health, radio power, and MM state — the facts the
|
|
5
|
+
// observer needs to order and reconcile modems — but leaves the richer 3GPP
|
|
6
|
+
// registration + access-technology set as `unknown`/empty. Faithful registration and
|
|
7
|
+
// cell-info normalisation are A3.2 (identity ladder) and A3.3 (Signal.Setup / cell
|
|
8
|
+
// info); mapping them here would either be a guess or trip the domain guards. The
|
|
9
|
+
// snapshot this produces is always guard-valid by construction.
|
|
10
|
+
import { imeiEquipmentId, subscriberNumber as makeSubscriberNumber, subscriptionId as makeSubscriptionId, runtimePath, } from '../domain/index.js';
|
|
11
|
+
import { MODEM_IFACE, MODEM3GPP_IFACE, SIM_IFACE } from './constants.js';
|
|
12
|
+
import { findInterface, followObjectPath, numberProp, pathsWithInterface, stringArrayProp, stringProp, } from './managed-objects.js';
|
|
13
|
+
/** MMModemState (`Modem.State`, signed) → the domain `MmState`. */
|
|
14
|
+
function mapMmState(state) {
|
|
15
|
+
switch (state) {
|
|
16
|
+
case -1:
|
|
17
|
+
return 'failed';
|
|
18
|
+
case 1:
|
|
19
|
+
return 'initializing';
|
|
20
|
+
case 2:
|
|
21
|
+
return 'locked';
|
|
22
|
+
case 3:
|
|
23
|
+
return 'disabled';
|
|
24
|
+
case 4:
|
|
25
|
+
return 'disabling';
|
|
26
|
+
case 5:
|
|
27
|
+
return 'enabling';
|
|
28
|
+
case 6:
|
|
29
|
+
return 'enabled';
|
|
30
|
+
case 7:
|
|
31
|
+
return 'searching';
|
|
32
|
+
case 8:
|
|
33
|
+
return 'registered';
|
|
34
|
+
case 9:
|
|
35
|
+
return 'disconnecting';
|
|
36
|
+
case 10:
|
|
37
|
+
return 'connecting';
|
|
38
|
+
case 11:
|
|
39
|
+
return 'connected';
|
|
40
|
+
default:
|
|
41
|
+
return 'unknown';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** MMModemPowerState (`Modem.PowerState`) → the domain `RadioPower`. */
|
|
45
|
+
function mapRadioPower(power) {
|
|
46
|
+
switch (power) {
|
|
47
|
+
case 1:
|
|
48
|
+
return 'off';
|
|
49
|
+
case 2:
|
|
50
|
+
return 'low';
|
|
51
|
+
case 3:
|
|
52
|
+
return 'on';
|
|
53
|
+
default:
|
|
54
|
+
return 'unknown';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Locked / failed modems keep the radio off; every other state we cannot see as
|
|
58
|
+
* off (the guards forbid an active MM state with the radio off), so an unknown
|
|
59
|
+
* power reading is treated as `on` when the modem is clearly on the air. */
|
|
60
|
+
function reconcilePower(power, state) {
|
|
61
|
+
const onTheAir = state === 'enabled' ||
|
|
62
|
+
state === 'searching' ||
|
|
63
|
+
state === 'registered' ||
|
|
64
|
+
state === 'connecting' ||
|
|
65
|
+
state === 'connected' ||
|
|
66
|
+
state === 'disconnecting';
|
|
67
|
+
if (onTheAir && (power === 'unknown' || power === 'off')) {
|
|
68
|
+
return 'on';
|
|
69
|
+
}
|
|
70
|
+
return power;
|
|
71
|
+
}
|
|
72
|
+
/** Read a modem's subscription id (ICCID) from its active SIM object, if any. */
|
|
73
|
+
function readSubscriptionId(tree, modemPath) {
|
|
74
|
+
const modem = findInterface(tree, modemPath, MODEM_IFACE);
|
|
75
|
+
const sim = followObjectPath(tree, modem, 'Sim', SIM_IFACE);
|
|
76
|
+
const iccid = stringProp(sim, 'SimIdentifier');
|
|
77
|
+
return iccid !== undefined && iccid.length > 0 ? makeSubscriptionId(iccid) : undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The SIM's own number(s) from `Modem.OwnNumbers`, or `undefined` when the
|
|
81
|
+
* carrier published none. Most SIMs carry no MSISDN at all, so an absent or
|
|
82
|
+
* empty property is the ordinary case and must read as "not reported" rather
|
|
83
|
+
* than as an empty list an operator could mistake for a failed read.
|
|
84
|
+
*/
|
|
85
|
+
function readOwnNumbers(modem) {
|
|
86
|
+
const raw = stringArrayProp(modem, 'OwnNumbers');
|
|
87
|
+
if (raw === undefined) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const numbers = raw
|
|
91
|
+
.map((value) => value.trim())
|
|
92
|
+
.filter((value) => value.length > 0)
|
|
93
|
+
.map((value) => makeSubscriberNumber(value));
|
|
94
|
+
return numbers.length > 0 ? numbers : undefined;
|
|
95
|
+
}
|
|
96
|
+
/** Map ONE modem object to its dimensions. The modem must expose `Modem`. */
|
|
97
|
+
export function mapModem(tree, modemPath) {
|
|
98
|
+
const modem = findInterface(tree, modemPath, MODEM_IFACE);
|
|
99
|
+
const modem3gpp = findInterface(tree, modemPath, MODEM3GPP_IFACE);
|
|
100
|
+
const equipment = stringProp(modem, 'EquipmentIdentifier') ?? stringProp(modem3gpp, 'Imei') ?? '';
|
|
101
|
+
const mmState = mapMmState(numberProp(modem, 'State'));
|
|
102
|
+
const radioPower = reconcilePower(mapRadioPower(numberProp(modem, 'PowerState')), mmState);
|
|
103
|
+
const sub = readSubscriptionId(tree, modemPath);
|
|
104
|
+
const ownNumbers = readOwnNumbers(modem);
|
|
105
|
+
return {
|
|
106
|
+
identity: {
|
|
107
|
+
equipmentId: imeiEquipmentId(equipment),
|
|
108
|
+
runtimePath: runtimePath(modemPath),
|
|
109
|
+
...(sub !== undefined ? { subscriptionId: sub } : {}),
|
|
110
|
+
...(ownNumbers !== undefined ? { ownNumbers } : {}),
|
|
111
|
+
},
|
|
112
|
+
presence: 'present',
|
|
113
|
+
sourceHealth: 'live',
|
|
114
|
+
simSlots: [],
|
|
115
|
+
radioPower,
|
|
116
|
+
mmState,
|
|
117
|
+
// Conservative: 3GPP registration + RAT set are A3.3's job (see file header).
|
|
118
|
+
registration: { status: 'unknown', activeRats: new Set() },
|
|
119
|
+
nmActivation: 'unavailable',
|
|
120
|
+
dataInterface: { present: false },
|
|
121
|
+
reconcileStatus: 'pending',
|
|
122
|
+
recoveryState: { stage: 'idle', attempts: 0 },
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** Every modem path in the tree (objects exposing the `Modem` interface), in order. */
|
|
126
|
+
export function modemPaths(tree) {
|
|
127
|
+
return pathsWithInterface(tree, MODEM_IFACE);
|
|
128
|
+
}
|
|
129
|
+
/** A stable fingerprint of a mapped modem's meaningful dimensions (ignores revision
|
|
130
|
+
* and source health), used to suppress redundant revision bumps on identical reads. */
|
|
131
|
+
export function fingerprint(mapped) {
|
|
132
|
+
return JSON.stringify({
|
|
133
|
+
id: mapped.identity.equipmentId,
|
|
134
|
+
sub: mapped.identity.subscriptionId ?? null,
|
|
135
|
+
own: mapped.identity.ownNumbers ?? null,
|
|
136
|
+
path: mapped.identity.runtimePath,
|
|
137
|
+
presence: mapped.presence,
|
|
138
|
+
radioPower: mapped.radioPower,
|
|
139
|
+
mmState: mapped.mmState,
|
|
140
|
+
registration: {
|
|
141
|
+
status: mapped.registration.status,
|
|
142
|
+
rats: [...mapped.registration.activeRats].sort(),
|
|
143
|
+
},
|
|
144
|
+
nmActivation: mapped.nmActivation,
|
|
145
|
+
dataInterface: mapped.dataInterface,
|
|
146
|
+
reconcileStatus: mapped.reconcileStatus,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { DesiredRadio } from '../domain/index.js';
|
|
2
|
+
import type { BandReadResult, InhibitLease, ModemManagerPort, ModemRef, NetworkScanResult, ObservationList, ObservationListener, Receipt, SimPukUnlockResult, SimUnlockResult, Unsubscribe } from '../ports/index.js';
|
|
3
|
+
import type { DbusTransport } from '../transport/index.js';
|
|
4
|
+
import { type CellReading } from './cell-info.js';
|
|
5
|
+
import { type ModemEnrichment } from './enrichment.js';
|
|
6
|
+
import { ModemActor, type QuiesceHook } from './modem-actor.js';
|
|
7
|
+
import { type SignalCadence } from './signal-setup.js';
|
|
8
|
+
export interface MmDbusBackendOptions {
|
|
9
|
+
readonly transport: DbusTransport;
|
|
10
|
+
readonly destination?: string;
|
|
11
|
+
readonly actor?: ModemActor;
|
|
12
|
+
/** NM quiesce hook for disruptive mode/slot changes (A3.3 default: no-op). */
|
|
13
|
+
readonly quiesce?: QuiesceHook;
|
|
14
|
+
/** Signal.Setup reporting interval in seconds. */
|
|
15
|
+
readonly signalIntervalSeconds?: number;
|
|
16
|
+
readonly scanTimeoutMs?: number;
|
|
17
|
+
readonly now?: () => number;
|
|
18
|
+
}
|
|
19
|
+
/** The real D-Bus ModemManager backend: observation + mutations + Signal.Setup. */
|
|
20
|
+
export declare class MmDbusBackend implements ModemManagerPort {
|
|
21
|
+
#private;
|
|
22
|
+
constructor(options: MmDbusBackendOptions);
|
|
23
|
+
start(): Promise<ObservationList>;
|
|
24
|
+
observe(listener: ObservationListener): Unsubscribe;
|
|
25
|
+
stop(): Promise<void>;
|
|
26
|
+
setRadioModes(modem: ModemRef, preference: DesiredRadio): Promise<Receipt>;
|
|
27
|
+
setModeCombination(modem: ModemRef, allowed: number, preferred: number): Promise<Receipt>;
|
|
28
|
+
setPrimarySimSlot(modem: ModemRef, slotIndex: number): Promise<Receipt>;
|
|
29
|
+
readBands(modem: ModemRef): Promise<BandReadResult>;
|
|
30
|
+
setCurrentBands(modem: ModemRef, bands: readonly string[]): Promise<Receipt>;
|
|
31
|
+
sendPin(modem: ModemRef, pin: string): Promise<SimUnlockResult>;
|
|
32
|
+
sendPuk(modem: ModemRef, puk: string, newPin: string): Promise<SimPukUnlockResult>;
|
|
33
|
+
scanNetworks(modem: ModemRef): Promise<NetworkScanResult>;
|
|
34
|
+
inhibit(uid: string): Promise<InhibitLease>;
|
|
35
|
+
uninhibit(lease: InhibitLease): Promise<void>;
|
|
36
|
+
/** Whether periodic signal reporting is configured for a modem (Signal.Setup). */
|
|
37
|
+
signalCadence(modem: ModemRef): SignalCadence;
|
|
38
|
+
/** Read the normalized visible-cell list for a modem via `Modem.GetCellInfo`. */
|
|
39
|
+
readCellInfo(modem: ModemRef): Promise<readonly CellReading[]>;
|
|
40
|
+
/** Assemble the full read-only enrichment (revision, eSIM, cadence, cell info). */
|
|
41
|
+
readEnrichment(modem: ModemRef): Promise<ModemEnrichment>;
|
|
42
|
+
}
|
|
43
|
+
/** Construct the real D-Bus ModemManager backend over an A2.4 transport. */
|
|
44
|
+
export declare function createMmDbusBackend(options: MmDbusBackendOptions): MmDbusBackend;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// MmDbusBackend — the real D-Bus `ModemManagerPort`, composed from the A3 parts.
|
|
2
|
+
//
|
|
3
|
+
// It fulfils the whole port: the read side delegates to A3.1's epoch-scoped observer;
|
|
4
|
+
// the mutations run through `MmMutations` (each serialized on the shared per-modem
|
|
5
|
+
// `ModemActor`, keyed on A3.2's STABLE key so serialization survives replug); the
|
|
6
|
+
// Signal.Setup lifecycle is driven off the observer's `onEpochRefresh` hook; and the
|
|
7
|
+
// read-only enrichment (firmware revision, eSIM, signal cadence, normalized cell info)
|
|
8
|
+
// is assembled on demand. One transport is shared by all of them.
|
|
9
|
+
//
|
|
10
|
+
// The `onEpochRefresh` hook is the single integration seam: on every current-epoch
|
|
11
|
+
// authoritative snapshot it (1) rebuilds the live path → stable-key map (so a mutation
|
|
12
|
+
// keys the actor by the durable identity, not the transient path) and (2) re-drives
|
|
13
|
+
// Signal.Setup for that epoch — applying to new modems, re-applying to survivors after
|
|
14
|
+
// an owner change, and never firing for a superseded epoch.
|
|
15
|
+
import { epochMillis } from '../domain/index.js';
|
|
16
|
+
import { normalizeCellInfo } from './cell-info.js';
|
|
17
|
+
import { MM_BUS_NAME, MODEM_IFACE } from './constants.js';
|
|
18
|
+
import { buildEnrichment } from './enrichment.js';
|
|
19
|
+
import { modemIdentityFactsFromTree, resolveModemIdentities } from './identity-ladder.js';
|
|
20
|
+
import { fetchManagedObjects, pathsWithInterface } from './managed-objects.js';
|
|
21
|
+
import { MmMutations } from './mm-mutations.js';
|
|
22
|
+
import { ModemActor } from './modem-actor.js';
|
|
23
|
+
import { createMmDbusObserver } from './observer.js';
|
|
24
|
+
import { SignalSetupManager } from './signal-setup.js';
|
|
25
|
+
/** The real D-Bus ModemManager backend: observation + mutations + Signal.Setup. */
|
|
26
|
+
export class MmDbusBackend {
|
|
27
|
+
#transport;
|
|
28
|
+
#destination;
|
|
29
|
+
#now;
|
|
30
|
+
#observer;
|
|
31
|
+
#mutations;
|
|
32
|
+
#signalSetup;
|
|
33
|
+
// Live modem path → durable stable key; rebuilt on every epoch snapshot.
|
|
34
|
+
#stableKeyByPath = new Map();
|
|
35
|
+
constructor(options) {
|
|
36
|
+
this.#transport = options.transport;
|
|
37
|
+
this.#destination = options.destination ?? MM_BUS_NAME;
|
|
38
|
+
this.#now = options.now ?? Date.now;
|
|
39
|
+
const actor = options.actor ?? new ModemActor(options.quiesce);
|
|
40
|
+
this.#signalSetup = new SignalSetupManager({
|
|
41
|
+
transport: this.#transport,
|
|
42
|
+
destination: this.#destination,
|
|
43
|
+
...(options.signalIntervalSeconds !== undefined
|
|
44
|
+
? { intervalSeconds: options.signalIntervalSeconds }
|
|
45
|
+
: {}),
|
|
46
|
+
});
|
|
47
|
+
this.#observer = createMmDbusObserver({
|
|
48
|
+
transport: this.#transport,
|
|
49
|
+
destination: this.#destination,
|
|
50
|
+
onEpochRefresh: (event) => this.#onEpochRefresh(event),
|
|
51
|
+
});
|
|
52
|
+
this.#mutations = new MmMutations({
|
|
53
|
+
transport: this.#transport,
|
|
54
|
+
actor,
|
|
55
|
+
destination: this.#destination,
|
|
56
|
+
resolveStableKey: (modem) => this.#stableKeyByPath.get(modem) ?? modem,
|
|
57
|
+
...(options.scanTimeoutMs !== undefined ? { scanTimeoutMs: options.scanTimeoutMs } : {}),
|
|
58
|
+
now: this.#now,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
// ── observation (delegated to the A3.1 observer) ────────────────────────────────
|
|
62
|
+
start() {
|
|
63
|
+
return this.#observer.start();
|
|
64
|
+
}
|
|
65
|
+
observe(listener) {
|
|
66
|
+
return this.#observer.observe(listener);
|
|
67
|
+
}
|
|
68
|
+
stop() {
|
|
69
|
+
return this.#observer.stop();
|
|
70
|
+
}
|
|
71
|
+
// ── mutations (serialized per modem through the shared actor) ────────────────────
|
|
72
|
+
setRadioModes(modem, preference) {
|
|
73
|
+
return this.#mutations.setRadioModes(modem, preference);
|
|
74
|
+
}
|
|
75
|
+
setModeCombination(modem, allowed, preferred) {
|
|
76
|
+
return this.#mutations.setModeCombination(modem, allowed, preferred);
|
|
77
|
+
}
|
|
78
|
+
setPrimarySimSlot(modem, slotIndex) {
|
|
79
|
+
return this.#mutations.setPrimarySimSlot(modem, slotIndex);
|
|
80
|
+
}
|
|
81
|
+
readBands(modem) {
|
|
82
|
+
return this.#mutations.readBands(modem);
|
|
83
|
+
}
|
|
84
|
+
setCurrentBands(modem, bands) {
|
|
85
|
+
return this.#mutations.setCurrentBands(modem, bands);
|
|
86
|
+
}
|
|
87
|
+
sendPin(modem, pin) {
|
|
88
|
+
return this.#mutations.sendPin(modem, pin);
|
|
89
|
+
}
|
|
90
|
+
sendPuk(modem, puk, newPin) {
|
|
91
|
+
return this.#mutations.sendPuk(modem, puk, newPin);
|
|
92
|
+
}
|
|
93
|
+
scanNetworks(modem) {
|
|
94
|
+
return this.#mutations.scanNetworks(modem);
|
|
95
|
+
}
|
|
96
|
+
inhibit(uid) {
|
|
97
|
+
return this.#mutations.inhibit(uid);
|
|
98
|
+
}
|
|
99
|
+
uninhibit(lease) {
|
|
100
|
+
return this.#mutations.uninhibit(lease);
|
|
101
|
+
}
|
|
102
|
+
// ── enrichment (additive, read-only, never gating) ──────────────────────────────
|
|
103
|
+
/** Whether periodic signal reporting is configured for a modem (Signal.Setup). */
|
|
104
|
+
signalCadence(modem) {
|
|
105
|
+
return this.#signalSetup.cadenceFor(modem);
|
|
106
|
+
}
|
|
107
|
+
/** Read the normalized visible-cell list for a modem via `Modem.GetCellInfo`. */
|
|
108
|
+
async readCellInfo(modem) {
|
|
109
|
+
const provenance = { source: modem, observedAt: epochMillis(this.#now()) };
|
|
110
|
+
try {
|
|
111
|
+
const reply = await this.#transport.callMethod({
|
|
112
|
+
destination: this.#destination,
|
|
113
|
+
path: modem,
|
|
114
|
+
interface: MODEM_IFACE,
|
|
115
|
+
member: 'GetCellInfo',
|
|
116
|
+
});
|
|
117
|
+
const cells = Array.isArray(reply.body[0])
|
|
118
|
+
? reply.body[0]
|
|
119
|
+
: [];
|
|
120
|
+
return normalizeCellInfo(cells, provenance);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Assemble the full read-only enrichment (revision, eSIM, cadence, cell info). */
|
|
127
|
+
async readEnrichment(modem) {
|
|
128
|
+
const [tree, cellInfo] = await Promise.all([
|
|
129
|
+
fetchManagedObjects(this.#transport, this.#destination),
|
|
130
|
+
this.readCellInfo(modem),
|
|
131
|
+
]);
|
|
132
|
+
return buildEnrichment(tree, modem, this.#signalSetup.cadenceFor(modem), cellInfo);
|
|
133
|
+
}
|
|
134
|
+
#onEpochRefresh(event) {
|
|
135
|
+
this.#refreshStableKeys(event);
|
|
136
|
+
this.#signalSetup.applyForEpoch(event.epoch, event.tree);
|
|
137
|
+
}
|
|
138
|
+
#refreshStableKeys(event) {
|
|
139
|
+
const paths = pathsWithInterface(event.tree, MODEM_IFACE);
|
|
140
|
+
const facts = paths.map((path) => modemIdentityFactsFromTree(event.tree, path));
|
|
141
|
+
const resolved = resolveModemIdentities(facts);
|
|
142
|
+
this.#stableKeyByPath.clear();
|
|
143
|
+
paths.forEach((path, index) => {
|
|
144
|
+
const entry = resolved[index];
|
|
145
|
+
if (entry !== undefined) {
|
|
146
|
+
this.#stableKeyByPath.set(path, entry.stableKey);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** Construct the real D-Bus ModemManager backend over an A2.4 transport. */
|
|
152
|
+
export function createMmDbusBackend(options) {
|
|
153
|
+
return new MmDbusBackend(options);
|
|
154
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FixRead, GnssSource, LocationStatusResult, LocationToggleResult, ModemLocationPort, ModemRef } from '../ports/index.js';
|
|
2
|
+
import type { DbusTransport } from '../transport/index.js';
|
|
3
|
+
import type { ModemActor } from './modem-actor.js';
|
|
4
|
+
/** Decode an MMModemLocationSource bitmask into source names. */
|
|
5
|
+
export declare function decodeLocationSources(mask: number): ReadonlySet<string>;
|
|
6
|
+
export declare function encodeLocationSources(sources: Iterable<string>): number;
|
|
7
|
+
export interface MmLocationDeps {
|
|
8
|
+
readonly transport: DbusTransport;
|
|
9
|
+
readonly actor: ModemActor;
|
|
10
|
+
readonly destination?: string;
|
|
11
|
+
readonly resolveStableKey: (modem: ModemRef) => string;
|
|
12
|
+
readonly now?: () => number;
|
|
13
|
+
}
|
|
14
|
+
export declare class MmLocation implements ModemLocationPort {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(deps: MmLocationDeps);
|
|
17
|
+
getLocationStatus(modem: ModemRef): Promise<LocationStatusResult>;
|
|
18
|
+
enableGnss(modem: ModemRef, sources: readonly GnssSource[]): Promise<LocationToggleResult>;
|
|
19
|
+
disableGnss(modem: ModemRef): Promise<LocationToggleResult>;
|
|
20
|
+
readFix(modem: ModemRef): Promise<FixRead>;
|
|
21
|
+
}
|