@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,157 @@
1
+ export const RUNTIME_COMPOSITION_VENDORS = ['fibocom', 'quectel', 'simcom', 'sierra'];
2
+ /** Commands only: selecting a port, sending, deadlines, and retries belong to the provider. */
3
+ export const RUNTIME_COMPOSITION_QUERY_REGISTRY = Object.freeze({
4
+ fibocom: Object.freeze({ current: 'AT+GTUSBMODE?', enumerate: 'AT+GTUSBMODE=?' }),
5
+ quectel: Object.freeze({ current: 'AT+QCFG="usbnet"', enumerate: 'AT+QCFG=?' }),
6
+ simcom: Object.freeze({ current: 'AT+CUSBPIDSWITCH?', enumerate: 'AT+CUSBPIDSWITCH=?' }),
7
+ sierra: Object.freeze({ current: 'AT!USBCOMP?', enumerate: 'AT!USBCOMP=?' }),
8
+ });
9
+ function decimalSetCommand(prefix) {
10
+ return (target) => typeof target === 'number' && Number.isSafeInteger(target) && target >= 0
11
+ ? `${prefix}${target}`
12
+ : undefined;
13
+ }
14
+ /** Exact reviewed SET forms. Callers still allowlist only the one enumerated target selected. */
15
+ export const RUNTIME_COMPOSITION_SET_REGISTRY = Object.freeze({
16
+ fibocom: decimalSetCommand('AT+GTUSBMODE='),
17
+ quectel: decimalSetCommand('AT+QCFG="usbnet",'),
18
+ simcom: (target) => typeof target === 'string' && /^[0-9A-Fa-f]{4}$/.test(target)
19
+ ? `AT+CUSBPIDSWITCH=${target.toUpperCase()},1,1`
20
+ : undefined,
21
+ sierra: decimalSetCommand('AT!USBCOMP='),
22
+ });
23
+ const UNKNOWN_VENDOR = Object.freeze({
24
+ status: 'unknown',
25
+ current: null,
26
+ enumerated: [],
27
+ returnPathProven: false,
28
+ offerable: [],
29
+ reason: 'vendor-unsupported',
30
+ });
31
+ const MALFORMED_RESPONSE = Object.freeze({
32
+ status: 'unknown',
33
+ current: null,
34
+ enumerated: [],
35
+ returnPathProven: false,
36
+ offerable: [],
37
+ reason: 'malformed-response',
38
+ });
39
+ function parseDecimalDomain(domain) {
40
+ const values = [];
41
+ for (const member of domain.split(',')) {
42
+ const token = member.trim();
43
+ const range = /^(\d+)-(\d+)$/.exec(token);
44
+ if (range !== null) {
45
+ const start = Number(range[1]);
46
+ const end = Number(range[2]);
47
+ if (!Number.isSafeInteger(start) ||
48
+ !Number.isSafeInteger(end) ||
49
+ start > end ||
50
+ end - start > 255)
51
+ return undefined;
52
+ for (let value = start; value <= end; value += 1)
53
+ values.push(value);
54
+ continue;
55
+ }
56
+ if (!/^\d+$/.test(token))
57
+ return undefined;
58
+ const value = Number(token);
59
+ if (!Number.isSafeInteger(value))
60
+ return undefined;
61
+ values.push(value);
62
+ }
63
+ return values.length > 0 && new Set(values).size === values.length ? values : undefined;
64
+ }
65
+ function parseFibocom(input) {
66
+ const current = /^\s*\+GTUSBMODE:\s*(\d+)\s*$/m.exec(input.currentResponse);
67
+ const enumeration = /^\s*\+GTUSBMODE:\s*\(([^)]+)\)\s*$/m.exec(input.enumerationResponse);
68
+ if (current === null || enumeration === null)
69
+ return undefined;
70
+ const enumerated = parseDecimalDomain(enumeration[1] ?? '');
71
+ return enumerated === undefined ? undefined : { current: Number(current[1]), enumerated };
72
+ }
73
+ function parseQuectel(input) {
74
+ const current = /^\s*\+QCFG:\s*"usbnet"\s*,\s*(\d+)\s*$/m.exec(input.currentResponse);
75
+ const enumeration = /^\s*\+QCFG:\s*"usbnet"\s*,\s*\(([^)]+)\)\s*$/m.exec(input.enumerationResponse);
76
+ if (current === null || enumeration === null)
77
+ return undefined;
78
+ const enumerated = parseDecimalDomain(enumeration[1] ?? '');
79
+ return enumerated === undefined ? undefined : { current: Number(current[1]), enumerated };
80
+ }
81
+ function parseSimcom(input) {
82
+ const current = /^\s*\+CUSBPIDSWITCH:\s*([0-9A-Fa-f]{4})\s*$/m.exec(input.currentResponse);
83
+ const enumeration = /\+CUSBPIDSWITCH:\s*\(([^)]+)\)\s*,\s*\(0-1\)\s*,\s*\(0-1\)/m.exec(input.enumerationResponse);
84
+ if (current === null || enumeration === null)
85
+ return undefined;
86
+ const tokens = (enumeration[1] ?? '').split(',').map((token) => token.trim().toUpperCase());
87
+ if (tokens.length === 0 || tokens.some((token) => !/^[0-9A-F]{4}$/.test(token)))
88
+ return undefined;
89
+ if (new Set(tokens).size !== tokens.length)
90
+ return undefined;
91
+ return { current: (current[1] ?? '').toUpperCase(), enumerated: tokens };
92
+ }
93
+ function parseSierra(input) {
94
+ const current = /^\s*!USBCOMP:\s*(\d+)(?:\s*,.*)?$/m.exec(input.currentResponse);
95
+ if (current === null)
96
+ return undefined;
97
+ const enumerated = Array.from(input.enumerationResponse.matchAll(/^\s*(\d+)\s*:\s*.+$/gm), (match) => Number(match[1]));
98
+ if (enumerated.length === 0 || new Set(enumerated).size !== enumerated.length)
99
+ return undefined;
100
+ return { current: Number(current[1]), enumerated };
101
+ }
102
+ const PARSERS = {
103
+ fibocom: parseFibocom,
104
+ quectel: parseQuectel,
105
+ simcom: parseSimcom,
106
+ sierra: parseSierra,
107
+ };
108
+ export function isRuntimeCompositionVendor(vendor) {
109
+ return Object.hasOwn(RUNTIME_COMPOSITION_QUERY_REGISTRY, vendor);
110
+ }
111
+ export function buildRuntimeCompositionSetCommand(vendor, target) {
112
+ const normalized = vendor.trim().toLowerCase();
113
+ return isRuntimeCompositionVendor(normalized)
114
+ ? RUNTIME_COMPOSITION_SET_REGISTRY[normalized](target)
115
+ : undefined;
116
+ }
117
+ /** Parse only the vendor READ response used by the weaker post-switch proof tier. */
118
+ export function readRuntimeCompositionCurrent(vendor, response) {
119
+ const normalized = vendor.trim().toLowerCase();
120
+ if (!isRuntimeCompositionVendor(normalized))
121
+ return undefined;
122
+ switch (normalized) {
123
+ case 'fibocom': {
124
+ const match = /^\s*\+GTUSBMODE:\s*(\d+)\s*$/m.exec(response);
125
+ return match === null ? undefined : Number(match[1]);
126
+ }
127
+ case 'quectel': {
128
+ const match = /^\s*\+QCFG:\s*"usbnet"\s*,\s*(\d+)\s*$/m.exec(response);
129
+ return match === null ? undefined : Number(match[1]);
130
+ }
131
+ case 'simcom': {
132
+ const match = /^\s*\+CUSBPIDSWITCH:\s*([0-9A-Fa-f]{4})\s*$/m.exec(response);
133
+ return match === null ? undefined : (match[1] ?? '').toUpperCase();
134
+ }
135
+ case 'sierra': {
136
+ const match = /^\s*!USBCOMP:\s*(\d+)(?:\s*,.*)?$/m.exec(response);
137
+ return match === null ? undefined : Number(match[1]);
138
+ }
139
+ }
140
+ }
141
+ /** Derive controls exclusively from the device's current and enumerated response text. */
142
+ export function resolveRuntimeCompositionCapability(input) {
143
+ const vendor = input.vendor.trim().toLowerCase();
144
+ if (!isRuntimeCompositionVendor(vendor))
145
+ return UNKNOWN_VENDOR;
146
+ const parsed = PARSERS[vendor](input);
147
+ if (parsed === undefined)
148
+ return MALFORMED_RESPONSE;
149
+ const returnPathProven = parsed.enumerated.includes(parsed.current);
150
+ return {
151
+ status: 'available',
152
+ current: parsed.current,
153
+ enumerated: parsed.enumerated,
154
+ returnPathProven,
155
+ offerable: returnPathProven ? parsed.enumerated : [],
156
+ };
157
+ }
@@ -0,0 +1,36 @@
1
+ /** One interface line of a `usb-devices` record. */
2
+ export interface ParsedUsbInterface {
3
+ readonly interfaceClass: number;
4
+ readonly interfaceSubClass: number;
5
+ readonly interfaceProtocol: number;
6
+ /** The bound kernel driver, omitted when `usb-devices` reports `(none)`. */
7
+ readonly driver?: string;
8
+ }
9
+ /** One device block of a `usb-devices` capture. */
10
+ export interface ParsedUsbDevice {
11
+ /** Lowercase hex `xxxx:xxxx`, exactly the catalog's `vidPid` discriminator shape. */
12
+ readonly vidPid: string;
13
+ /** The `D:` line's `Cls=` byte — the device-descriptor `bDeviceClass`. */
14
+ readonly bDeviceClass: number;
15
+ readonly manufacturer?: string;
16
+ readonly product?: string;
17
+ readonly interfaces: readonly ParsedUsbInterface[];
18
+ }
19
+ /**
20
+ * Parse `usb-devices` output into one record per device. Pure and total: malformed
21
+ * lines are skipped rather than guessed at, and a block with no `P:` line yields no
22
+ * record (it has no identity, so inventing one would be a lie).
23
+ */
24
+ export declare function parseUsbDevices(text: string): ParsedUsbDevice[];
25
+ /**
26
+ * Find the single device matching `vidPid` in a parsed capture. Returns `undefined`
27
+ * when there is NO match, and — deliberately — also when there is more than one: a
28
+ * duplicate VID:PID (this bench has two identical Huawei HiLink units) makes the
29
+ * selection ambiguous, and an ambiguous selection must refuse rather than pick the
30
+ * first. The caller turns that into a typed refusal.
31
+ */
32
+ export declare function selectUniqueDevice(devices: readonly ParsedUsbDevice[], vidPid: string): {
33
+ readonly device: ParsedUsbDevice;
34
+ } | {
35
+ readonly ambiguousMatches: number;
36
+ };
@@ -0,0 +1,157 @@
1
+ // Parsing `usb-devices` text — the ONLY per-interface descriptor source inside a
2
+ // certification bundle.
3
+ //
4
+ // A base certification bundle (`certify <slot>` with no `--transition`) carries no
5
+ // structured descriptors at all: it holds `lsusb -v` and `usb-devices` as raw text plus
6
+ // the slot's udev property map. Authoring a classifier fixture or a catalog entry from
7
+ // such a bundle therefore requires reading the descriptors back out of that text, and
8
+ // `usb-devices` is the right half to read — it is line-oriented, one fixed-width record
9
+ // per device, and it names each interface's BOUND KERNEL DRIVER, which `lsusb -v` does
10
+ // not. The driver is not optional detail here: `classifyDevice` decides `mm-managed` vs
11
+ // `router-mode` partly on `qmi_wwan` / `cdc_ether` / `option` bindings.
12
+ //
13
+ // The parser is pure and total: unparseable lines are SKIPPED, never guessed at, and a
14
+ // device that yields no interfaces still yields a record (callers decide whether an
15
+ // interface-less device is usable — this file never makes that judgement).
16
+ //
17
+ // Record shape (`usb-devices`, one blank-line-separated block per device):
18
+ // T: Bus=04 Lev=03 Prnt=03 Port=03 Cnt=01 Dev#= 7 Spd=480 MxCh= 0
19
+ // D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
20
+ // P: Vendor=2c7c ProdID=0801 Rev=05.04
21
+ // S: Manufacturer=Quectel
22
+ // S: Product=RM530N-GL
23
+ // I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
24
+ /** Read `Key=value` from a `usb-devices` line; `undefined` when the key is absent. */
25
+ function field(line, key) {
26
+ // Values are whitespace-delimited and may be preceded by padding spaces (`Dev#= 7`).
27
+ // `Cls=ff(vend.)` carries a trailing gloss, stripped by the hex/number parsers below.
28
+ const match = new RegExp(`${key}=\\s*(\\S+)`).exec(line);
29
+ return match?.[1];
30
+ }
31
+ /** Parse a hex byte field, tolerating `usb-devices`' `ff(vend.)` gloss suffix. */
32
+ function hexByte(line, key) {
33
+ const raw = field(line, key);
34
+ if (raw === undefined) {
35
+ return undefined;
36
+ }
37
+ const digits = /^[0-9a-fA-F]{1,2}/.exec(raw)?.[0];
38
+ if (digits === undefined) {
39
+ return undefined;
40
+ }
41
+ const value = Number.parseInt(digits, 16);
42
+ return Number.isNaN(value) ? undefined : value;
43
+ }
44
+ /** Parse an `S: Manufacturer=…` style line into its `[key, value]` pair. */
45
+ function stringField(line) {
46
+ const eq = line.indexOf('=');
47
+ if (eq < 0) {
48
+ return undefined;
49
+ }
50
+ const key = line.slice(3, eq).trim();
51
+ const value = line.slice(eq + 1).trim();
52
+ return key === '' || value === '' ? undefined : [key, value];
53
+ }
54
+ function emptyAccumulator() {
55
+ return { interfaces: [] };
56
+ }
57
+ function finish(acc, out) {
58
+ // A record with no `P:` line is not a device — never synthesise an identity for it.
59
+ if (acc.vidPid === undefined) {
60
+ return;
61
+ }
62
+ out.push({
63
+ vidPid: acc.vidPid,
64
+ bDeviceClass: acc.bDeviceClass ?? 0,
65
+ interfaces: acc.interfaces,
66
+ ...(acc.manufacturer !== undefined ? { manufacturer: acc.manufacturer } : {}),
67
+ ...(acc.product !== undefined ? { product: acc.product } : {}),
68
+ });
69
+ }
70
+ function applyProductLine(line, acc) {
71
+ const vendor = field(line, 'Vendor');
72
+ const product = field(line, 'ProdID');
73
+ if (vendor !== undefined && product !== undefined) {
74
+ acc.vidPid = `${vendor.toLowerCase()}:${product.toLowerCase()}`;
75
+ }
76
+ }
77
+ function applyStringLine(line, acc) {
78
+ const pair = stringField(line);
79
+ if (pair === undefined) {
80
+ return;
81
+ }
82
+ const [key, value] = pair;
83
+ if (key === 'Manufacturer') {
84
+ acc.manufacturer = value;
85
+ }
86
+ else if (key === 'Product') {
87
+ acc.product = value;
88
+ }
89
+ }
90
+ function applyInterfaceLine(line, acc) {
91
+ const interfaceClass = hexByte(line, 'Cls');
92
+ const interfaceSubClass = hexByte(line, 'Sub');
93
+ const interfaceProtocol = hexByte(line, 'Prot');
94
+ if (interfaceClass === undefined ||
95
+ interfaceSubClass === undefined ||
96
+ interfaceProtocol === undefined) {
97
+ return;
98
+ }
99
+ const driver = field(line, 'Driver');
100
+ acc.interfaces.push({
101
+ interfaceClass,
102
+ interfaceSubClass,
103
+ interfaceProtocol,
104
+ ...(driver !== undefined && driver !== '(none)' ? { driver } : {}),
105
+ });
106
+ }
107
+ /**
108
+ * Parse `usb-devices` output into one record per device. Pure and total: malformed
109
+ * lines are skipped rather than guessed at, and a block with no `P:` line yields no
110
+ * record (it has no identity, so inventing one would be a lie).
111
+ */
112
+ export function parseUsbDevices(text) {
113
+ const out = [];
114
+ let acc = emptyAccumulator();
115
+ for (const line of text.split('\n')) {
116
+ // A `T:` line opens a new device record; `usb-devices` also blank-line-separates
117
+ // them, but the topology line is the reliable delimiter (blank lines are optional
118
+ // in some kernels' output).
119
+ if (line.startsWith('T:')) {
120
+ finish(acc, out);
121
+ acc = emptyAccumulator();
122
+ continue;
123
+ }
124
+ if (line.startsWith('D:')) {
125
+ const deviceClass = hexByte(line, 'Cls');
126
+ if (deviceClass !== undefined) {
127
+ acc.bDeviceClass = deviceClass;
128
+ }
129
+ }
130
+ else if (line.startsWith('P:')) {
131
+ applyProductLine(line, acc);
132
+ }
133
+ else if (line.startsWith('S:')) {
134
+ applyStringLine(line, acc);
135
+ }
136
+ else if (line.startsWith('I:')) {
137
+ applyInterfaceLine(line, acc);
138
+ }
139
+ }
140
+ finish(acc, out);
141
+ return out;
142
+ }
143
+ /**
144
+ * Find the single device matching `vidPid` in a parsed capture. Returns `undefined`
145
+ * when there is NO match, and — deliberately — also when there is more than one: a
146
+ * duplicate VID:PID (this bench has two identical Huawei HiLink units) makes the
147
+ * selection ambiguous, and an ambiguous selection must refuse rather than pick the
148
+ * first. The caller turns that into a typed refusal.
149
+ */
150
+ export function selectUniqueDevice(devices, vidPid) {
151
+ const matches = devices.filter((d) => d.vidPid === vidPid);
152
+ const only = matches[0];
153
+ if (matches.length === 1 && only !== undefined) {
154
+ return { device: only };
155
+ }
156
+ return { ambiguousMatches: matches.length };
157
+ }
@@ -0,0 +1,32 @@
1
+ import type { DbusTransport } from '../transport/index.js';
2
+ import type { UssdRepliedState } from './session.js';
3
+ /** `MMModem3gppUssdSessionState`. */
4
+ export declare const USSD_STATE_UNKNOWN = 0;
5
+ export declare const USSD_STATE_IDLE = 1;
6
+ export declare const USSD_STATE_ACTIVE = 2;
7
+ export declare const USSD_STATE_USER_RESPONSE = 3;
8
+ /**
9
+ * Decode MM's post-call session state. `UNKNOWN` folds onto `released` with the
10
+ * rest: an unreadable state must close the session rather than leave the operator
11
+ * looking at a dialogue nothing can advance.
12
+ */
13
+ export declare function decodeRepliedState(state: number): UssdRepliedState;
14
+ export interface UssdCallTarget {
15
+ readonly transport: DbusTransport;
16
+ readonly destination: string;
17
+ readonly modem: string;
18
+ readonly timeoutMs: number;
19
+ }
20
+ export declare function callInitiate(target: UssdCallTarget, ussdCommand: string): Promise<string>;
21
+ export declare function callRespond(target: UssdCallTarget, ussdResponse: string): Promise<string>;
22
+ export declare function callCancel(target: UssdCallTarget): Promise<void>;
23
+ /**
24
+ * Read the post-call session state.
25
+ *
26
+ * A targeted `Properties.Get` rather than a `GetManagedObjects` sweep: this runs
27
+ * after every network round-trip, and the whole-tree read is the most expensive
28
+ * call in the package. `unknown` on anything unreadable — the caller treats that
29
+ * as "the network released the session", which is the conservative direction (it
30
+ * closes a session rather than leaving one the operator cannot see).
31
+ */
32
+ export declare function readUssdState(target: UssdCallTarget): Promise<number>;
@@ -0,0 +1,96 @@
1
+ // The four D-Bus calls the USSD adapter makes, and nothing else.
2
+ //
3
+ // Split from the adapter so the session machinery above can be read without the
4
+ // marshalling below, and so a call's shape (interface, member, signature) is
5
+ // stated once in one place.
6
+ //
7
+ // CARRIER TEXT DISCIPLINE: `Initiate` and `Respond` both take and return operator
8
+ // text, and neither the command nor the reply may ever reach a log line. Nothing
9
+ // in this file logs, and every error raised here is re-thrown untouched so the
10
+ // classifier — not a string built around the payload — decides what the caller is
11
+ // told.
12
+ import { MODEM3GPP_USSD_IFACE, PROPERTIES_IFACE } from '../backend/constants.js';
13
+ /** `MMModem3gppUssdSessionState`. */
14
+ export const USSD_STATE_UNKNOWN = 0;
15
+ export const USSD_STATE_IDLE = 1;
16
+ export const USSD_STATE_ACTIVE = 2;
17
+ export const USSD_STATE_USER_RESPONSE = 3;
18
+ /**
19
+ * Decode MM's post-call session state. `UNKNOWN` folds onto `released` with the
20
+ * rest: an unreadable state must close the session rather than leave the operator
21
+ * looking at a dialogue nothing can advance.
22
+ */
23
+ export function decodeRepliedState(state) {
24
+ if (state === USSD_STATE_USER_RESPONSE) {
25
+ return 'awaiting-reply';
26
+ }
27
+ return state === USSD_STATE_ACTIVE ? 'active' : 'released';
28
+ }
29
+ function firstString(body) {
30
+ const value = body[0];
31
+ return typeof value === 'string' ? value : '';
32
+ }
33
+ export async function callInitiate(target, ussdCommand) {
34
+ const reply = await target.transport.callMethod({
35
+ destination: target.destination,
36
+ path: target.modem,
37
+ interface: MODEM3GPP_USSD_IFACE,
38
+ member: 'Initiate',
39
+ signature: 's',
40
+ args: [ussdCommand],
41
+ timeoutMs: target.timeoutMs,
42
+ });
43
+ return firstString(reply.body);
44
+ }
45
+ export async function callRespond(target, ussdResponse) {
46
+ const reply = await target.transport.callMethod({
47
+ destination: target.destination,
48
+ path: target.modem,
49
+ interface: MODEM3GPP_USSD_IFACE,
50
+ member: 'Respond',
51
+ signature: 's',
52
+ args: [ussdResponse],
53
+ timeoutMs: target.timeoutMs,
54
+ });
55
+ return firstString(reply.body);
56
+ }
57
+ export async function callCancel(target) {
58
+ await target.transport.callMethod({
59
+ destination: target.destination,
60
+ path: target.modem,
61
+ interface: MODEM3GPP_USSD_IFACE,
62
+ member: 'Cancel',
63
+ timeoutMs: target.timeoutMs,
64
+ });
65
+ }
66
+ /**
67
+ * Read the post-call session state.
68
+ *
69
+ * A targeted `Properties.Get` rather than a `GetManagedObjects` sweep: this runs
70
+ * after every network round-trip, and the whole-tree read is the most expensive
71
+ * call in the package. `unknown` on anything unreadable — the caller treats that
72
+ * as "the network released the session", which is the conservative direction (it
73
+ * closes a session rather than leaving one the operator cannot see).
74
+ */
75
+ export async function readUssdState(target) {
76
+ try {
77
+ const reply = await target.transport.callMethod({
78
+ destination: target.destination,
79
+ path: target.modem,
80
+ interface: PROPERTIES_IFACE,
81
+ member: 'Get',
82
+ signature: 'ss',
83
+ args: [MODEM3GPP_USSD_IFACE, 'State'],
84
+ timeoutMs: target.timeoutMs,
85
+ });
86
+ const wrapped = reply.body[0];
87
+ if (typeof wrapped === 'number') {
88
+ return wrapped;
89
+ }
90
+ const inner = wrapped?.value;
91
+ return typeof inner === 'number' ? inner : USSD_STATE_UNKNOWN;
92
+ }
93
+ catch {
94
+ return USSD_STATE_UNKNOWN;
95
+ }
96
+ }
@@ -0,0 +1,5 @@
1
+ export { callCancel, callInitiate, callRespond, decodeRepliedState, readUssdState, USSD_STATE_ACTIVE, USSD_STATE_IDLE, USSD_STATE_UNKNOWN, USSD_STATE_USER_RESPONSE, type UssdCallTarget, } from './calls.js';
2
+ export { MmUssd, type MmUssdDeps, type UssdScheduler, type UssdTimerHandle, type UssdVerbResult, } from './mm-ussd.js';
3
+ export { classifyUssdFailure, isPacketSwitchedOnly, USSD_REFUSAL_REASONS, type UssdRefusalReason, type UssdRegistrationFacts, } from './refusal.js';
4
+ export { decodeAccessTechnologies, readUssdRegistrationFacts, registrationFactsFromTree, UNKNOWN_REGISTRATION, } from './registration.js';
5
+ export { IDLE_SESSION, isUssdSessionOpen, reduceUssdSession, USSD_SESSION_OUTCOMES, USSD_SESSION_STATES, type UssdRepliedState, type UssdSessionEvent, type UssdSessionOutcome, type UssdSessionSnapshot, type UssdSessionState, type UssdTransition, } from './session.js';
@@ -0,0 +1,12 @@
1
+ // The gated USSD capability module — session state machine, refusal taxonomy, and
2
+ // the ModemManager `Modem3gpp.Ussd` adapter.
3
+ //
4
+ // GATED: nothing here runs unless the operator has enabled the `ussd` capability
5
+ // module and the modem positively advertises the interface (`../capability`).
6
+ // LEASE-ONLY: a USSD session cannot re-register the radio, so it takes the
7
+ // per-modem mutation lease and is NOT journaled.
8
+ export { callCancel, callInitiate, callRespond, decodeRepliedState, readUssdState, USSD_STATE_ACTIVE, USSD_STATE_IDLE, USSD_STATE_UNKNOWN, USSD_STATE_USER_RESPONSE, } from './calls.js';
9
+ export { MmUssd, } from './mm-ussd.js';
10
+ export { classifyUssdFailure, isPacketSwitchedOnly, USSD_REFUSAL_REASONS, } from './refusal.js';
11
+ export { decodeAccessTechnologies, readUssdRegistrationFacts, registrationFactsFromTree, UNKNOWN_REGISTRATION, } from './registration.js';
12
+ export { IDLE_SESSION, isUssdSessionOpen, reduceUssdSession, USSD_SESSION_OUTCOMES, USSD_SESSION_STATES, } from './session.js';
@@ -0,0 +1,37 @@
1
+ import type { ModemActor } from '../backend/modem-actor.js';
2
+ import type { ModemRef } from '../ports/index.js';
3
+ import type { DbusTransport } from '../transport/index.js';
4
+ import { type UssdRefusalReason } from './refusal.js';
5
+ import { type UssdSessionSnapshot } from './session.js';
6
+ export interface UssdTimerHandle {
7
+ cancel(): void;
8
+ }
9
+ export type UssdScheduler = (delayMs: number, run: () => void) => UssdTimerHandle;
10
+ export interface UssdVerbResult {
11
+ readonly ok: boolean;
12
+ readonly snapshot: UssdSessionSnapshot;
13
+ /** Carrier text. Redacted by key everywhere it is serialized. */
14
+ readonly ussdReply?: string;
15
+ readonly refusal?: UssdRefusalReason;
16
+ }
17
+ export interface MmUssdDeps {
18
+ readonly transport: DbusTransport;
19
+ readonly actor: ModemActor;
20
+ readonly destination?: string;
21
+ readonly resolveStableKey: (modem: ModemRef) => string;
22
+ readonly callTimeoutMs?: number;
23
+ readonly sessionIdleTimeoutMs?: number;
24
+ readonly scheduler?: UssdScheduler;
25
+ /** Notified on every stored-state change, so a UI can follow a session. */
26
+ readonly onSessionChange?: (stableKey: string, snapshot: UssdSessionSnapshot) => void;
27
+ }
28
+ export declare class MmUssd {
29
+ #private;
30
+ constructor(deps: MmUssdDeps);
31
+ snapshot(modem: ModemRef): UssdSessionSnapshot;
32
+ initiate(modem: ModemRef, ussdCommand: string): Promise<UssdVerbResult>;
33
+ respond(modem: ModemRef, ussdResponse: string): Promise<UssdVerbResult>;
34
+ cancel(modem: ModemRef): Promise<UssdVerbResult>;
35
+ /** Drop every timer. A live session on the modem is NOT cancelled by this. */
36
+ stop(): void;
37
+ }