@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,109 @@
|
|
|
1
|
+
// ModemManager feature detection — what a given MM daemon can actually do.
|
|
2
|
+
//
|
|
3
|
+
// A3.2 must run against MM 1.20 (the bookworm floor), 1.22, 1.24, and versions
|
|
4
|
+
// nobody has shipped yet. The plan is explicit that this is NOT a version-string
|
|
5
|
+
// whitelist: a version we have never seen must degrade gracefully by PROBING the
|
|
6
|
+
// observed property set, never throw. So detection combines two signals:
|
|
7
|
+
//
|
|
8
|
+
// - the daemon `Version` string (a floor: e.g. eSIM read model is 1.20+), and
|
|
9
|
+
// - the properties actually present on the observed modem (authoritative for
|
|
10
|
+
// `physdev` — the plan requires `physdev` be true ONLY when the `Physdev`
|
|
11
|
+
// property is really there, never merely inferred from a version number).
|
|
12
|
+
//
|
|
13
|
+
// Property facts pinned by the reviewed design (draft §Oracle round-2 #9 / round-4):
|
|
14
|
+
// - `Modem.Device` carries the udev slot UID on ALL versions.
|
|
15
|
+
// - `Modem.Physdev` is the physical topology path, 1.22+ ONLY.
|
|
16
|
+
// - there is NO `PhysdevUid` property anywhere — do not look for one.
|
|
17
|
+
import { MODEM_IFACE, MODEM3GPP_IFACE, SIM_IFACE } from './constants.js';
|
|
18
|
+
import { findInterface, followObjectPath } from './managed-objects.js';
|
|
19
|
+
const VERSION_PATTERN = /^(\d+)\.(\d+)(?:\.\d+)*/;
|
|
20
|
+
/**
|
|
21
|
+
* Parse an MM `Version` string (`1.20.0`, `1.24`, `1.26.0-rc1`, …) to `major.minor`.
|
|
22
|
+
* Returns `null` on anything unparseable — callers must degrade, never throw.
|
|
23
|
+
*/
|
|
24
|
+
export function parseMmVersion(version) {
|
|
25
|
+
const match = VERSION_PATTERN.exec(version.trim());
|
|
26
|
+
if (match === null) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const major = Number(match[1]);
|
|
30
|
+
const minor = Number(match[2]);
|
|
31
|
+
if (!Number.isSafeInteger(major) || !Number.isSafeInteger(minor)) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return { major, minor };
|
|
35
|
+
}
|
|
36
|
+
/** Whether `version` is at least `major.minor` (false when unparseable). */
|
|
37
|
+
function atLeast(version, major, minor) {
|
|
38
|
+
if (version === null) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return version.major > major || (version.major === major && version.minor >= minor);
|
|
42
|
+
}
|
|
43
|
+
/** MM baseline this stack supports — eSIM read model, `GetCellInfo`, Signal.Setup. */
|
|
44
|
+
const MM_MIN = { major: 1, minor: 20 };
|
|
45
|
+
/** Physdev + rich cell-info were co-introduced at 1.22. */
|
|
46
|
+
const MM_RICH = { major: 1, minor: 22 };
|
|
47
|
+
function detectCellInfo(probe, supported, modern, physdev) {
|
|
48
|
+
// Version floor first: below 1.20 there is no GetCellInfo at all.
|
|
49
|
+
if (!supported) {
|
|
50
|
+
return 'none';
|
|
51
|
+
}
|
|
52
|
+
// A modem that explicitly advertises no cell-info capability degrades to none,
|
|
53
|
+
// even on a version that would otherwise support it.
|
|
54
|
+
if (probe.cellInfoAvailable === false) {
|
|
55
|
+
return 'none';
|
|
56
|
+
}
|
|
57
|
+
const fields = probe.cellInfoFields;
|
|
58
|
+
if (fields !== undefined && (fields.has('serving-type') || fields.has('bandwidth'))) {
|
|
59
|
+
return 'rich';
|
|
60
|
+
}
|
|
61
|
+
// 1.22 co-introduced `Physdev` and the rich cell-info fields, so either signal
|
|
62
|
+
// promotes the tier — this is what makes an unseen future version (e.g. 1.26)
|
|
63
|
+
// resolve to `rich` by probing rather than by matching a whitelist.
|
|
64
|
+
if (modern || physdev) {
|
|
65
|
+
return 'rich';
|
|
66
|
+
}
|
|
67
|
+
return 'basic';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Detect what an MM daemon can do from its version string AND the properties
|
|
71
|
+
* observed on a modem. Pure — no I/O, never throws (an unparseable version yields
|
|
72
|
+
* the safe floor: property-probed `physdev`, everything else off).
|
|
73
|
+
*/
|
|
74
|
+
export function detectMmFeatures(version, probe) {
|
|
75
|
+
const parsed = parseMmVersion(version);
|
|
76
|
+
const supported = atLeast(parsed, MM_MIN.major, MM_MIN.minor);
|
|
77
|
+
const modern = atLeast(parsed, MM_RICH.major, MM_RICH.minor);
|
|
78
|
+
// `physdev` is property-authoritative: present iff the `Physdev` property is
|
|
79
|
+
// really in the observed set (never inferred from the version alone).
|
|
80
|
+
const physdev = probe.properties.has('Physdev');
|
|
81
|
+
const esimStatus = probe.properties.has('SimType') || probe.properties.has('EsimStatus') || supported;
|
|
82
|
+
const cellInfo = detectCellInfo(probe, supported, modern, physdev);
|
|
83
|
+
return { physdev, cellInfo, esimStatus, opSerialization: supported };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Build an `MmPropertyProbe` for one modem from a decoded `GetManagedObjects` tree:
|
|
87
|
+
* the union of property names on its `Modem`, `Modem.Modem3gpp`, and active `Sim`
|
|
88
|
+
* interfaces. Cell-info fields are not carried by the static tree, so the returned
|
|
89
|
+
* probe leaves them unset (detection falls back to version + `Physdev`).
|
|
90
|
+
*/
|
|
91
|
+
export function probeModemProperties(tree, modemPath) {
|
|
92
|
+
const modem = findInterface(tree, modemPath, MODEM_IFACE);
|
|
93
|
+
const modem3gpp = findInterface(tree, modemPath, MODEM3GPP_IFACE);
|
|
94
|
+
const sim = followObjectPath(tree, modem, 'Sim', SIM_IFACE);
|
|
95
|
+
const properties = new Set();
|
|
96
|
+
for (const source of [modem, modem3gpp, sim]) {
|
|
97
|
+
if (source === undefined) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
for (const [name] of source) {
|
|
101
|
+
properties.add(name);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return { properties };
|
|
105
|
+
}
|
|
106
|
+
/** Convenience: detect features straight off a decoded tree for one modem. */
|
|
107
|
+
export function detectModemFeatures(version, tree, modemPath) {
|
|
108
|
+
return detectMmFeatures(version, probeModemProperties(tree, modemPath));
|
|
109
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type EquipmentId, type IdentityConfidence, type ModemIdentity } from '../domain/index.js';
|
|
2
|
+
import { type DecodedManagedObjects } from './managed-objects.js';
|
|
3
|
+
/** Which rung of the ladder produced the stable key. */
|
|
4
|
+
export type SlotSource = 'device-slot-uid' | 'physdev' | 'sysfs-walk' | 'equipment-fallback';
|
|
5
|
+
/** The prefix OUR udev rules use to label a slot in `Modem.Device`. */
|
|
6
|
+
export declare const SLOT_UID_PREFIX = "slot-";
|
|
7
|
+
/** The raw facts the ladder resolves from — one modem's observed identity inputs. */
|
|
8
|
+
export interface ModemIdentityFacts {
|
|
9
|
+
/** The live MM object path (becomes `runtimePath`; never a durable key). */
|
|
10
|
+
readonly runtimePath: string;
|
|
11
|
+
/** `Modem.Device` — a `slot-*` UID (ours) or MM's path-shaped default. */
|
|
12
|
+
readonly device?: string;
|
|
13
|
+
/** `Modem.Physdev` — physical topology path (1.22+; absent on 1.20). */
|
|
14
|
+
readonly physdev?: string;
|
|
15
|
+
/** The modem's port device names (e.g. `ttyUSB0`, `wwan0`) for the sysfs walk. */
|
|
16
|
+
readonly ports?: readonly string[];
|
|
17
|
+
/** IMEI/serial equipment id with its own confidence (A2.1). */
|
|
18
|
+
readonly equipmentId: EquipmentId;
|
|
19
|
+
}
|
|
20
|
+
/** The ladder's output: a resolved identity plus how (and how firmly) we got it. */
|
|
21
|
+
export interface ResolvedIdentity {
|
|
22
|
+
/** The four-part identity; `logicalSlotId` is set for rungs 1-3 only. */
|
|
23
|
+
readonly identity: ModemIdentity;
|
|
24
|
+
/** Which rung produced the result. */
|
|
25
|
+
readonly slotSource: SlotSource;
|
|
26
|
+
/** Confidence in the SLOT resolution (rung 4 is always `low`). */
|
|
27
|
+
readonly confidence: IdentityConfidence;
|
|
28
|
+
/** The durable row key — stable across replug for rungs 1-3 (and unique-IMEI rung 4). */
|
|
29
|
+
readonly stableKey: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Whether a `Modem.Device` value is one of OUR slot UIDs (shaped `slot-*`) rather
|
|
33
|
+
* than MM's path-shaped default. This is the documented Phase-A heuristic that
|
|
34
|
+
* keeps a hand-labelled slot preferred over a `/sys/devices/...` path.
|
|
35
|
+
*/
|
|
36
|
+
export declare function looksLikeSlotUid(device: string | undefined): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve ONE modem's stable identity by walking the ladder. Pure — no I/O.
|
|
39
|
+
*
|
|
40
|
+
* Rungs 1-3 yield a `logicalSlotId` and a stable key that survives replug into the
|
|
41
|
+
* same slot. Rung 4 (equipment fallback) yields NO slot and `confidence: 'low'`,
|
|
42
|
+
* so a durable policy bound via `policyBindingKey` is refused for an ambiguous
|
|
43
|
+
* (duplicate/zero) equipment id.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveModemIdentity(facts: ModemIdentityFacts): ResolvedIdentity;
|
|
46
|
+
/**
|
|
47
|
+
* Resolve a batch of modems, demoting any equipment id that appears on more than
|
|
48
|
+
* one modem to LOW confidence FIRST (cross-modem duplicate detection A2.1 cannot do
|
|
49
|
+
* from a single value). A duplicate IMEI thus reaches rung 4 with a low-confidence
|
|
50
|
+
* equipment id, and `canBindPolicy` refuses durable binding on it.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveModemIdentities(factsList: readonly ModemIdentityFacts[]): ResolvedIdentity[];
|
|
53
|
+
/**
|
|
54
|
+
* Extract one modem's `ModemIdentityFacts` from a decoded `GetManagedObjects` tree —
|
|
55
|
+
* the bridge real backends use to feed the ladder from an observed snapshot.
|
|
56
|
+
*/
|
|
57
|
+
export declare function modemIdentityFactsFromTree(tree: DecodedManagedObjects, modemPath: string): ModemIdentityFacts;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// The identity ladder — resolving a STABLE slot handle for a live modem.
|
|
2
|
+
//
|
|
3
|
+
// A modem's D-Bus object path (`/org/freedesktop/ModemManager1/Modem/3`) is a
|
|
4
|
+
// per-boot, per-plug value: it changes on replug and daemon restart, so it can
|
|
5
|
+
// never be the durable key. The ladder derives a stable key by trying, in order:
|
|
6
|
+
//
|
|
7
|
+
// 1. slot-UID in `Modem.Device` — when OUR udev rules label the slot they set
|
|
8
|
+
// `Device` to a `slot-*` UID (e.g. `slot-usb2-1`). That is stable and ours,
|
|
9
|
+
// distinguishable from MM's own path-shaped default (`/sys/devices/...`).
|
|
10
|
+
// 2. `Modem.Physdev` (1.22+) — the physical USB topology path. Stable across
|
|
11
|
+
// replug into the same port; used when no slot-UID is present.
|
|
12
|
+
// 3. a ports-derived sysfs walk — a deterministic key from the modem's port
|
|
13
|
+
// list when neither of the above is available (MM 1.20, no udev rule yet).
|
|
14
|
+
// 4. equipment-id fallback — LOW confidence. Per A2.1's ambiguity rules a
|
|
15
|
+
// low-confidence identity must never bind durable policy, so this rung sets
|
|
16
|
+
// `confidence: 'low'` and `canBindPolicy` refuses on an ambiguous equipment id.
|
|
17
|
+
//
|
|
18
|
+
// Phase A note: no image-pipeline udev rules ship yet, so on the bench `Device`
|
|
19
|
+
// is usually MM's path-shaped default and the ladder lands on Physdev / sysfs.
|
|
20
|
+
// The `slot-*` heuristic is documented here so a bench operator can label a slot
|
|
21
|
+
// by hand and see rung 1 fire.
|
|
22
|
+
import { demoteToLowConfidence, imeiEquipmentId, logicalSlotId, runtimePath, } from '../domain/index.js';
|
|
23
|
+
import { MODEM_IFACE, MODEM3GPP_IFACE } from './constants.js';
|
|
24
|
+
import { findInterface, propValue, stringProp, } from './managed-objects.js';
|
|
25
|
+
/** The prefix OUR udev rules use to label a slot in `Modem.Device`. */
|
|
26
|
+
export const SLOT_UID_PREFIX = 'slot-';
|
|
27
|
+
/**
|
|
28
|
+
* Whether a `Modem.Device` value is one of OUR slot UIDs (shaped `slot-*`) rather
|
|
29
|
+
* than MM's path-shaped default. This is the documented Phase-A heuristic that
|
|
30
|
+
* keeps a hand-labelled slot preferred over a `/sys/devices/...` path.
|
|
31
|
+
*/
|
|
32
|
+
export function looksLikeSlotUid(device) {
|
|
33
|
+
if (device === undefined) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return device.startsWith(SLOT_UID_PREFIX) && device.length > SLOT_UID_PREFIX.length;
|
|
37
|
+
}
|
|
38
|
+
/** Derive a deterministic key from a modem's port list (sorted, stable across replug). */
|
|
39
|
+
function sysfsWalkKey(ports) {
|
|
40
|
+
const named = ports.map((p) => p.trim()).filter((p) => p.length > 0);
|
|
41
|
+
if (named.length === 0) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
return [...named].sort().join('+');
|
|
45
|
+
}
|
|
46
|
+
function buildIdentity(facts, slot) {
|
|
47
|
+
return {
|
|
48
|
+
equipmentId: facts.equipmentId,
|
|
49
|
+
runtimePath: runtimePath(facts.runtimePath),
|
|
50
|
+
...(slot !== undefined ? { logicalSlotId: slot } : {}),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Resolve ONE modem's stable identity by walking the ladder. Pure — no I/O.
|
|
55
|
+
*
|
|
56
|
+
* Rungs 1-3 yield a `logicalSlotId` and a stable key that survives replug into the
|
|
57
|
+
* same slot. Rung 4 (equipment fallback) yields NO slot and `confidence: 'low'`,
|
|
58
|
+
* so a durable policy bound via `policyBindingKey` is refused for an ambiguous
|
|
59
|
+
* (duplicate/zero) equipment id.
|
|
60
|
+
*/
|
|
61
|
+
export function resolveModemIdentity(facts) {
|
|
62
|
+
// Rung 1 — our slot-UID in `Device`.
|
|
63
|
+
if (looksLikeSlotUid(facts.device)) {
|
|
64
|
+
const device = facts.device;
|
|
65
|
+
const slot = logicalSlotId(device);
|
|
66
|
+
return {
|
|
67
|
+
identity: buildIdentity(facts, slot),
|
|
68
|
+
slotSource: 'device-slot-uid',
|
|
69
|
+
confidence: 'high',
|
|
70
|
+
stableKey: `slot:${device}`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// Rung 2 — `Physdev` physical topology path (1.22+).
|
|
74
|
+
const physdev = facts.physdev?.trim();
|
|
75
|
+
if (physdev !== undefined && physdev.length > 0) {
|
|
76
|
+
const slot = logicalSlotId(`physdev:${physdev}`);
|
|
77
|
+
return {
|
|
78
|
+
identity: buildIdentity(facts, slot),
|
|
79
|
+
slotSource: 'physdev',
|
|
80
|
+
confidence: 'high',
|
|
81
|
+
stableKey: `physdev:${physdev}`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// Rung 3 — ports-derived sysfs walk.
|
|
85
|
+
const walk = facts.ports !== undefined ? sysfsWalkKey(facts.ports) : undefined;
|
|
86
|
+
if (walk !== undefined) {
|
|
87
|
+
const slot = logicalSlotId(`sysfs:${walk}`);
|
|
88
|
+
return {
|
|
89
|
+
identity: buildIdentity(facts, slot),
|
|
90
|
+
slotSource: 'sysfs-walk',
|
|
91
|
+
confidence: 'medium',
|
|
92
|
+
stableKey: `sysfs:${walk}`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// Rung 4 — equipment fallback, LOW confidence, no durable slot.
|
|
96
|
+
const equip = facts.equipmentId;
|
|
97
|
+
const stableKey = equip.provenance !== 'none' && equip.value.trim().length > 0
|
|
98
|
+
? `equip:${equip.value}`
|
|
99
|
+
: `path:${facts.runtimePath}`;
|
|
100
|
+
return {
|
|
101
|
+
identity: buildIdentity(facts, undefined),
|
|
102
|
+
slotSource: 'equipment-fallback',
|
|
103
|
+
confidence: 'low',
|
|
104
|
+
stableKey,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Resolve a batch of modems, demoting any equipment id that appears on more than
|
|
109
|
+
* one modem to LOW confidence FIRST (cross-modem duplicate detection A2.1 cannot do
|
|
110
|
+
* from a single value). A duplicate IMEI thus reaches rung 4 with a low-confidence
|
|
111
|
+
* equipment id, and `canBindPolicy` refuses durable binding on it.
|
|
112
|
+
*/
|
|
113
|
+
export function resolveModemIdentities(factsList) {
|
|
114
|
+
const counts = new Map();
|
|
115
|
+
for (const facts of factsList) {
|
|
116
|
+
const { equipmentId } = facts;
|
|
117
|
+
if (equipmentId.provenance !== 'none' && equipmentId.value.trim().length > 0) {
|
|
118
|
+
counts.set(equipmentId.value, (counts.get(equipmentId.value) ?? 0) + 1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return factsList.map((facts) => {
|
|
122
|
+
const { equipmentId } = facts;
|
|
123
|
+
const duplicated = equipmentId.provenance !== 'none' && (counts.get(equipmentId.value) ?? 0) > 1;
|
|
124
|
+
const resolvedFacts = duplicated
|
|
125
|
+
? { ...facts, equipmentId: demoteToLowConfidence(equipmentId) }
|
|
126
|
+
: facts;
|
|
127
|
+
return resolveModemIdentity(resolvedFacts);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/** MM `Modem.Ports` is `a(su)`: entries of `[portName, portType]`. */
|
|
131
|
+
function portNames(value) {
|
|
132
|
+
if (!Array.isArray(value)) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
const names = value
|
|
136
|
+
.map((entry) => (Array.isArray(entry) ? entry[0] : undefined))
|
|
137
|
+
.filter((name) => typeof name === 'string');
|
|
138
|
+
return names.length > 0 ? names : undefined;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Extract one modem's `ModemIdentityFacts` from a decoded `GetManagedObjects` tree —
|
|
142
|
+
* the bridge real backends use to feed the ladder from an observed snapshot.
|
|
143
|
+
*/
|
|
144
|
+
export function modemIdentityFactsFromTree(tree, modemPath) {
|
|
145
|
+
const modem = findInterface(tree, modemPath, MODEM_IFACE);
|
|
146
|
+
const modem3gpp = findInterface(tree, modemPath, MODEM3GPP_IFACE);
|
|
147
|
+
const equipment = stringProp(modem, 'EquipmentIdentifier') ?? stringProp(modem3gpp, 'Imei') ?? '';
|
|
148
|
+
const device = stringProp(modem, 'Device');
|
|
149
|
+
const physdev = stringProp(modem, 'Physdev');
|
|
150
|
+
const ports = portNames(propValue(modem, 'Ports'));
|
|
151
|
+
return {
|
|
152
|
+
runtimePath: modemPath,
|
|
153
|
+
equipmentId: imeiEquipmentId(equipment),
|
|
154
|
+
...(device !== undefined ? { device } : {}),
|
|
155
|
+
...(physdev !== undefined ? { physdev } : {}),
|
|
156
|
+
...(ports !== undefined ? { ports } : {}),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { EquipmentId, LogicalSlotId, RuntimePath } from '../domain/index.js';
|
|
2
|
+
import type { ResolvedIdentity } from './identity-ladder.js';
|
|
3
|
+
/** One durable logical row, keyed by the ladder's stable identifier. */
|
|
4
|
+
export interface IdentityRow {
|
|
5
|
+
/** The stable durable key (`slot:…` / `physdev:…` / `sysfs:…` / `equip:…`). */
|
|
6
|
+
readonly stableKey: string;
|
|
7
|
+
/** The resolved slot, when the row was slot-resolved (rungs 1-3). */
|
|
8
|
+
readonly logicalSlotId?: LogicalSlotId;
|
|
9
|
+
/** The equipment currently occupying this slot. */
|
|
10
|
+
readonly equipmentId: EquipmentId;
|
|
11
|
+
/** The live MM path — updated on every replug (never a durable key). */
|
|
12
|
+
readonly runtimePath: RuntimePath;
|
|
13
|
+
}
|
|
14
|
+
/** A transition the registry detected while applying a resolved identity. */
|
|
15
|
+
export type IdentityTransition = {
|
|
16
|
+
readonly kind: 'attached';
|
|
17
|
+
readonly row: IdentityRow;
|
|
18
|
+
} | {
|
|
19
|
+
readonly kind: 'replugged';
|
|
20
|
+
readonly row: IdentityRow;
|
|
21
|
+
readonly previousPath: RuntimePath;
|
|
22
|
+
} | {
|
|
23
|
+
readonly kind: 'equipment-swapped-in-slot';
|
|
24
|
+
readonly row: IdentityRow;
|
|
25
|
+
readonly previousEquipment: EquipmentId;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: 'equipment-moved';
|
|
28
|
+
readonly row: IdentityRow;
|
|
29
|
+
readonly previousKey: string;
|
|
30
|
+
readonly previousSlot?: LogicalSlotId;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Tracks logical modem rows across replug/swap/move. Stateful by design — it holds
|
|
34
|
+
* the last-known row per stable key. `apply()` folds one resolved identity in and
|
|
35
|
+
* reports the transition it produced.
|
|
36
|
+
*/
|
|
37
|
+
export declare class IdentityRegistry {
|
|
38
|
+
#private;
|
|
39
|
+
/** A snapshot of the current logical rows, in insertion order. */
|
|
40
|
+
get rows(): IdentityRow[];
|
|
41
|
+
/** The row for a stable key, or `undefined`. */
|
|
42
|
+
get(stableKey: string): IdentityRow | undefined;
|
|
43
|
+
/** Drop a row (e.g. after a current-epoch removal). */
|
|
44
|
+
remove(stableKey: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Fold one resolved identity into the registry and report the transition.
|
|
47
|
+
* Keeps ONE row per stable key: a replug into the same slot updates the live
|
|
48
|
+
* path in place rather than adding a duplicate.
|
|
49
|
+
*/
|
|
50
|
+
apply(resolved: ResolvedIdentity): IdentityTransition;
|
|
51
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// The identity registry — ONE logical row per physical slot, across replugs.
|
|
2
|
+
//
|
|
3
|
+
// The epoch observer (A3.1) keys rows by the MM object path, which CHANGES on
|
|
4
|
+
// replug and daemon restart. This registry sits above it and keys rows by the
|
|
5
|
+
// STABLE identifier the ladder resolves (slot-UID / Physdev / sysfs / unique
|
|
6
|
+
// equipment id), so a modem that disconnects and reconnects to the SAME slot
|
|
7
|
+
// resolves to the SAME logical row instead of a duplicate.
|
|
8
|
+
//
|
|
9
|
+
// It also names the transitions the ladder can observe:
|
|
10
|
+
//
|
|
11
|
+
// - `attached` — a stable key we have not seen before.
|
|
12
|
+
// - `replugged` — same stable key, same equipment: one row, new path.
|
|
13
|
+
// - `equipment-swapped-in-slot` — same slot, DIFFERENT equipment. The slot keeps
|
|
14
|
+
// its policy (slot-inherits-policy): unplug modem A,
|
|
15
|
+
// plug modem B into the same slot, B adopts A's
|
|
16
|
+
// slot-bound policy.
|
|
17
|
+
// - `equipment-moved` — same equipment, DIFFERENT slot: the modem was
|
|
18
|
+
// physically moved to another port.
|
|
19
|
+
const equipmentValue = (equipment) => equipment.provenance !== 'none' && equipment.value.trim().length > 0
|
|
20
|
+
? equipment.value
|
|
21
|
+
: undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Tracks logical modem rows across replug/swap/move. Stateful by design — it holds
|
|
24
|
+
* the last-known row per stable key. `apply()` folds one resolved identity in and
|
|
25
|
+
* reports the transition it produced.
|
|
26
|
+
*/
|
|
27
|
+
export class IdentityRegistry {
|
|
28
|
+
#rows = new Map();
|
|
29
|
+
/** A snapshot of the current logical rows, in insertion order. */
|
|
30
|
+
get rows() {
|
|
31
|
+
return [...this.#rows.values()];
|
|
32
|
+
}
|
|
33
|
+
/** The row for a stable key, or `undefined`. */
|
|
34
|
+
get(stableKey) {
|
|
35
|
+
return this.#rows.get(stableKey);
|
|
36
|
+
}
|
|
37
|
+
/** Drop a row (e.g. after a current-epoch removal). */
|
|
38
|
+
remove(stableKey) {
|
|
39
|
+
this.#rows.delete(stableKey);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Fold one resolved identity into the registry and report the transition.
|
|
43
|
+
* Keeps ONE row per stable key: a replug into the same slot updates the live
|
|
44
|
+
* path in place rather than adding a duplicate.
|
|
45
|
+
*/
|
|
46
|
+
apply(resolved) {
|
|
47
|
+
const row = this.#rowFrom(resolved);
|
|
48
|
+
const existing = this.#rows.get(row.stableKey);
|
|
49
|
+
if (existing !== undefined) {
|
|
50
|
+
return this.#applyToExisting(existing, resolved, row);
|
|
51
|
+
}
|
|
52
|
+
// A unique equipment id at a NEW stable key that already lives elsewhere
|
|
53
|
+
// means the modem physically moved to a different slot/port.
|
|
54
|
+
const moved = this.#findByEquipment(row.equipmentId, row.stableKey);
|
|
55
|
+
if (moved !== undefined) {
|
|
56
|
+
this.#rows.delete(moved.stableKey);
|
|
57
|
+
this.#rows.set(row.stableKey, row);
|
|
58
|
+
return {
|
|
59
|
+
kind: 'equipment-moved',
|
|
60
|
+
row,
|
|
61
|
+
previousKey: moved.stableKey,
|
|
62
|
+
...(moved.logicalSlotId !== undefined ? { previousSlot: moved.logicalSlotId } : {}),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
this.#rows.set(row.stableKey, row);
|
|
66
|
+
return { kind: 'attached', row };
|
|
67
|
+
}
|
|
68
|
+
#applyToExisting(existing, resolved, row) {
|
|
69
|
+
const before = equipmentValue(existing.equipmentId);
|
|
70
|
+
const after = equipmentValue(resolved.identity.equipmentId);
|
|
71
|
+
if (before !== undefined && after !== undefined && before !== after) {
|
|
72
|
+
// Same slot, different equipment — the slot keeps its policy binding.
|
|
73
|
+
this.#rows.set(row.stableKey, row);
|
|
74
|
+
return { kind: 'equipment-swapped-in-slot', row, previousEquipment: existing.equipmentId };
|
|
75
|
+
}
|
|
76
|
+
// Same slot, same (or unchanged) equipment — a replug: one row, new path.
|
|
77
|
+
this.#rows.set(row.stableKey, row);
|
|
78
|
+
return { kind: 'replugged', row, previousPath: existing.runtimePath };
|
|
79
|
+
}
|
|
80
|
+
#rowFrom(resolved) {
|
|
81
|
+
const { identity, stableKey } = resolved;
|
|
82
|
+
return {
|
|
83
|
+
stableKey,
|
|
84
|
+
equipmentId: identity.equipmentId,
|
|
85
|
+
runtimePath: identity.runtimePath,
|
|
86
|
+
...(identity.logicalSlotId !== undefined ? { logicalSlotId: identity.logicalSlotId } : {}),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
#findByEquipment(equipment, exceptKey) {
|
|
90
|
+
const value = equipmentValue(equipment);
|
|
91
|
+
if (value === undefined) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
for (const row of this.#rows.values()) {
|
|
95
|
+
if (row.stableKey !== exceptKey && equipmentValue(row.equipmentId) === value) {
|
|
96
|
+
return row;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export { AT_BASELINE_ALLOWLIST, type AtAuditEntry, type AtAuditSink, AtCommandLease, type AtCommandLeaseDeps, AtCommandNotAllowedError, type AtCommandSender, AtCommandTimeoutError, type AtResponse, computeAtAllowlist, } from './at-lease.js';
|
|
2
|
+
export { type CellInfoProvenance, type CellReading, compareServing, normalizeCellInfo, normalizeCellReading, selectServingCell, } from './cell-info.js';
|
|
3
|
+
export { MM_BUS_NAME, MM_MANAGER_IFACE, MM_ROOT_PATH, MODEM_IFACE, MODEM_LOCATION_IFACE, MODEM3GPP_IFACE, MODEM3GPP_USSD_IFACE, SIM_IFACE, } from './constants.js';
|
|
4
|
+
export { CELLULAR_USB_VENDOR_IDS, cellularEvidence, cellularVendorName, classifyDevice, classifyUsbNetDevice, type DeviceClass, type DeviceClassification, descriptorsMatch, detectUsbMode, modelLabel, publishesGenericIdentity, type UsbDeviceSnapshot, type UsbInterface, type UsbNetClass, type UsbNetClassification, unitDiscriminator, vendorLabel, } from './device-classifier.js';
|
|
5
|
+
export { buildEnrichment, type EsimInfo, type EsimStatus, type ModemEnrichment, readEsimInfo, readRevision, type SimType, } from './enrichment.js';
|
|
6
|
+
export { detectMmFeatures, detectModemFeatures, type MmFeatures, type MmPropertyProbe, type MmVersion, parseMmVersion, probeModemProperties, } from './features.js';
|
|
7
|
+
export { looksLikeSlotUid, type ModemIdentityFacts, modemIdentityFactsFromTree, type ResolvedIdentity, resolveModemIdentities, resolveModemIdentity, SLOT_UID_PREFIX, type SlotSource, } from './identity-ladder.js';
|
|
8
|
+
export { IdentityRegistry, type IdentityRow, type IdentityTransition, } from './identity-registry.js';
|
|
9
|
+
export { ALLOW_ALL_INTERLOCK, type InterlockDecision, type InterlockTarget, type LifecycleInterlock, } from './lifecycle-interlock.js';
|
|
10
|
+
export { asManagedObjects, type DecodedInterfaces, type DecodedManagedObjects, type DecodedObject, type DecodedProps, fetchManagedObjects, findInterface, findObject, followObjectPath, hasInterface, numberProp, objectPaths, pathsWithInterface, propValue, stringProp, } from './managed-objects.js';
|
|
11
|
+
export { createMmDbusBackend, MmDbusBackend, type MmDbusBackendOptions, } from './mm-backend.js';
|
|
12
|
+
export { decodeLocationSources, encodeLocationSources, MmLocation, type MmLocationDeps, } from './mm-location.js';
|
|
13
|
+
export { MmMutations, type MmMutationsDeps } from './mm-mutations.js';
|
|
14
|
+
export { ModemActor, NO_OP_QUIESCE, type QuiesceHook, type QuiesceLeaseHandle, type QuiesceTarget, } from './modem-actor.js';
|
|
15
|
+
export { AUTO_APN_ADVISORY, type AutoApnAdvisory, type AutoApnTransitionResult, autoApnCapableFromVersion, autoApnSupportedByVersion, classifyActivation, type ManualApn, parseNmVersion, probeAutoApnCapability, toAutoArgs, toManualArgs, } from './nm-auto-apn.js';
|
|
16
|
+
export { buildProfile, cliArg, createGsmArgs, flattenPairs, gsmFieldPairs, passwordFlags, patchPairs, } from './nm-gsm-fields.js';
|
|
17
|
+
export { NmcliNmPort, type NmcliNmPortOptions, } from './nmcli-nm-port.js';
|
|
18
|
+
export { type NmcliResult, type NmcliRunner, parseTerse, runNmcli, SpawnNmcliRunner, } from './nmcli-runner.js';
|
|
19
|
+
export { createMmDbusObserver, type EpochRefreshEvent, MmDbusObserver, type MmDbusObserverOptions, } from './observer.js';
|
|
20
|
+
export { NONE_POWER_CAPABILITY, NONE_POWER_HOOK, type PowerCapability, type PowerCapabilityKind, type PowerCycleContext, type PowerCycleResult, type PowerHook, type PreferredUsbMode, unsupportedPowerHook, } from './power-contract.js';
|
|
21
|
+
export { attributeFault, attributeSnapshot, type FaultAttribution, type FaultSymptoms, symptomsFromSnapshot, } from './recovery-attribution.js';
|
|
22
|
+
export { type BudgetDecision, beginAttempt, DEFAULT_RECOVERY_BUDGET, INITIAL_BUDGET_STATE, markRecovered, type RecoveryBudget, type RecoveryBudgetState, } from './recovery-budget.js';
|
|
23
|
+
export { DEFAULT_LADDER_CONFIG, LADDER_ORDER, RecoveryLadder, type RecoveryLadderConfig, type RecoveryLadderDeps, type RecoveryOutcome, type RecoveryOutcomeKind, type RecoveryRequest, type RecoveryRung, type RecoveryStepContext, type RecoveryStepGate, type RecoveryStepReport, type RecoverySteps, type StepOutcome, } from './recovery-ladder.js';
|
|
24
|
+
export { createRouterEthernetProbe, type RouterEthernetProbeDeps } from './router-ethernet.js';
|
|
25
|
+
export { DEFAULT_SIGNAL_INTERVAL_SECONDS, type SignalCadence, SignalSetupManager, type SignalSetupManagerOptions, } from './signal-setup.js';
|
|
26
|
+
export { sendSimPin, sendSimPuk } from './sim-unlock.js';
|
|
27
|
+
export { ALLOW_ALL_TRANSITION_INTERLOCK, checkTransitionPreconditions, type InterlockHold, type PreconditionResult, type TransitionInterlock, type TransitionReadiness, type UsbModeTransitionOutcome, type UsbModeTransitionRequest, } from './transition-preconditions.js';
|
|
28
|
+
export * from './usage/index.js';
|
|
29
|
+
export { createUsbEnumerator, enumerateUsbDevices, parseUdevDatabase, type UsbEnumerator, type UsbEnumeratorDeps, } from './usb-enumerator.js';
|
|
30
|
+
export { UsbModeTransition, type UsbModeTransitionDeps } from './usb-mode-transition.js';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Backend adapters — the concrete D-Bus implementations of the port contracts.
|
|
2
|
+
//
|
|
3
|
+
// A3.1 lands the epoch-scoped `MmDbusObserver` (the read side). A3.2 adds MM
|
|
4
|
+
// feature detection + the stable identity ladder. Later A3 waves add mutations +
|
|
5
|
+
// Signal.Setup (A3.3) and the recovery ladder (A3.4) here.
|
|
6
|
+
export { AT_BASELINE_ALLOWLIST, AtCommandLease, AtCommandNotAllowedError, AtCommandTimeoutError, computeAtAllowlist, } from './at-lease.js';
|
|
7
|
+
export { compareServing, normalizeCellInfo, normalizeCellReading, selectServingCell, } from './cell-info.js';
|
|
8
|
+
export { MM_BUS_NAME, MM_MANAGER_IFACE, MM_ROOT_PATH, MODEM_IFACE, MODEM_LOCATION_IFACE, MODEM3GPP_IFACE, MODEM3GPP_USSD_IFACE, SIM_IFACE, } from './constants.js';
|
|
9
|
+
export { CELLULAR_USB_VENDOR_IDS, cellularEvidence, cellularVendorName, classifyDevice, classifyUsbNetDevice, descriptorsMatch, detectUsbMode, modelLabel, publishesGenericIdentity, unitDiscriminator, vendorLabel, } from './device-classifier.js';
|
|
10
|
+
export { buildEnrichment, readEsimInfo, readRevision, } from './enrichment.js';
|
|
11
|
+
export { detectMmFeatures, detectModemFeatures, parseMmVersion, probeModemProperties, } from './features.js';
|
|
12
|
+
export { looksLikeSlotUid, modemIdentityFactsFromTree, resolveModemIdentities, resolveModemIdentity, SLOT_UID_PREFIX, } from './identity-ladder.js';
|
|
13
|
+
export { IdentityRegistry, } from './identity-registry.js';
|
|
14
|
+
export { ALLOW_ALL_INTERLOCK, } from './lifecycle-interlock.js';
|
|
15
|
+
export { asManagedObjects, fetchManagedObjects, findInterface, findObject, followObjectPath, hasInterface, numberProp, objectPaths, pathsWithInterface, propValue, stringProp, } from './managed-objects.js';
|
|
16
|
+
export { createMmDbusBackend, MmDbusBackend, } from './mm-backend.js';
|
|
17
|
+
export { decodeLocationSources, encodeLocationSources, MmLocation, } from './mm-location.js';
|
|
18
|
+
export { MmMutations } from './mm-mutations.js';
|
|
19
|
+
export { ModemActor, NO_OP_QUIESCE, } from './modem-actor.js';
|
|
20
|
+
export { AUTO_APN_ADVISORY, autoApnCapableFromVersion, autoApnSupportedByVersion, classifyActivation, parseNmVersion, probeAutoApnCapability, toAutoArgs, toManualArgs, } from './nm-auto-apn.js';
|
|
21
|
+
export { buildProfile, cliArg, createGsmArgs, flattenPairs, gsmFieldPairs, passwordFlags, patchPairs, } from './nm-gsm-fields.js';
|
|
22
|
+
export { NmcliNmPort, } from './nmcli-nm-port.js';
|
|
23
|
+
export { parseTerse, runNmcli, SpawnNmcliRunner, } from './nmcli-runner.js';
|
|
24
|
+
export { createMmDbusObserver, MmDbusObserver, } from './observer.js';
|
|
25
|
+
export { NONE_POWER_CAPABILITY, NONE_POWER_HOOK, unsupportedPowerHook, } from './power-contract.js';
|
|
26
|
+
export { attributeFault, attributeSnapshot, symptomsFromSnapshot, } from './recovery-attribution.js';
|
|
27
|
+
export { beginAttempt, DEFAULT_RECOVERY_BUDGET, INITIAL_BUDGET_STATE, markRecovered, } from './recovery-budget.js';
|
|
28
|
+
export { DEFAULT_LADDER_CONFIG, LADDER_ORDER, RecoveryLadder, } from './recovery-ladder.js';
|
|
29
|
+
export { createRouterEthernetProbe } from './router-ethernet.js';
|
|
30
|
+
export { DEFAULT_SIGNAL_INTERVAL_SECONDS, SignalSetupManager, } from './signal-setup.js';
|
|
31
|
+
export { sendSimPin, sendSimPuk } from './sim-unlock.js';
|
|
32
|
+
export { ALLOW_ALL_TRANSITION_INTERLOCK, checkTransitionPreconditions, } from './transition-preconditions.js';
|
|
33
|
+
export * from './usage/index.js';
|
|
34
|
+
export { createUsbEnumerator, enumerateUsbDevices, parseUdevDatabase, } from './usb-enumerator.js';
|
|
35
|
+
export { UsbModeTransition } from './usb-mode-transition.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** What a disruptive step is about to act on — enough for an interlock to decide. */
|
|
2
|
+
export interface InterlockTarget {
|
|
3
|
+
readonly stableKey: string;
|
|
4
|
+
}
|
|
5
|
+
/** An interlock verdict. A denial ALWAYS carries a reason (why it is unsafe now). */
|
|
6
|
+
export type InterlockDecision = {
|
|
7
|
+
readonly allow: true;
|
|
8
|
+
} | {
|
|
9
|
+
readonly allow: false;
|
|
10
|
+
readonly reason: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* The safety interlock consulted before each disruptive recovery step. Returning
|
|
14
|
+
* `{ allow: false, reason }` stops the ladder — the modem is left as-is rather than
|
|
15
|
+
* disrupted mid-stream.
|
|
16
|
+
*/
|
|
17
|
+
export interface LifecycleInterlock {
|
|
18
|
+
canDisrupt(target: InterlockTarget): Promise<InterlockDecision>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The Phase-A interlock: always allows. There is no streaming-admission signal in
|
|
22
|
+
* the CLI, so nothing to block against. Phase B replaces this instance with a
|
|
23
|
+
* real streaming-aware interlock; no ladder code changes.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ALLOW_ALL_INTERLOCK: LifecycleInterlock;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// The pluggable safety interlock the recovery ladder consults before disruption.
|
|
2
|
+
//
|
|
3
|
+
// A disruptive recovery step (deactivate NM, disable MM, Reset(), power-cycle) must
|
|
4
|
+
// never fire while the modem is carrying a live stream. The ladder therefore asks a
|
|
5
|
+
// `LifecycleInterlock` BEFORE every disruptive step. Phase A (CLI) injects the
|
|
6
|
+
// always-allow stub below; Phase B wires CeraUI's real streaming-admission check
|
|
7
|
+
// into this SAME interface — the ladder code does not change, only the injected
|
|
8
|
+
// instance. A4.2's USB-mode transition reuses this exact interlock shape.
|
|
9
|
+
/**
|
|
10
|
+
* The Phase-A interlock: always allows. There is no streaming-admission signal in
|
|
11
|
+
* the CLI, so nothing to block against. Phase B replaces this instance with a
|
|
12
|
+
* real streaming-aware interlock; no ladder code changes.
|
|
13
|
+
*/
|
|
14
|
+
export const ALLOW_ALL_INTERLOCK = {
|
|
15
|
+
canDisrupt() {
|
|
16
|
+
return Promise.resolve({ allow: true });
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { DbusTransport, DbusValue, DbusVariant } from '../transport/index.js';
|
|
2
|
+
/** One interface's property entries: `[propertyName, variant][]`. */
|
|
3
|
+
export type DecodedProps = ReadonlyArray<readonly [string, DbusVariant]>;
|
|
4
|
+
/** One object's interfaces: `[interfaceName, props][]`. */
|
|
5
|
+
export type DecodedInterfaces = ReadonlyArray<readonly [string, DecodedProps]>;
|
|
6
|
+
/** One managed object: `[objectPath, interfaces]`. */
|
|
7
|
+
export type DecodedObject = readonly [string, DecodedInterfaces];
|
|
8
|
+
/** The whole `a{oa{sa{sv}}}` payload. */
|
|
9
|
+
export type DecodedManagedObjects = readonly DecodedObject[];
|
|
10
|
+
/** Treat a `GetManagedObjects` reply body value as the decoded tree. */
|
|
11
|
+
export declare function asManagedObjects(value: DbusValue | undefined): DecodedManagedObjects;
|
|
12
|
+
/** Call `ObjectManager.GetManagedObjects` on `destination` and decode the reply. */
|
|
13
|
+
export declare function fetchManagedObjects(transport: DbusTransport, destination: string): Promise<DecodedManagedObjects>;
|
|
14
|
+
/** Treat an `InterfacesAdded` body (`[path, interfaces]`) as one decoded object. */
|
|
15
|
+
export declare function asAddedObject(path: DbusValue, interfaces: DbusValue): DecodedObject;
|
|
16
|
+
/** Every object path in the tree, in wire order. */
|
|
17
|
+
export declare function objectPaths(tree: DecodedManagedObjects): string[];
|
|
18
|
+
/** The object at `path`, or `undefined`. */
|
|
19
|
+
export declare function findObject(tree: DecodedManagedObjects, path: string): DecodedObject | undefined;
|
|
20
|
+
/** The property entries of one interface on one object, or `undefined`. */
|
|
21
|
+
export declare function findInterface(tree: DecodedManagedObjects, path: string, iface: string): DecodedProps | undefined;
|
|
22
|
+
/** Object paths that carry a given interface. */
|
|
23
|
+
export declare function pathsWithInterface(tree: DecodedManagedObjects, iface: string): string[];
|
|
24
|
+
/** Whether an object exposes a given interface. */
|
|
25
|
+
export declare function hasInterface(tree: DecodedManagedObjects, path: string, iface: string): boolean;
|
|
26
|
+
/** The inner value of a property (a variant's `.value`), or `undefined`. */
|
|
27
|
+
export declare function propValue(props: DecodedProps | undefined, name: string): DbusValue | undefined;
|
|
28
|
+
/** A string-typed property, or `undefined` if absent / not a string. */
|
|
29
|
+
export declare function stringProp(props: DecodedProps | undefined, name: string): string | undefined;
|
|
30
|
+
/** A number-typed property, or `undefined` if absent / not a number. */
|
|
31
|
+
export declare function numberProp(props: DecodedProps | undefined, name: string): number | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* A string-array (`as`) property, or `undefined` if absent / not an array. An
|
|
34
|
+
* EMPTY array answers `[]` — the device saying "none", a different fact from an
|
|
35
|
+
* absent property. Non-string members are dropped, never coerced.
|
|
36
|
+
*/
|
|
37
|
+
export declare function stringArrayProp(props: DecodedProps | undefined, name: string): readonly string[] | undefined;
|
|
38
|
+
/** Resolve an object-path property (e.g. a modem's `Sim`) to that object's props. */
|
|
39
|
+
export declare function followObjectPath(tree: DecodedManagedObjects, props: DecodedProps | undefined, propName: string, iface: string): DecodedProps | undefined;
|