@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.
Files changed (480) hide show
  1. package/README.md +341 -0
  2. package/dist/backend/at-lease.d.ts +59 -0
  3. package/dist/backend/at-lease.js +118 -0
  4. package/dist/backend/cell-info.d.ts +46 -0
  5. package/dist/backend/cell-info.js +124 -0
  6. package/dist/backend/constants.d.ts +24 -0
  7. package/{src/backend/constants.ts → dist/backend/constants.js} +4 -9
  8. package/dist/backend/device-classifier.d.ts +46 -0
  9. package/dist/backend/device-classifier.js +258 -0
  10. package/dist/backend/enrichment.d.ts +28 -0
  11. package/dist/backend/enrichment.js +59 -0
  12. package/dist/backend/features.d.ts +61 -0
  13. package/dist/backend/features.js +109 -0
  14. package/dist/backend/identity-ladder.d.ts +57 -0
  15. package/dist/backend/identity-ladder.js +158 -0
  16. package/dist/backend/identity-registry.d.ts +51 -0
  17. package/dist/backend/identity-registry.js +101 -0
  18. package/dist/backend/index.d.ts +30 -0
  19. package/dist/backend/index.js +35 -0
  20. package/dist/backend/lifecycle-interlock.d.ts +25 -0
  21. package/dist/backend/lifecycle-interlock.js +18 -0
  22. package/dist/backend/managed-objects.d.ts +39 -0
  23. package/dist/backend/managed-objects.js +82 -0
  24. package/dist/backend/mapping.d.ts +11 -0
  25. package/dist/backend/mapping.js +148 -0
  26. package/dist/backend/mm-backend.d.ts +44 -0
  27. package/dist/backend/mm-backend.js +154 -0
  28. package/dist/backend/mm-location.d.ts +21 -0
  29. package/dist/backend/mm-location.js +237 -0
  30. package/dist/backend/mm-mutations.d.ts +42 -0
  31. package/dist/backend/mm-mutations.js +259 -0
  32. package/dist/backend/modem-actor.d.ts +41 -0
  33. package/dist/backend/modem-actor.js +78 -0
  34. package/dist/backend/nm-auto-apn.d.ts +54 -0
  35. package/dist/backend/nm-auto-apn.js +124 -0
  36. package/dist/backend/nm-gsm-fields.d.ts +23 -0
  37. package/dist/backend/nm-gsm-fields.js +107 -0
  38. package/dist/backend/nmcli-nm-port.d.ts +28 -0
  39. package/dist/backend/nmcli-nm-port.js +173 -0
  40. package/dist/backend/nmcli-runner.d.ts +24 -0
  41. package/dist/backend/nmcli-runner.js +35 -0
  42. package/dist/backend/observer.d.ts +37 -0
  43. package/dist/backend/observer.js +219 -0
  44. package/dist/backend/power-contract.d.ts +49 -0
  45. package/dist/backend/power-contract.js +34 -0
  46. package/dist/backend/recovery-attribution.d.ts +32 -0
  47. package/dist/backend/recovery-attribution.js +57 -0
  48. package/dist/backend/recovery-budget.d.ts +45 -0
  49. package/dist/backend/recovery-budget.js +44 -0
  50. package/dist/backend/recovery-ladder.d.ts +94 -0
  51. package/dist/backend/recovery-ladder.js +116 -0
  52. package/dist/backend/router-ethernet.d.ts +19 -0
  53. package/dist/backend/router-ethernet.js +66 -0
  54. package/dist/backend/row-store.d.ts +13 -0
  55. package/dist/backend/row-store.js +82 -0
  56. package/dist/backend/signal-setup.d.ts +30 -0
  57. package/dist/backend/signal-setup.js +92 -0
  58. package/dist/backend/sim-unlock.d.ts +13 -0
  59. package/dist/backend/sim-unlock.js +153 -0
  60. package/dist/backend/transition-preconditions.d.ts +101 -0
  61. package/dist/backend/transition-preconditions.js +132 -0
  62. package/dist/backend/usage/accounting.d.ts +39 -0
  63. package/dist/backend/usage/accounting.js +73 -0
  64. package/dist/backend/usage/billing-cycle.d.ts +11 -0
  65. package/dist/backend/usage/billing-cycle.js +39 -0
  66. package/dist/backend/usage/boot-id.d.ts +6 -0
  67. package/{src/backend/usage/boot-id.ts → dist/backend/usage/boot-id.js} +7 -7
  68. package/dist/backend/usage/index.d.ts +8 -0
  69. package/dist/backend/usage/index.js +11 -0
  70. package/dist/backend/usage/policy-store.d.ts +50 -0
  71. package/dist/backend/usage/policy-store.js +161 -0
  72. package/dist/backend/usage/policy-write.d.ts +65 -0
  73. package/dist/backend/usage/policy-write.js +112 -0
  74. package/dist/backend/usage/proc-net-dev.d.ts +18 -0
  75. package/{src/backend/usage/proc-net-dev.ts → dist/backend/usage/proc-net-dev.js} +39 -47
  76. package/dist/backend/usage/sampler.d.ts +75 -0
  77. package/dist/backend/usage/sampler.js +211 -0
  78. package/dist/backend/usage/store.d.ts +38 -0
  79. package/dist/backend/usage/store.js +126 -0
  80. package/dist/backend/usb-device-snapshot.d.ts +31 -0
  81. package/dist/backend/usb-device-snapshot.js +1 -0
  82. package/dist/backend/usb-enumerator.d.ts +21 -0
  83. package/dist/backend/usb-enumerator.js +153 -0
  84. package/dist/backend/usb-mode-transition.d.ts +29 -0
  85. package/dist/backend/usb-mode-transition.js +216 -0
  86. package/dist/band/band-names.d.ts +42 -0
  87. package/dist/band/band-names.js +150 -0
  88. package/dist/band/certification.d.ts +84 -0
  89. package/dist/band/certification.js +127 -0
  90. package/dist/band/certified-bands.json +4 -0
  91. package/dist/band/index.d.ts +2 -0
  92. package/dist/band/index.js +8 -0
  93. package/dist/capability/detect.d.ts +52 -0
  94. package/dist/capability/detect.js +86 -0
  95. package/dist/capability/five-g-preference.d.ts +104 -0
  96. package/dist/capability/five-g-preference.js +171 -0
  97. package/dist/capability/index.d.ts +3 -0
  98. package/dist/capability/index.js +10 -0
  99. package/dist/capability/support-claim.d.ts +39 -0
  100. package/dist/capability/support-claim.js +81 -0
  101. package/dist/domain/brand.d.ts +10 -0
  102. package/dist/domain/brand.js +21 -0
  103. package/dist/domain/errors.d.ts +32 -0
  104. package/dist/domain/errors.js +48 -0
  105. package/dist/domain/generation.d.ts +8 -0
  106. package/dist/domain/generation.js +12 -0
  107. package/dist/domain/guards.d.ts +6 -0
  108. package/dist/domain/guards.js +127 -0
  109. package/dist/domain/identity.d.ts +109 -0
  110. package/dist/domain/identity.js +86 -0
  111. package/dist/domain/index.d.ts +14 -0
  112. package/dist/domain/index.js +18 -0
  113. package/dist/domain/mm-enums.d.ts +12 -0
  114. package/dist/domain/mm-enums.js +139 -0
  115. package/dist/domain/modem-presentation.d.ts +10 -0
  116. package/dist/domain/modem-presentation.js +39 -0
  117. package/dist/domain/observation.d.ts +39 -0
  118. package/dist/domain/observation.js +4 -0
  119. package/dist/domain/operation.d.ts +118 -0
  120. package/dist/domain/operation.js +85 -0
  121. package/dist/domain/physical-identity.d.ts +43 -0
  122. package/dist/domain/physical-identity.js +113 -0
  123. package/{src/domain/policy.ts → dist/domain/policy.d.ts} +34 -69
  124. package/dist/domain/policy.js +38 -0
  125. package/dist/domain/shadow-divergence.d.ts +27 -0
  126. package/dist/domain/shadow-divergence.js +70 -0
  127. package/dist/domain/snapshot.d.ts +53 -0
  128. package/dist/domain/snapshot.js +75 -0
  129. package/{src/domain/state.ts → dist/domain/state.d.ts} +23 -122
  130. package/dist/domain/state.js +38 -0
  131. package/dist/fcc/coverage.d.ts +63 -0
  132. package/dist/fcc/coverage.js +102 -0
  133. package/dist/fcc/index.d.ts +3 -0
  134. package/dist/fcc/index.js +12 -0
  135. package/dist/fcc/policy-store.d.ts +40 -0
  136. package/dist/fcc/policy-store.js +146 -0
  137. package/dist/fcc/policy-write.d.ts +32 -0
  138. package/dist/fcc/policy-write.js +37 -0
  139. package/dist/hardware/hilink-protocol.d.ts +39 -0
  140. package/dist/hardware/hilink-protocol.js +58 -0
  141. package/dist/hardware/index.d.ts +3 -0
  142. package/dist/hardware/index.js +15 -0
  143. package/dist/hardware/router-parsers.d.ts +89 -0
  144. package/dist/hardware/router-parsers.js +234 -0
  145. package/dist/index.d.ts +20 -0
  146. package/dist/index.js +27 -0
  147. package/dist/journal/codec.d.ts +44 -0
  148. package/dist/journal/codec.js +198 -0
  149. package/dist/journal/engine.d.ts +28 -0
  150. package/dist/journal/engine.js +68 -0
  151. package/dist/journal/entry.d.ts +74 -0
  152. package/dist/journal/entry.js +56 -0
  153. package/dist/journal/index.d.ts +6 -0
  154. package/dist/journal/index.js +6 -0
  155. package/dist/journal/legacy-ceraui.d.ts +73 -0
  156. package/dist/journal/legacy-ceraui.js +227 -0
  157. package/dist/journal/recovery.d.ts +58 -0
  158. package/dist/journal/recovery.js +117 -0
  159. package/dist/journal/store.d.ts +55 -0
  160. package/dist/journal/store.js +150 -0
  161. package/dist/location/fix-state.d.ts +53 -0
  162. package/dist/location/fix-state.js +75 -0
  163. package/dist/location/index.d.ts +2 -0
  164. package/dist/location/index.js +8 -0
  165. package/dist/location/nmea.d.ts +10 -0
  166. package/dist/location/nmea.js +89 -0
  167. package/dist/observations/envelope.d.ts +63 -0
  168. package/dist/observations/envelope.js +77 -0
  169. package/dist/observations/freshness.d.ts +28 -0
  170. package/dist/observations/freshness.js +76 -0
  171. package/dist/observations/index.d.ts +13 -0
  172. package/dist/observations/index.js +24 -0
  173. package/dist/observations/metric.d.ts +61 -0
  174. package/dist/observations/metric.js +73 -0
  175. package/dist/observations/model.d.ts +80 -0
  176. package/dist/observations/model.js +11 -0
  177. package/dist/observations/provenance.d.ts +94 -0
  178. package/dist/observations/provenance.js +67 -0
  179. package/dist/observations/raw.d.ts +42 -0
  180. package/dist/observations/raw.js +146 -0
  181. package/dist/observations/reading.d.ts +51 -0
  182. package/dist/observations/reading.js +65 -0
  183. package/dist/observations/sources/hilink.d.ts +10 -0
  184. package/dist/observations/sources/hilink.js +84 -0
  185. package/dist/observations/sources/modemmanager.d.ts +18 -0
  186. package/dist/observations/sources/modemmanager.js +239 -0
  187. package/dist/observations/sources/router-shared.d.ts +29 -0
  188. package/dist/observations/sources/router-shared.js +68 -0
  189. package/dist/observations/sources/ufi.d.ts +10 -0
  190. package/dist/observations/sources/ufi.js +111 -0
  191. package/dist/observations/sources/zte.d.ts +7 -0
  192. package/dist/observations/sources/zte.js +71 -0
  193. package/dist/observations/state-separation.d.ts +64 -0
  194. package/dist/observations/state-separation.js +52 -0
  195. package/dist/operation-ids.d.ts +2 -0
  196. package/dist/operation-ids.js +26 -0
  197. package/dist/operations/contracts.d.ts +72 -0
  198. package/dist/operations/contracts.js +1 -0
  199. package/dist/operations/index.d.ts +1 -0
  200. package/dist/operations/index.js +1 -0
  201. package/dist/operations/operation-engine.d.ts +16 -0
  202. package/dist/operations/operation-engine.js +194 -0
  203. package/dist/ports/index.d.ts +12 -0
  204. package/{src/ports/index.ts → dist/ports/index.js} +12 -8
  205. package/dist/ports/location.d.ts +87 -0
  206. package/dist/ports/location.js +36 -0
  207. package/dist/ports/modem-manager.d.ts +89 -0
  208. package/dist/ports/modem-manager.js +9 -0
  209. package/dist/ports/mutation-admission.d.ts +27 -0
  210. package/dist/ports/mutation-admission.js +9 -0
  211. package/dist/ports/network-manager.d.ts +68 -0
  212. package/dist/ports/network-manager.js +13 -0
  213. package/{src/ports/observation.ts → dist/ports/observation.d.ts} +16 -27
  214. package/dist/ports/observation.js +7 -0
  215. package/dist/ports/ops.d.ts +44 -0
  216. package/dist/ports/ops.js +16 -0
  217. package/{src/ports/receipts.ts → dist/ports/receipts.d.ts} +5 -27
  218. package/dist/ports/receipts.js +9 -0
  219. package/dist/ports/reconcile.d.ts +33 -0
  220. package/dist/ports/reconcile.js +200 -0
  221. package/dist/ports/resource-ownership.d.ts +29 -0
  222. package/dist/ports/resource-ownership.js +1 -0
  223. package/dist/ports/router.d.ts +19 -0
  224. package/dist/ports/router.js +7 -0
  225. package/dist/ports/sms.d.ts +64 -0
  226. package/dist/ports/sms.js +24 -0
  227. package/dist/ports/uhubctl.d.ts +6 -0
  228. package/dist/ports/uhubctl.js +1 -0
  229. package/dist/providers/contracts.d.ts +124 -0
  230. package/dist/providers/contracts.js +10 -0
  231. package/dist/providers/huawei-hilink/index.d.ts +2 -0
  232. package/dist/providers/huawei-hilink/index.js +2 -0
  233. package/dist/providers/huawei-hilink/operations.d.ts +20 -0
  234. package/dist/providers/huawei-hilink/operations.js +56 -0
  235. package/dist/providers/huawei-hilink/provider.d.ts +52 -0
  236. package/dist/providers/huawei-hilink/provider.js +76 -0
  237. package/dist/providers/huawei-hilink/runtime.d.ts +22 -0
  238. package/dist/providers/huawei-hilink/runtime.js +171 -0
  239. package/dist/providers/huawei-hilink/session.d.ts +28 -0
  240. package/dist/providers/huawei-hilink/session.js +120 -0
  241. package/dist/providers/huawei-hilink/transport.d.ts +19 -0
  242. package/dist/providers/huawei-hilink/transport.js +1 -0
  243. package/dist/providers/index.d.ts +8 -0
  244. package/dist/providers/index.js +8 -0
  245. package/dist/providers/matcher.d.ts +3 -0
  246. package/dist/providers/matcher.js +205 -0
  247. package/dist/providers/modem-manager/errors.d.ts +7 -0
  248. package/dist/providers/modem-manager/errors.js +37 -0
  249. package/dist/providers/modem-manager/generic-operations.d.ts +10 -0
  250. package/dist/providers/modem-manager/generic-operations.js +209 -0
  251. package/dist/providers/modem-manager/index.d.ts +4 -0
  252. package/dist/providers/modem-manager/index.js +4 -0
  253. package/dist/providers/modem-manager/module-operations.d.ts +21 -0
  254. package/dist/providers/modem-manager/module-operations.js +118 -0
  255. package/dist/providers/modem-manager/provider.d.ts +41 -0
  256. package/dist/providers/modem-manager/provider.js +155 -0
  257. package/dist/providers/modem-manager/runtime-composition-operation.d.ts +32 -0
  258. package/dist/providers/modem-manager/runtime-composition-operation.js +151 -0
  259. package/dist/providers/modem-manager/snapshot.d.ts +5 -0
  260. package/dist/providers/modem-manager/snapshot.js +204 -0
  261. package/dist/providers/modem-manager/types.d.ts +137 -0
  262. package/dist/providers/modem-manager/types.js +1 -0
  263. package/dist/providers/network-manager/adapter.d.ts +71 -0
  264. package/dist/providers/network-manager/adapter.js +348 -0
  265. package/dist/providers/network-manager/index.d.ts +2 -0
  266. package/dist/providers/network-manager/index.js +2 -0
  267. package/dist/providers/network-manager/types.d.ts +171 -0
  268. package/dist/providers/network-manager/types.js +77 -0
  269. package/dist/providers/registry.d.ts +13 -0
  270. package/dist/providers/registry.js +33 -0
  271. package/dist/providers/ufi-himi/index.d.ts +6 -0
  272. package/dist/providers/ufi-himi/index.js +6 -0
  273. package/dist/providers/ufi-himi/operations.d.ts +41 -0
  274. package/dist/providers/ufi-himi/operations.js +66 -0
  275. package/dist/providers/ufi-himi/prohibitions.d.ts +62 -0
  276. package/dist/providers/ufi-himi/prohibitions.js +88 -0
  277. package/dist/providers/ufi-himi/provider.d.ts +41 -0
  278. package/dist/providers/ufi-himi/provider.js +204 -0
  279. package/dist/providers/ufi-himi/qualcomm-evidence.d.ts +32 -0
  280. package/dist/providers/ufi-himi/qualcomm-evidence.js +51 -0
  281. package/dist/providers/ufi-himi/session.d.ts +46 -0
  282. package/dist/providers/ufi-himi/session.js +92 -0
  283. package/dist/providers/ufi-himi/transport.d.ts +29 -0
  284. package/dist/providers/ufi-himi/transport.js +25 -0
  285. package/dist/providers/zte-goform/index.d.ts +2 -0
  286. package/dist/providers/zte-goform/index.js +2 -0
  287. package/dist/providers/zte-goform/provider.d.ts +56 -0
  288. package/dist/providers/zte-goform/provider.js +101 -0
  289. package/dist/providers/zte-goform/session.d.ts +23 -0
  290. package/dist/providers/zte-goform/session.js +197 -0
  291. package/dist/providers/zte-goform/transport.d.ts +16 -0
  292. package/dist/providers/zte-goform/transport.js +1 -0
  293. package/dist/radio/band-truth.d.ts +50 -0
  294. package/dist/radio/band-truth.js +92 -0
  295. package/dist/radio/index.d.ts +3 -0
  296. package/dist/radio/index.js +10 -0
  297. package/dist/radio/mode-combinations.d.ts +88 -0
  298. package/dist/radio/mode-combinations.js +198 -0
  299. package/dist/radio/mode-truth.d.ts +67 -0
  300. package/dist/radio/mode-truth.js +112 -0
  301. package/dist/redact.d.ts +15 -0
  302. package/dist/redact.js +189 -0
  303. package/dist/safety/composition-root.d.ts +28 -0
  304. package/dist/safety/composition-root.js +65 -0
  305. package/dist/safety/flock-resource-ownership.d.ts +11 -0
  306. package/dist/safety/flock-resource-ownership.js +138 -0
  307. package/dist/safety/index.d.ts +2 -0
  308. package/dist/safety/index.js +2 -0
  309. package/dist/sms/dbus-messaging.d.ts +17 -0
  310. package/dist/sms/dbus-messaging.js +185 -0
  311. package/dist/sms/inbox-store.d.ts +10 -0
  312. package/dist/sms/inbox-store.js +82 -0
  313. package/dist/sms/index.d.ts +4 -0
  314. package/dist/sms/index.js +10 -0
  315. package/dist/sms/mmcli-parse.d.ts +54 -0
  316. package/dist/sms/mmcli-parse.js +224 -0
  317. package/dist/sms/normalize.d.ts +42 -0
  318. package/dist/sms/normalize.js +95 -0
  319. package/dist/testing/domain-fakes.d.ts +58 -0
  320. package/dist/testing/domain-fakes.js +98 -0
  321. package/dist/testing/index.d.ts +2 -0
  322. package/dist/testing/index.js +17 -0
  323. package/dist/testing/provider-fakes.d.ts +45 -0
  324. package/dist/testing/provider-fakes.js +64 -0
  325. package/dist/transport/calls.d.ts +9 -0
  326. package/dist/transport/calls.js +88 -0
  327. package/dist/transport/codec.d.ts +3 -0
  328. package/dist/transport/codec.js +207 -0
  329. package/dist/transport/dbus-native.d.ts +57 -0
  330. package/dist/transport/dbus-native.js +17 -0
  331. package/dist/transport/errors.d.ts +21 -0
  332. package/{src/transport/errors.ts → dist/transport/errors.js} +34 -46
  333. package/dist/transport/index.d.ts +4 -0
  334. package/dist/transport/index.js +9 -0
  335. package/dist/transport/signals.d.ts +15 -0
  336. package/dist/transport/signals.js +123 -0
  337. package/dist/transport/signature.d.ts +7 -0
  338. package/dist/transport/signature.js +94 -0
  339. package/dist/transport/transport.d.ts +2 -0
  340. package/dist/transport/transport.js +202 -0
  341. package/dist/transport/types.d.ts +61 -0
  342. package/dist/transport/types.js +19 -0
  343. package/dist/usb-mode/catalog-schema.d.ts +139 -0
  344. package/dist/usb-mode/catalog-schema.js +97 -0
  345. package/dist/usb-mode/catalog.d.ts +21 -0
  346. package/{src/usb-mode/catalog.ts → dist/usb-mode/catalog.js} +10 -32
  347. package/dist/usb-mode/certified-catalog.json +67 -0
  348. package/dist/usb-mode/index.d.ts +6 -0
  349. package/dist/usb-mode/index.js +16 -0
  350. package/dist/usb-mode/ingestion.d.ts +111 -0
  351. package/dist/usb-mode/ingestion.js +187 -0
  352. package/dist/usb-mode/promotion-review.d.ts +21 -0
  353. package/dist/usb-mode/promotion-review.js +87 -0
  354. package/dist/usb-mode/runtime-capability.d.ts +59 -0
  355. package/dist/usb-mode/runtime-capability.js +157 -0
  356. package/dist/usb-mode/usb-devices-parse.d.ts +36 -0
  357. package/dist/usb-mode/usb-devices-parse.js +157 -0
  358. package/dist/ussd/calls.d.ts +32 -0
  359. package/dist/ussd/calls.js +96 -0
  360. package/dist/ussd/index.d.ts +5 -0
  361. package/dist/ussd/index.js +12 -0
  362. package/dist/ussd/mm-ussd.d.ts +37 -0
  363. package/dist/ussd/mm-ussd.js +205 -0
  364. package/dist/ussd/refusal.d.ts +53 -0
  365. package/dist/ussd/refusal.js +154 -0
  366. package/dist/ussd/registration.d.ts +20 -0
  367. package/dist/ussd/registration.js +101 -0
  368. package/dist/ussd/session.d.ts +106 -0
  369. package/dist/ussd/session.js +163 -0
  370. package/package.json +38 -4
  371. package/src/backend/at-lease.test.ts +0 -106
  372. package/src/backend/at-lease.ts +0 -158
  373. package/src/backend/cell-info.test.ts +0 -154
  374. package/src/backend/cell-info.ts +0 -160
  375. package/src/backend/device-classifier.test.ts +0 -168
  376. package/src/backend/device-classifier.ts +0 -248
  377. package/src/backend/enrichment.ts +0 -96
  378. package/src/backend/features.test.ts +0 -162
  379. package/src/backend/features.ts +0 -179
  380. package/src/backend/identity-ladder.test.ts +0 -117
  381. package/src/backend/identity-ladder.ts +0 -221
  382. package/src/backend/identity-registry.test.ts +0 -89
  383. package/src/backend/identity-registry.ts +0 -151
  384. package/src/backend/index.ts +0 -236
  385. package/src/backend/lifecycle-interlock.ts +0 -38
  386. package/src/backend/managed-objects.ts +0 -108
  387. package/src/backend/mapping.ts +0 -160
  388. package/src/backend/mm-backend.ts +0 -191
  389. package/src/backend/mm-mutations.ts +0 -228
  390. package/src/backend/modem-actor.test.ts +0 -95
  391. package/src/backend/modem-actor.ts +0 -112
  392. package/src/backend/nm-auto-apn.ts +0 -161
  393. package/src/backend/nm-gsm-fields.ts +0 -122
  394. package/src/backend/nmcli-nm-port.ts +0 -228
  395. package/src/backend/nmcli-runner.ts +0 -52
  396. package/src/backend/observer.ts +0 -297
  397. package/src/backend/power-contract.test.ts +0 -40
  398. package/src/backend/power-contract.ts +0 -83
  399. package/src/backend/recovery-attribution.test.ts +0 -102
  400. package/src/backend/recovery-attribution.ts +0 -86
  401. package/src/backend/recovery-budget.test.ts +0 -64
  402. package/src/backend/recovery-budget.ts +0 -84
  403. package/src/backend/recovery-ladder.test.ts +0 -257
  404. package/src/backend/recovery-ladder.ts +0 -249
  405. package/src/backend/router-ethernet.test.ts +0 -71
  406. package/src/backend/router-ethernet.ts +0 -90
  407. package/src/backend/row-store.ts +0 -105
  408. package/src/backend/signal-setup.ts +0 -112
  409. package/src/backend/sim-unlock.ts +0 -193
  410. package/src/backend/transition-preconditions.ts +0 -149
  411. package/src/backend/uhubctl-power-hook.test.ts +0 -274
  412. package/src/backend/uhubctl-power-hook.ts +0 -377
  413. package/src/backend/usage/accounting.test.ts +0 -147
  414. package/src/backend/usage/accounting.ts +0 -123
  415. package/src/backend/usage/billing-cycle.test.ts +0 -62
  416. package/src/backend/usage/billing-cycle.ts +0 -45
  417. package/src/backend/usage/index.ts +0 -60
  418. package/src/backend/usage/policy-store.test.ts +0 -164
  419. package/src/backend/usage/policy-store.ts +0 -216
  420. package/src/backend/usage/policy-write.test.ts +0 -198
  421. package/src/backend/usage/policy-write.ts +0 -207
  422. package/src/backend/usage/proc-net-dev.test.ts +0 -56
  423. package/src/backend/usage/sampler.test.ts +0 -327
  424. package/src/backend/usage/sampler.ts +0 -282
  425. package/src/backend/usage/store.test.ts +0 -148
  426. package/src/backend/usage/store.ts +0 -177
  427. package/src/backend/usb-enumerator.test.ts +0 -87
  428. package/src/backend/usb-enumerator.ts +0 -181
  429. package/src/backend/usb-mode-transition.test.ts +0 -323
  430. package/src/backend/usb-mode-transition.ts +0 -253
  431. package/src/domain/brand.ts +0 -29
  432. package/src/domain/errors.ts +0 -77
  433. package/src/domain/guards.test.ts +0 -218
  434. package/src/domain/guards.ts +0 -144
  435. package/src/domain/identity.test.ts +0 -83
  436. package/src/domain/identity.ts +0 -165
  437. package/src/domain/index.ts +0 -12
  438. package/src/domain/snapshot.test.ts +0 -266
  439. package/src/domain/snapshot.ts +0 -120
  440. package/src/index.test.ts +0 -6
  441. package/src/index.ts +0 -15
  442. package/src/ports/README.md +0 -61
  443. package/src/ports/forbidden-surface.test.ts +0 -241
  444. package/src/ports/modem-manager.ts +0 -72
  445. package/src/ports/network-manager.ts +0 -87
  446. package/src/ports/ops.ts +0 -60
  447. package/src/ports/ops.type-test.ts +0 -39
  448. package/src/ports/receipts.test.ts +0 -153
  449. package/src/ports/reconcile.test.ts +0 -152
  450. package/src/ports/reconcile.ts +0 -338
  451. package/src/ports/router.ts +0 -29
  452. package/src/redact.test.ts +0 -82
  453. package/src/redact.ts +0 -73
  454. package/src/transport/README.md +0 -65
  455. package/src/transport/calls.ts +0 -113
  456. package/src/transport/characterization.test.ts +0 -260
  457. package/src/transport/codec.test.ts +0 -118
  458. package/src/transport/codec.ts +0 -240
  459. package/src/transport/conformance-python.test.ts +0 -152
  460. package/src/transport/conformance-same-lib.test.ts +0 -115
  461. package/src/transport/dbus-native-lib.d.ts +0 -19
  462. package/src/transport/dbus-native.ts +0 -85
  463. package/src/transport/index.ts +0 -30
  464. package/src/transport/no-library-leak.test.ts +0 -61
  465. package/src/transport/reliability.test.ts +0 -173
  466. package/src/transport/signals.ts +0 -150
  467. package/src/transport/signature.ts +0 -110
  468. package/src/transport/test-support/fake-service.ts +0 -168
  469. package/src/transport/test-support/independent-producer.py +0 -110
  470. package/src/transport/test-support/private-bus.ts +0 -66
  471. package/src/transport/transport.ts +0 -250
  472. package/src/transport/types.ts +0 -118
  473. package/src/usb-mode/catalog-schema.test.ts +0 -181
  474. package/src/usb-mode/catalog-schema.ts +0 -113
  475. package/src/usb-mode/certified-catalog.json +0 -67
  476. package/src/usb-mode/index.ts +0 -58
  477. package/src/usb-mode/ingestion.test.ts +0 -268
  478. package/src/usb-mode/ingestion.ts +0 -297
  479. package/src/usb-mode/promotion-review.ts +0 -117
  480. 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
+ }