@mentra/bluetooth-sdk 0.1.21-beta.5 → 3.1.0-beta.103

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 (140) hide show
  1. package/README.md +67 -25
  2. package/android/build.gradle +7 -4
  3. package/android/lc3Lib/build.gradle +18 -4
  4. package/android/silero/build.gradle +9 -1
  5. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +16 -0
  6. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +35 -4
  7. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +205 -19
  8. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +2 -0
  9. package/android/src/main/java/com/mentra/bluetoothsdk/GeneratedChangelogCatalog.kt +7 -0
  10. package/android/src/main/java/com/mentra/bluetoothsdk/GeneratedReleaseMetadata.kt +11 -0
  11. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +127 -8
  12. package/android/src/main/java/com/mentra/bluetoothsdk/MentraLocalNetworkModule.kt +93 -12
  13. package/android/src/main/java/com/mentra/bluetoothsdk/OtaManifest.kt +5 -7
  14. package/android/src/main/java/com/mentra/bluetoothsdk/ReleaseChangelog.kt +61 -0
  15. package/android/src/main/java/com/mentra/bluetoothsdk/ScopedNetworkReadiness.kt +17 -0
  16. package/android/src/main/java/com/mentra/bluetoothsdk/audio/AudioModels.kt +15 -0
  17. package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +24 -0
  18. package/android/src/main/java/com/mentra/bluetoothsdk/net/LocalIpv4.kt +57 -0
  19. package/android/src/main/java/com/mentra/bluetoothsdk/otaserver/LocalOtaServer.kt +304 -0
  20. package/android/src/main/java/com/mentra/bluetoothsdk/otaserver/MentraOtaServerModule.kt +120 -0
  21. package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/MentraPhotoReceiverModule.kt +2 -49
  22. package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +61 -30
  23. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +1186 -191
  24. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLivePairingAdvertisement.kt +54 -0
  25. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +8 -0
  26. package/android/src/main/java/com/mentra/bluetoothsdk/status/DeviceStatus.kt +17 -0
  27. package/android/src/main/java/com/mentra/bluetoothsdk/types/DeviceModels.kt +12 -0
  28. package/android/src/main/java/com/mentra/bluetoothsdk/utils/BleJsonCompact.java +74 -79
  29. package/android/src/main/java/com/mentra/bluetoothsdk/utils/K900ProtocolUtils.java +3 -3
  30. package/android/src/test/java/com/mentra/bluetoothsdk/OtaStartResponsePolicyTest.kt +30 -0
  31. package/android/src/test/java/com/mentra/bluetoothsdk/ReleaseChangelogTest.kt +13 -0
  32. package/android/src/test/java/com/mentra/bluetoothsdk/ScopedNetworkReadinessTest.kt +39 -0
  33. package/android/src/test/java/com/mentra/bluetoothsdk/otaserver/LocalOtaServerTest.kt +82 -0
  34. package/android/src/test/java/com/mentra/bluetoothsdk/services/ForegroundServiceTypeTest.kt +69 -0
  35. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/MentraLiveGattCharacteristicsTest.kt +39 -0
  36. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/MentraLivePairingAdvertisementParserTest.kt +133 -0
  37. package/android/src/test/java/com/mentra/bluetoothsdk/utils/BleJsonCompactTest.java +148 -7
  38. package/build/BluetoothSdk.types.d.ts +82 -2
  39. package/build/BluetoothSdk.types.d.ts.map +1 -1
  40. package/build/BluetoothSdk.types.js.map +1 -1
  41. package/build/_internal.d.ts +2 -0
  42. package/build/_internal.d.ts.map +1 -1
  43. package/build/_internal.js +2 -0
  44. package/build/_internal.js.map +1 -1
  45. package/build/_private/BluetoothSdkModule.d.ts +4 -1
  46. package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
  47. package/build/_private/BluetoothSdkModule.js +1 -1
  48. package/build/_private/BluetoothSdkModule.js.map +1 -1
  49. package/build/_private/MentraLocalNetworkModule.d.ts +1 -0
  50. package/build/_private/MentraLocalNetworkModule.d.ts.map +1 -1
  51. package/build/_private/MentraLocalNetworkModule.js.map +1 -1
  52. package/build/_private/sdkOtaManifest.d.ts +3 -12
  53. package/build/_private/sdkOtaManifest.d.ts.map +1 -1
  54. package/build/_private/sdkOtaManifest.js +5 -17
  55. package/build/_private/sdkOtaManifest.js.map +1 -1
  56. package/build/changelogs.d.ts +7 -0
  57. package/build/changelogs.d.ts.map +1 -0
  58. package/build/changelogs.js +44 -0
  59. package/build/changelogs.js.map +1 -0
  60. package/build/generated/changelogCatalog.d.ts +6 -0
  61. package/build/generated/changelogCatalog.d.ts.map +1 -0
  62. package/build/generated/changelogCatalog.js +8 -0
  63. package/build/generated/changelogCatalog.js.map +1 -0
  64. package/build/generated/releaseMetadata.d.ts +12 -0
  65. package/build/generated/releaseMetadata.d.ts.map +1 -0
  66. package/build/generated/releaseMetadata.js +10 -0
  67. package/build/generated/releaseMetadata.js.map +1 -0
  68. package/build/index.d.ts +1 -1
  69. package/build/index.d.ts.map +1 -1
  70. package/build/index.js +24 -2
  71. package/build/index.js.map +1 -1
  72. package/build/ota-server/MentraOtaServer.types.d.ts +14 -0
  73. package/build/ota-server/MentraOtaServer.types.d.ts.map +1 -0
  74. package/build/ota-server/MentraOtaServer.types.js +2 -0
  75. package/build/ota-server/MentraOtaServer.types.js.map +1 -0
  76. package/build/ota-server/MentraOtaServerModule.d.ts +21 -0
  77. package/build/ota-server/MentraOtaServerModule.d.ts.map +1 -0
  78. package/build/ota-server/MentraOtaServerModule.js +3 -0
  79. package/build/ota-server/MentraOtaServerModule.js.map +1 -0
  80. package/build/ota-server/MentraOtaServerModule.web.d.ts +10 -0
  81. package/build/ota-server/MentraOtaServerModule.web.d.ts.map +1 -0
  82. package/build/ota-server/MentraOtaServerModule.web.js +12 -0
  83. package/build/ota-server/MentraOtaServerModule.web.js.map +1 -0
  84. package/build/ota-server/index.d.ts +3 -0
  85. package/build/ota-server/index.d.ts.map +1 -0
  86. package/build/ota-server/index.js +3 -0
  87. package/build/ota-server/index.js.map +1 -0
  88. package/build/ota-transport/index.d.ts +67 -0
  89. package/build/ota-transport/index.d.ts.map +1 -0
  90. package/build/ota-transport/index.js +58 -0
  91. package/build/ota-transport/index.js.map +1 -0
  92. package/expo-module.config.json +3 -2
  93. package/ios/BackgroundOtaArtifactDownloader.swift +125 -0
  94. package/ios/BluetoothSdkModule.swift +16 -2
  95. package/ios/LocalIPv4.swift +150 -0
  96. package/ios/LocalOtaServer.swift +309 -0
  97. package/ios/MentraBluetoothSDK.podspec +5 -1
  98. package/ios/MentraOtaServerModule.swift +147 -0
  99. package/ios/MentraPhotoReceiverModule.swift +1 -81
  100. package/ios/Source/BluetoothSdkDefaults.swift +4 -1
  101. package/ios/Source/Bridge.swift +43 -4
  102. package/ios/Source/DeviceManager.swift +143 -13
  103. package/ios/Source/DeviceStore.swift +2 -0
  104. package/ios/Source/GeneratedChangelogCatalog.swift +6 -0
  105. package/ios/Source/GeneratedReleaseMetadata.swift +11 -0
  106. package/ios/Source/MentraBluetoothSDK.swift +91 -6
  107. package/ios/Source/OtaManifest.swift +5 -7
  108. package/ios/Source/ReleaseChangelog.swift +65 -0
  109. package/ios/Source/audio/AudioModels.swift +17 -0
  110. package/ios/Source/camera/CameraModels.swift +1 -0
  111. package/ios/Source/events/BluetoothEvents.swift +27 -0
  112. package/ios/Source/sgcs/MentraLive.swift +453 -31
  113. package/ios/Source/sgcs/MentraLivePairingAdvertisement.swift +64 -0
  114. package/ios/Source/sgcs/SGCManager.swift +11 -0
  115. package/ios/Source/status/DeviceStatus.swift +23 -0
  116. package/ios/Source/types/DeviceModels.swift +23 -2
  117. package/ios/Source/utils/BleJsonCompact.swift +73 -71
  118. package/ios/Tests/MentraLivePairingAdvertisementTests.swift +160 -0
  119. package/ios/Tests/ReleaseChangelogTests.swift +13 -0
  120. package/package.json +10 -1
  121. package/plugin/build/withIos.d.ts +3 -1
  122. package/plugin/build/withIos.js +22 -10
  123. package/scripts/public-ota-api.test.mjs +37 -0
  124. package/scripts/verify-release-package.mjs +34 -0
  125. package/scripts/write-release-metadata.mjs +154 -0
  126. package/scripts/write-release-metadata.test.mjs +29 -0
  127. package/src/BluetoothSdk.types.ts +95 -3
  128. package/src/_internal.ts +2 -0
  129. package/src/_private/BluetoothSdkModule.ts +5 -5
  130. package/src/_private/MentraLocalNetworkModule.ts +1 -1
  131. package/src/_private/sdkOtaManifest.ts +5 -17
  132. package/src/changelogs.ts +44 -0
  133. package/src/generated/changelogCatalog.ts +9 -0
  134. package/src/generated/releaseMetadata.ts +20 -0
  135. package/src/index.ts +43 -2
  136. package/src/ota-server/MentraOtaServer.types.ts +10 -0
  137. package/src/ota-server/MentraOtaServerModule.ts +23 -0
  138. package/src/ota-server/MentraOtaServerModule.web.ts +17 -0
  139. package/src/ota-server/index.ts +2 -0
  140. package/src/ota-transport/index.ts +116 -0
package/build/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import PrivateBluetoothSdkModule from "./_private/BluetoothSdkModule";
2
+ import { getReleaseChangelogs } from "./changelogs";
2
3
  const PUBLIC_EVENT_NAMES = new Set([
3
4
  "log",
4
5
  "device_discovered",
@@ -29,12 +30,18 @@ const PUBLIC_EVENT_NAMES = new Set([
29
30
  "rgb_led_control_response",
30
31
  "settings_ack",
31
32
  "pair_failure",
33
+ "pairing_info",
34
+ "entering_pairing_mode",
35
+ "owner_replaced",
32
36
  "audio_pairing_needed",
33
37
  "audio_connected",
34
38
  "audio_disconnected",
35
39
  "mic_pcm",
36
40
  "mic_lc3",
41
+ "mic_health",
37
42
  "stream_status",
43
+ "mtk_update_complete",
44
+ "glasses_session_changed",
38
45
  "ota_start_ack",
39
46
  "ota_status",
40
47
  "ar99_ota_status",
@@ -47,8 +54,11 @@ const addListener = (eventName, listener) => {
47
54
  }
48
55
  return PrivateBluetoothSdkModule.addListener(eventName, listener);
49
56
  };
50
- const startOtaUpdate = () => {
51
- return PrivateBluetoothSdkModule.startOtaUpdate();
57
+ const startOtaUpdate = (otaVersionUrl) => {
58
+ return PrivateBluetoothSdkModule.startOtaUpdate(otaVersionUrl);
59
+ };
60
+ const queryOtaStatus = () => {
61
+ return PrivateBluetoothSdkModule.sendOtaQueryStatus();
52
62
  };
53
63
  const bindPublicMethod = (name) => {
54
64
  const method = PrivateBluetoothSdkModule[name];
@@ -61,6 +71,10 @@ const bindPublicMethod = (name) => {
61
71
  };
62
72
  export const BluetoothSdk = Object.freeze({
63
73
  addListener,
74
+ getGlassesStatus: bindPublicMethod("getGlassesStatus"),
75
+ getBluetoothStatus: bindPublicMethod("getBluetoothStatus"),
76
+ subscribeGlassesStatus: (listener) => PrivateBluetoothSdkModule.onGlassesStatus(listener),
77
+ subscribeBluetoothStatus: (listener) => PrivateBluetoothSdkModule.onBluetoothStatus(listener),
64
78
  getDefaultDevice: bindPublicMethod("getDefaultDevice"),
65
79
  setDefaultDevice: bindPublicMethod("setDefaultDevice"),
66
80
  clearDefaultDevice: bindPublicMethod("clearDefaultDevice"),
@@ -79,10 +93,13 @@ export const BluetoothSdk = Object.freeze({
79
93
  setHeadUpAngle: bindPublicMethod("setHeadUpAngle"),
80
94
  setImuEnabled: bindPublicMethod("setImuEnabled"),
81
95
  setScreenDisabled: bindPublicMethod("setScreenDisabled"),
96
+ ping: bindPublicMethod("ping"),
82
97
  requestWifiScan: bindPublicMethod("requestWifiScan"),
83
98
  sendWifiCredentials: bindPublicMethod("sendWifiCredentials"),
84
99
  forgetWifiNetwork: bindPublicMethod("forgetWifiNetwork"),
85
100
  setHotspotState: bindPublicMethod("setHotspotState"),
101
+ setSystemTime: bindPublicMethod("setSystemTime"),
102
+ setWifiAdbState: bindPublicMethod("setWifiAdbState"),
86
103
  setGalleryModeEnabled: bindPublicMethod("setGalleryModeEnabled"),
87
104
  setVoiceActivityDetectionEnabled: bindPublicMethod("setVoiceActivityDetectionEnabled"),
88
105
  setLoudnessGateEnabled: bindPublicMethod("setLoudnessGateEnabled"),
@@ -111,6 +128,7 @@ export const BluetoothSdk = Object.freeze({
111
128
  stopCameraWarmUp: bindPublicMethod("stopCameraWarmUp"),
112
129
  startVideoRecording: bindPublicMethod("startVideoRecording"),
113
130
  stopVideoRecording: bindPublicMethod("stopVideoRecording"),
131
+ queryVideoRecordingStatus: bindPublicMethod("queryVideoRecordingStatus"),
114
132
  startStream: bindPublicMethod("startStream"),
115
133
  stopStream: bindPublicMethod("stopStream"),
116
134
  setMicState: bindPublicMethod("setMicState"),
@@ -120,8 +138,12 @@ export const BluetoothSdk = Object.freeze({
120
138
  setGlassesMediaVolume: bindPublicMethod("setGlassesMediaVolume"),
121
139
  rgbLedControl: bindPublicMethod("rgbLedControl"),
122
140
  requestVersionInfo: bindPublicMethod("requestVersionInfo"),
141
+ setOtaVersionUrl: bindPublicMethod("setOtaVersionUrl"),
142
+ getOtaVersionUrl: bindPublicMethod("getOtaVersionUrl"),
123
143
  checkForOtaUpdate: bindPublicMethod("checkForOtaUpdate"),
144
+ getReleaseChangelogs,
124
145
  startOtaUpdate,
146
+ queryOtaStatus,
125
147
  startAr99OtaFromFile: bindPublicMethod("startAr99OtaFromFile"),
126
148
  cancelAr99Ota: bindPublicMethod("cancelAr99Ota"),
127
149
  sendAr99FactoryReset: bindPublicMethod("sendAr99FactoryReset"),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import PrivateBluetoothSdkModule from \"./_private/BluetoothSdkModule\"\nimport type {\n BluetoothSdkEventListener,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule,\n VideoRecordingDefaults,\n} from \"./BluetoothSdk.types\"\n\nconst PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([\n \"log\",\n \"device_discovered\",\n \"default_device_changed\",\n \"glasses_not_ready\",\n \"button_press\",\n \"touch_event\",\n \"accel_event\",\n \"head_up\",\n \"voice_activity_detection_status\",\n \"speaking_status\",\n \"battery_status\",\n \"local_transcription\",\n \"wifi_status_change\",\n \"wifi_scan_result\",\n \"hotspot_status_change\",\n \"hotspot_error\",\n \"photo_response\",\n \"photo_status\",\n \"camera_status\",\n \"video_recording_status\",\n \"media_success\",\n \"media_error\",\n \"gallery_status\",\n \"compatible_glasses_search_stop\",\n \"swipe_volume_status\",\n \"switch_status\",\n \"rgb_led_control_response\",\n \"settings_ack\",\n \"pair_failure\",\n \"audio_pairing_needed\",\n \"audio_connected\",\n \"audio_disconnected\",\n \"mic_pcm\",\n \"mic_lc3\",\n \"stream_status\",\n \"ota_start_ack\",\n \"ota_status\",\n \"ar99_ota_status\",\n \"version_info\",\n \"extraction_progress\",\n])\n\nconst addListener: BluetoothSdkPublicModule[\"addListener\"] = (eventName, listener) => {\n if (!PUBLIC_EVENT_NAMES.has(eventName)) {\n throw new Error(`Unsupported BluetoothSdk event \"${eventName}\". Use @mentra/bluetooth-sdk/react for status state.`)\n }\n return PrivateBluetoothSdkModule.addListener(eventName, listener as BluetoothSdkEventListener<BluetoothSdkEventName>)\n}\n\nconst startOtaUpdate: BluetoothSdkPublicModule[\"startOtaUpdate\"] = () => {\n return PrivateBluetoothSdkModule.startOtaUpdate()\n}\n\nconst bindPublicMethod = <K extends keyof BluetoothSdkPublicModule>(name: K): BluetoothSdkPublicModule[K] => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>)[name]\n if (typeof method === \"function\") {\n return method.bind(PrivateBluetoothSdkModule) as BluetoothSdkPublicModule[K]\n }\n\n return (async () => {\n throw new Error(`BluetoothSdk.${String(name)} is not available in this native build. Rebuild the app.`)\n }) as unknown as BluetoothSdkPublicModule[K]\n}\n\nexport const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({\n addListener,\n getDefaultDevice: bindPublicMethod(\"getDefaultDevice\"),\n setDefaultDevice: bindPublicMethod(\"setDefaultDevice\"),\n clearDefaultDevice: bindPublicMethod(\"clearDefaultDevice\"),\n startScan: bindPublicMethod(\"startScan\"),\n stopScan: bindPublicMethod(\"stopScan\"),\n scan: bindPublicMethod(\"scan\") as BluetoothSdkPublicModule[\"scan\"],\n connect: bindPublicMethod(\"connect\"),\n connectDefault: bindPublicMethod(\"connectDefault\"),\n cancelConnectionAttempt: bindPublicMethod(\"cancelConnectionAttempt\"),\n disconnect: bindPublicMethod(\"disconnect\"),\n forget: bindPublicMethod(\"forget\"),\n displayText: bindPublicMethod(\"displayText\"),\n clearDisplay: bindPublicMethod(\"clearDisplay\"),\n showDashboard: bindPublicMethod(\"showDashboard\"),\n setDashboardPosition: bindPublicMethod(\"setDashboardPosition\"),\n setHeadUpAngle: bindPublicMethod(\"setHeadUpAngle\"),\n setImuEnabled: bindPublicMethod(\"setImuEnabled\"),\n setScreenDisabled: bindPublicMethod(\"setScreenDisabled\"),\n requestWifiScan: bindPublicMethod(\"requestWifiScan\"),\n sendWifiCredentials: bindPublicMethod(\"sendWifiCredentials\"),\n forgetWifiNetwork: bindPublicMethod(\"forgetWifiNetwork\"),\n setHotspotState: bindPublicMethod(\"setHotspotState\"),\n setGalleryModeEnabled: bindPublicMethod(\"setGalleryModeEnabled\"),\n setVoiceActivityDetectionEnabled: bindPublicMethod(\"setVoiceActivityDetectionEnabled\"),\n setLoudnessGateEnabled: bindPublicMethod(\"setLoudnessGateEnabled\"),\n /**\n * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request\n * `requestPhoto(...)` options (e.g. `mode: \"text\"` for text sensor size/crop, or explicit per-shot\n * fields). Still functional until removed in a future release.\n */\n setPhotoCaptureDefaults: bindPublicMethod(\"setPhotoCaptureDefaults\"),\n setVideoRecordingDefaults: ({width, height, fps}: VideoRecordingDefaults) => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>).setVideoRecordingDefaults\n if (typeof method !== \"function\") {\n return Promise.reject(\n new Error(\"BluetoothSdk.setVideoRecordingDefaults is not available in this native build. Rebuild the app.\"),\n )\n }\n return PrivateBluetoothSdkModule.setVideoRecordingDefaults(width, height, fps)\n },\n setMaxVideoRecordingDuration: bindPublicMethod(\"setMaxVideoRecordingDuration\"),\n setCameraFov: bindPublicMethod(\"setCameraFov\"),\n setLegacyCameraFov: bindPublicMethod(\"setLegacyCameraFov\"),\n setCameraFovOverride: bindPublicMethod(\"setCameraFovOverride\"),\n releaseCameraFovOverride: bindPublicMethod(\"releaseCameraFovOverride\"),\n setCameraTuningConfig: bindPublicMethod(\"setCameraTuningConfig\"),\n queryGalleryStatus: bindPublicMethod(\"queryGalleryStatus\"),\n requestPhoto: bindPublicMethod(\"requestPhoto\"),\n warmUpCamera: bindPublicMethod(\"warmUpCamera\"),\n stopCameraWarmUp: bindPublicMethod(\"stopCameraWarmUp\"),\n startVideoRecording: bindPublicMethod(\"startVideoRecording\"),\n stopVideoRecording: bindPublicMethod(\"stopVideoRecording\"),\n startStream: bindPublicMethod(\"startStream\"),\n stopStream: bindPublicMethod(\"stopStream\"),\n setMicState: bindPublicMethod(\"setMicState\"),\n setPreferredMic: bindPublicMethod(\"setPreferredMic\"),\n setOwnAppAudioPlaying: bindPublicMethod(\"setOwnAppAudioPlaying\"),\n getGlassesMediaVolume: bindPublicMethod(\"getGlassesMediaVolume\"),\n setGlassesMediaVolume: bindPublicMethod(\"setGlassesMediaVolume\"),\n rgbLedControl: bindPublicMethod(\"rgbLedControl\"),\n requestVersionInfo: bindPublicMethod(\"requestVersionInfo\"),\n checkForOtaUpdate: bindPublicMethod(\"checkForOtaUpdate\"),\n startOtaUpdate,\n startAr99OtaFromFile: bindPublicMethod(\"startAr99OtaFromFile\"),\n cancelAr99Ota: bindPublicMethod(\"cancelAr99Ota\"),\n sendAr99FactoryReset: bindPublicMethod(\"sendAr99FactoryReset\"),\n buildAr99OtaSignature: bindPublicMethod(\"buildAr99OtaSignature\"),\n setSttModelDetails: bindPublicMethod(\"setSttModelDetails\"),\n getSttModelPath: bindPublicMethod(\"getSttModelPath\"),\n checkSttModelAvailable: bindPublicMethod(\"checkSttModelAvailable\"),\n validateSttModel: bindPublicMethod(\"validateSttModel\"),\n extractTarBz2: bindPublicMethod(\"extractTarBz2\"),\n restartTranscriber: bindPublicMethod(\"restartTranscriber\"),\n setTtsModelDetails: bindPublicMethod(\"setTtsModelDetails\"),\n getTtsModelPath: bindPublicMethod(\"getTtsModelPath\"),\n getTtsModelLanguage: bindPublicMethod(\"getTtsModelLanguage\"),\n checkTtsModelAvailable: bindPublicMethod(\"checkTtsModelAvailable\"),\n validateTtsModel: bindPublicMethod(\"validateTtsModel\"),\n generateTtsAudio: bindPublicMethod(\"generateTtsAudio\"),\n})\n\nexport default BluetoothSdk\n\nexport {\n CAMERA_FOV_DEFAULT,\n CAMERA_FOV_MAX,\n CAMERA_FOV_MIN,\n DeviceModels,\n isBusyGlassesConnectionStatus,\n isConnectedGlassesConnectionStatus,\n isConnectedWifiStatus,\n isEnabledHotspotStatus,\n isReadyGlassesConnectionStatus,\n} from \"./BluetoothSdk.types\"\n\nexport type {\n AccelEvent,\n Ar99OtaStatusEvent,\n AudioConnectedEvent,\n AudioDisconnectedEvent,\n AudioPairingNeededEvent,\n BatteryStatusEvent,\n BluetoothSdkEvent,\n BluetoothSdkEventListener,\n BluetoothSdkEventMap,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule as BluetoothSdkModule,\n BluetoothSdkSubscription,\n ButtonPhotoSize,\n PhotoCaptureDefaults,\n ButtonPressEvent,\n CameraFovPreset,\n CameraFovRequest,\n CameraFovResult,\n CameraRoiPosition,\n CompatibleGlassesSearchStopEvent,\n ConnectOptions,\n ConnectedGlassesConnectionStatus,\n ConnectedWifiStatus,\n Device,\n DeviceModel,\n EnabledHotspotStatus,\n GalleryStatusEvent,\n GlassesConnectionStatus,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesNotReadyEvent,\n HeadUpEvent,\n HotspotErrorEvent,\n HotspotStatus,\n HotspotStatusChangeEvent,\n LocalTranscriptionEvent,\n LogEvent,\n MicLc3Event,\n MicMode,\n MicPcmEvent,\n MicPreference,\n OtaStartAckEvent,\n OtaStatus,\n OtaStatusEvent,\n OtaQueryResult,\n PairFailureEvent,\n PhotoCaptureMetadata,\n PhotoResolvedConfig,\n PhotoCompression,\n PhotoFpsRange,\n PhotoMeteredPreview,\n PhotoMode,\n PhotoTransferMethod,\n PhotoResponseEvent,\n PhotoRequestedCaptureConfig,\n PhotoRequestParams,\n PhotoSize,\n PhotoStatusEvent,\n PhotoStatusState,\n PhotoSuccessResponseEvent,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlResponseEvent,\n RgbLedControlSuccessResponseEvent,\n ScanModelOptions,\n ScanOptions,\n ScanResultsCallback,\n SpeakingStatusEvent,\n SettingsAckEvent,\n SettingsAckSetting,\n SettingsAckSuccessEvent,\n SettingsAckSuccessStatus,\n SettingsAckStatus,\n StreamAudioConfig,\n StreamResolvedConfig,\n StreamStartRequest,\n StreamStatusEvent,\n StreamStatusLifecycleState,\n StreamStatusReconnectState,\n StreamStatusState,\n StreamVideoConfig,\n SwipeVolumeStatusEvent,\n SwitchStatusEvent,\n TouchEvent,\n VideoRecordingDefaults,\n VideoRecordingStartedStatusEvent,\n VideoRecordingStatusEvent,\n VideoRecordingStatusState,\n VideoRecordingStoppedStatusEvent,\n VideoRecordingSuccessStatusEvent,\n VersionInfoEvent,\n VersionInfoResult,\n WifiScanResultEvent,\n VoiceActivityDetectionStatusEvent,\n WifiSearchResult,\n WifiStatus,\n WifiStatusChangeEvent,\n} from \"./BluetoothSdk.types\"\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import PrivateBluetoothSdkModule from \"./_private/BluetoothSdkModule\"\nimport type {\n BluetoothSdkEventListener,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule,\n PublicBluetoothStatus,\n PublicGlassesStatus,\n VideoRecordingDefaults,\n} from \"./BluetoothSdk.types\"\nimport {getReleaseChangelogs} from \"./changelogs\"\n\nconst PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([\n \"log\",\n \"device_discovered\",\n \"default_device_changed\",\n \"glasses_not_ready\",\n \"button_press\",\n \"touch_event\",\n \"accel_event\",\n \"head_up\",\n \"voice_activity_detection_status\",\n \"speaking_status\",\n \"battery_status\",\n \"local_transcription\",\n \"wifi_status_change\",\n \"wifi_scan_result\",\n \"hotspot_status_change\",\n \"hotspot_error\",\n \"photo_response\",\n \"photo_status\",\n \"camera_status\",\n \"video_recording_status\",\n \"media_success\",\n \"media_error\",\n \"gallery_status\",\n \"compatible_glasses_search_stop\",\n \"swipe_volume_status\",\n \"switch_status\",\n \"rgb_led_control_response\",\n \"settings_ack\",\n \"pair_failure\",\n \"pairing_info\",\n \"entering_pairing_mode\",\n \"owner_replaced\",\n \"audio_pairing_needed\",\n \"audio_connected\",\n \"audio_disconnected\",\n \"mic_pcm\",\n \"mic_lc3\",\n \"mic_health\",\n \"stream_status\",\n \"mtk_update_complete\",\n \"glasses_session_changed\",\n \"ota_start_ack\",\n \"ota_status\",\n \"ar99_ota_status\",\n \"version_info\",\n \"extraction_progress\",\n])\n\nconst addListener: BluetoothSdkPublicModule[\"addListener\"] = (eventName, listener) => {\n if (!PUBLIC_EVENT_NAMES.has(eventName)) {\n throw new Error(`Unsupported BluetoothSdk event \"${eventName}\". Use @mentra/bluetooth-sdk/react for status state.`)\n }\n return PrivateBluetoothSdkModule.addListener(eventName, listener as BluetoothSdkEventListener<BluetoothSdkEventName>)\n}\n\nconst startOtaUpdate: BluetoothSdkPublicModule[\"startOtaUpdate\"] = (otaVersionUrl) => {\n return PrivateBluetoothSdkModule.startOtaUpdate(otaVersionUrl)\n}\n\nconst queryOtaStatus: BluetoothSdkPublicModule[\"queryOtaStatus\"] = () => {\n return PrivateBluetoothSdkModule.sendOtaQueryStatus()\n}\n\nconst bindPublicMethod = <K extends keyof BluetoothSdkPublicModule>(name: K): BluetoothSdkPublicModule[K] => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>)[name]\n if (typeof method === \"function\") {\n return method.bind(PrivateBluetoothSdkModule) as BluetoothSdkPublicModule[K]\n }\n\n return (async () => {\n throw new Error(`BluetoothSdk.${String(name)} is not available in this native build. Rebuild the app.`)\n }) as unknown as BluetoothSdkPublicModule[K]\n}\n\nexport const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({\n addListener,\n getGlassesStatus: bindPublicMethod(\"getGlassesStatus\"),\n getBluetoothStatus: bindPublicMethod(\"getBluetoothStatus\"),\n subscribeGlassesStatus: (listener: (changed: Partial<PublicGlassesStatus>) => void) =>\n PrivateBluetoothSdkModule.onGlassesStatus(listener),\n subscribeBluetoothStatus: (listener: (changed: Partial<PublicBluetoothStatus>) => void) =>\n PrivateBluetoothSdkModule.onBluetoothStatus(listener),\n getDefaultDevice: bindPublicMethod(\"getDefaultDevice\"),\n setDefaultDevice: bindPublicMethod(\"setDefaultDevice\"),\n clearDefaultDevice: bindPublicMethod(\"clearDefaultDevice\"),\n startScan: bindPublicMethod(\"startScan\"),\n stopScan: bindPublicMethod(\"stopScan\"),\n scan: bindPublicMethod(\"scan\") as BluetoothSdkPublicModule[\"scan\"],\n connect: bindPublicMethod(\"connect\"),\n connectDefault: bindPublicMethod(\"connectDefault\"),\n cancelConnectionAttempt: bindPublicMethod(\"cancelConnectionAttempt\"),\n disconnect: bindPublicMethod(\"disconnect\"),\n forget: bindPublicMethod(\"forget\"),\n displayText: bindPublicMethod(\"displayText\"),\n clearDisplay: bindPublicMethod(\"clearDisplay\"),\n showDashboard: bindPublicMethod(\"showDashboard\"),\n setDashboardPosition: bindPublicMethod(\"setDashboardPosition\"),\n setHeadUpAngle: bindPublicMethod(\"setHeadUpAngle\"),\n setImuEnabled: bindPublicMethod(\"setImuEnabled\"),\n setScreenDisabled: bindPublicMethod(\"setScreenDisabled\"),\n ping: bindPublicMethod(\"ping\"),\n requestWifiScan: bindPublicMethod(\"requestWifiScan\"),\n sendWifiCredentials: bindPublicMethod(\"sendWifiCredentials\"),\n forgetWifiNetwork: bindPublicMethod(\"forgetWifiNetwork\"),\n setHotspotState: bindPublicMethod(\"setHotspotState\"),\n setSystemTime: bindPublicMethod(\"setSystemTime\"),\n setWifiAdbState: bindPublicMethod(\"setWifiAdbState\"),\n setGalleryModeEnabled: bindPublicMethod(\"setGalleryModeEnabled\"),\n setVoiceActivityDetectionEnabled: bindPublicMethod(\"setVoiceActivityDetectionEnabled\"),\n setLoudnessGateEnabled: bindPublicMethod(\"setLoudnessGateEnabled\"),\n /**\n * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request\n * `requestPhoto(...)` options (e.g. `mode: \"text\"` for text sensor size/crop, or explicit per-shot\n * fields). Still functional until removed in a future release.\n */\n setPhotoCaptureDefaults: bindPublicMethod(\"setPhotoCaptureDefaults\"),\n setVideoRecordingDefaults: ({width, height, fps}: VideoRecordingDefaults) => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>).setVideoRecordingDefaults\n if (typeof method !== \"function\") {\n return Promise.reject(\n new Error(\"BluetoothSdk.setVideoRecordingDefaults is not available in this native build. Rebuild the app.\"),\n )\n }\n return PrivateBluetoothSdkModule.setVideoRecordingDefaults(width, height, fps)\n },\n setMaxVideoRecordingDuration: bindPublicMethod(\"setMaxVideoRecordingDuration\"),\n setCameraFov: bindPublicMethod(\"setCameraFov\"),\n setLegacyCameraFov: bindPublicMethod(\"setLegacyCameraFov\"),\n setCameraFovOverride: bindPublicMethod(\"setCameraFovOverride\"),\n releaseCameraFovOverride: bindPublicMethod(\"releaseCameraFovOverride\"),\n setCameraTuningConfig: bindPublicMethod(\"setCameraTuningConfig\"),\n queryGalleryStatus: bindPublicMethod(\"queryGalleryStatus\"),\n requestPhoto: bindPublicMethod(\"requestPhoto\"),\n warmUpCamera: bindPublicMethod(\"warmUpCamera\"),\n stopCameraWarmUp: bindPublicMethod(\"stopCameraWarmUp\"),\n startVideoRecording: bindPublicMethod(\"startVideoRecording\"),\n stopVideoRecording: bindPublicMethod(\"stopVideoRecording\"),\n queryVideoRecordingStatus: bindPublicMethod(\"queryVideoRecordingStatus\"),\n startStream: bindPublicMethod(\"startStream\"),\n stopStream: bindPublicMethod(\"stopStream\"),\n setMicState: bindPublicMethod(\"setMicState\"),\n setPreferredMic: bindPublicMethod(\"setPreferredMic\"),\n setOwnAppAudioPlaying: bindPublicMethod(\"setOwnAppAudioPlaying\"),\n getGlassesMediaVolume: bindPublicMethod(\"getGlassesMediaVolume\"),\n setGlassesMediaVolume: bindPublicMethod(\"setGlassesMediaVolume\"),\n rgbLedControl: bindPublicMethod(\"rgbLedControl\"),\n requestVersionInfo: bindPublicMethod(\"requestVersionInfo\"),\n setOtaVersionUrl: bindPublicMethod(\"setOtaVersionUrl\"),\n getOtaVersionUrl: bindPublicMethod(\"getOtaVersionUrl\"),\n checkForOtaUpdate: bindPublicMethod(\"checkForOtaUpdate\"),\n getReleaseChangelogs,\n startOtaUpdate,\n queryOtaStatus,\n startAr99OtaFromFile: bindPublicMethod(\"startAr99OtaFromFile\"),\n cancelAr99Ota: bindPublicMethod(\"cancelAr99Ota\"),\n sendAr99FactoryReset: bindPublicMethod(\"sendAr99FactoryReset\"),\n buildAr99OtaSignature: bindPublicMethod(\"buildAr99OtaSignature\"),\n setSttModelDetails: bindPublicMethod(\"setSttModelDetails\"),\n getSttModelPath: bindPublicMethod(\"getSttModelPath\"),\n checkSttModelAvailable: bindPublicMethod(\"checkSttModelAvailable\"),\n validateSttModel: bindPublicMethod(\"validateSttModel\"),\n extractTarBz2: bindPublicMethod(\"extractTarBz2\"),\n restartTranscriber: bindPublicMethod(\"restartTranscriber\"),\n setTtsModelDetails: bindPublicMethod(\"setTtsModelDetails\"),\n getTtsModelPath: bindPublicMethod(\"getTtsModelPath\"),\n getTtsModelLanguage: bindPublicMethod(\"getTtsModelLanguage\"),\n checkTtsModelAvailable: bindPublicMethod(\"checkTtsModelAvailable\"),\n validateTtsModel: bindPublicMethod(\"validateTtsModel\"),\n generateTtsAudio: bindPublicMethod(\"generateTtsAudio\"),\n})\n\nexport default BluetoothSdk\n\nexport {\n CAMERA_FOV_DEFAULT,\n CAMERA_FOV_MAX,\n CAMERA_FOV_MIN,\n DeviceModels,\n isBusyGlassesConnectionStatus,\n isConnectedGlassesConnectionStatus,\n isConnectedWifiStatus,\n isEnabledHotspotStatus,\n isReadyGlassesConnectionStatus,\n} from \"./BluetoothSdk.types\"\n\nexport type {\n AccelEvent,\n Ar99OtaStatusEvent,\n AudioConnectedEvent,\n AudioDisconnectedEvent,\n AudioPairingNeededEvent,\n BatteryStatusEvent,\n BluetoothSdkEvent,\n BluetoothSdkEventListener,\n BluetoothSdkEventMap,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule as BluetoothSdkModule,\n BluetoothSdkSubscription,\n ButtonPhotoSize,\n PhotoCaptureDefaults,\n ButtonPressEvent,\n CameraFovPreset,\n CameraFovRequest,\n CameraFovResult,\n CameraRoiPosition,\n CompatibleGlassesSearchStopEvent,\n ConnectOptions,\n ConnectedGlassesConnectionStatus,\n ConnectedWifiStatus,\n Device,\n DeviceModel,\n EnabledHotspotStatus,\n GalleryStatusEvent,\n GlassesConnectionStatus,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesNotReadyEvent,\n HeadUpEvent,\n HotspotErrorEvent,\n HotspotStatus,\n HotspotStatusChangeEvent,\n GlassesSessionChangedEvent,\n KeepAliveAckEvent,\n LocalTranscriptionEvent,\n LogEvent,\n MicLc3Event,\n MicHealthEvent,\n MicMode,\n MicPcmEvent,\n MicPreference,\n OtaStartAckEvent,\n OtaProgress,\n OtaProgressStatus,\n OtaStage,\n OtaStatus,\n OtaStatusEvent,\n OtaQueryResult,\n OtaUpdateInfo,\n ReleaseChangelog,\n MtkUpdateCompleteEvent,\n PairFailureEvent,\n PairingInfoEvent,\n EnteringPairingModeEvent,\n OwnerReplacedEvent,\n PhotoCaptureMetadata,\n PhotoResolvedConfig,\n PhotoCompression,\n PhotoFpsRange,\n PhotoMeteredPreview,\n PhotoMode,\n PublicBluetoothStatus,\n PublicGlassesStatus,\n PhotoTransferMethod,\n PhotoResponseEvent,\n PhotoRequestedCaptureConfig,\n PhotoRequestParams,\n PhotoSize,\n PhotoStatusEvent,\n PhotoStatusState,\n PhotoSuccessResponseEvent,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlResponseEvent,\n RgbLedControlSuccessResponseEvent,\n ScanModelOptions,\n ScanOptions,\n ScanResultsCallback,\n SpeakingStatusEvent,\n SettingsAckEvent,\n SettingsAckSetting,\n SettingsAckSuccessEvent,\n SettingsAckSuccessStatus,\n SettingsAckStatus,\n StreamAudioConfig,\n StreamResolvedConfig,\n StreamStartRequest,\n StreamStatusEvent,\n StreamStatusLifecycleState,\n StreamStatusReconnectState,\n StreamStatusState,\n StreamVideoConfig,\n SwipeVolumeStatusEvent,\n SwitchStatusEvent,\n TouchEvent,\n VideoRecordingDefaults,\n VideoRecordingStartedStatusEvent,\n VideoRecordingStatusEvent,\n VideoRecordingStatusState,\n VideoRecordingStoppedStatusEvent,\n VideoRecordingSuccessStatusEvent,\n VersionInfoEvent,\n VersionInfoResult,\n WifiScanResultEvent,\n VoiceActivityDetectionStatusEvent,\n WifiSearchResult,\n WifiStatus,\n WifiStatusChangeEvent,\n} from \"./BluetoothSdk.types\"\n"]}
@@ -0,0 +1,14 @@
1
+ export type OtaServerResult = {
2
+ baseUrl: string;
3
+ host: string;
4
+ manifestUrl: string;
5
+ port: number;
6
+ };
7
+ export type MentraOtaServerModuleEvents = {
8
+ artifactDownloadProgress: (event: {
9
+ destination: string;
10
+ bytesWritten: number;
11
+ contentLength: number;
12
+ }) => void;
13
+ };
14
+ //# sourceMappingURL=MentraOtaServer.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentraOtaServer.types.d.ts","sourceRoot":"","sources":["../../src/ota-server/MentraOtaServer.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,wBAAwB,EAAE,CAAC,KAAK,EAAE;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAC,KAAK,IAAI,CAAA;CAC9G,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=MentraOtaServer.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentraOtaServer.types.js","sourceRoot":"","sources":["../../src/ota-server/MentraOtaServer.types.ts"],"names":[],"mappings":"","sourcesContent":["export type OtaServerResult = {\n baseUrl: string\n host: string\n manifestUrl: string\n port: number\n}\n\nexport type MentraOtaServerModuleEvents = {\n artifactDownloadProgress: (event: {destination: string; bytesWritten: number; contentLength: number}) => void\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import { NativeModule } from "expo";
2
+ import type { MentraOtaServerModuleEvents, OtaServerResult } from "./MentraOtaServer.types";
3
+ declare class MentraOtaServerModule extends NativeModule<MentraOtaServerModuleEvents> {
4
+ /**
5
+ * Serve `manifestJson` at /version.json and `artifactPaths` (sha256 -> local file path)
6
+ * at /artifacts/<sha256>. Pass `host` when the caller knows the authoritative local
7
+ * address (e.g. from the scoped hotspot network); omit to fall back to interface
8
+ * scanning. Returns the URLs to hand to the glasses via ota_start.
9
+ */
10
+ startOtaServer(manifestJson: string, artifactPaths: Record<string, string>, host?: string | null): Promise<OtaServerResult>;
11
+ stopOtaServer(): Promise<void>;
12
+ /** Wait for iPhone Wi-Fi (`en0`) to acquire an address on the glasses gateway subnet. */
13
+ waitForWifiAddress(gateway: string, timeoutMs: number): Promise<string>;
14
+ downloadArtifact(source: string, destination: string): Promise<{
15
+ statusCode: number;
16
+ bytesWritten: number;
17
+ }>;
18
+ }
19
+ declare const _default: MentraOtaServerModule;
20
+ export default _default;
21
+ //# sourceMappingURL=MentraOtaServerModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentraOtaServerModule.d.ts","sourceRoot":"","sources":["../../src/ota-server/MentraOtaServerModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAsB,MAAM,MAAM,CAAA;AAEtD,OAAO,KAAK,EAAC,2BAA2B,EAAE,eAAe,EAAC,MAAM,yBAAyB,CAAA;AAEzF,OAAO,OAAO,qBAAsB,SAAQ,YAAY,CAAC,2BAA2B,CAAC;IACnF;;;;;OAKG;IACH,cAAc,CACZ,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC,eAAe,CAAC;IAC3B,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAC9B,yFAAyF;IACzF,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACvE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,CAAC;CAC3G;;AAED,wBAA4E"}
@@ -0,0 +1,3 @@
1
+ import { requireNativeModule } from "expo";
2
+ export default requireNativeModule("MentraOtaServer");
3
+ //# sourceMappingURL=MentraOtaServerModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentraOtaServerModule.js","sourceRoot":"","sources":["../../src/ota-server/MentraOtaServerModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,mBAAmB,EAAC,MAAM,MAAM,CAAA;AAsBtD,eAAe,mBAAmB,CAAwB,iBAAiB,CAAC,CAAA","sourcesContent":["import {NativeModule, requireNativeModule} from \"expo\"\n\nimport type {MentraOtaServerModuleEvents, OtaServerResult} from \"./MentraOtaServer.types\"\n\ndeclare class MentraOtaServerModule extends NativeModule<MentraOtaServerModuleEvents> {\n /**\n * Serve `manifestJson` at /version.json and `artifactPaths` (sha256 -> local file path)\n * at /artifacts/<sha256>. Pass `host` when the caller knows the authoritative local\n * address (e.g. from the scoped hotspot network); omit to fall back to interface\n * scanning. Returns the URLs to hand to the glasses via ota_start.\n */\n startOtaServer(\n manifestJson: string,\n artifactPaths: Record<string, string>,\n host?: string | null,\n ): Promise<OtaServerResult>\n stopOtaServer(): Promise<void>\n /** Wait for iPhone Wi-Fi (`en0`) to acquire an address on the glasses gateway subnet. */\n waitForWifiAddress(gateway: string, timeoutMs: number): Promise<string>\n downloadArtifact(source: string, destination: string): Promise<{statusCode: number; bytesWritten: number}>\n}\n\nexport default requireNativeModule<MentraOtaServerModule>(\"MentraOtaServer\")\n"]}
@@ -0,0 +1,10 @@
1
+ import { NativeModule } from "expo";
2
+ import type { MentraOtaServerModuleEvents, OtaServerResult } from "./MentraOtaServer.types";
3
+ declare class MentraOtaServerModule extends NativeModule<MentraOtaServerModuleEvents> {
4
+ startOtaServer(): Promise<OtaServerResult>;
5
+ stopOtaServer(): Promise<void>;
6
+ waitForWifiAddress(): Promise<string>;
7
+ }
8
+ declare const _default: typeof MentraOtaServerModule;
9
+ export default _default;
10
+ //# sourceMappingURL=MentraOtaServerModule.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentraOtaServerModule.web.d.ts","sourceRoot":"","sources":["../../src/ota-server/MentraOtaServerModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAoB,MAAM,MAAM,CAAA;AAEpD,OAAO,KAAK,EAAC,2BAA2B,EAAE,eAAe,EAAC,MAAM,yBAAyB,CAAA;AAEzF,cAAM,qBAAsB,SAAQ,YAAY,CAAC,2BAA2B,CAAC;IACrE,cAAc,IAAI,OAAO,CAAC,eAAe,CAAC;IAI1C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9B,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;CAG5C;;AAED,wBAA0E"}
@@ -0,0 +1,12 @@
1
+ import { NativeModule, registerWebModule } from "expo";
2
+ class MentraOtaServerModule extends NativeModule {
3
+ async startOtaServer() {
4
+ throw new Error("The OTA server is only available in native apps.");
5
+ }
6
+ async stopOtaServer() { }
7
+ async waitForWifiAddress() {
8
+ throw new Error("The OTA server is only available in native apps.");
9
+ }
10
+ }
11
+ export default registerWebModule(MentraOtaServerModule, "MentraOtaServer");
12
+ //# sourceMappingURL=MentraOtaServerModule.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentraOtaServerModule.web.js","sourceRoot":"","sources":["../../src/ota-server/MentraOtaServerModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,MAAM,CAAA;AAIpD,MAAM,qBAAsB,SAAQ,YAAyC;IAC3E,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IACrE,CAAC;IAED,KAAK,CAAC,aAAa,KAAmB,CAAC;IAEvC,KAAK,CAAC,kBAAkB;QACtB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IACrE,CAAC;CACF;AAED,eAAe,iBAAiB,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,CAAA","sourcesContent":["import {NativeModule, registerWebModule} from \"expo\"\n\nimport type {MentraOtaServerModuleEvents, OtaServerResult} from \"./MentraOtaServer.types\"\n\nclass MentraOtaServerModule extends NativeModule<MentraOtaServerModuleEvents> {\n async startOtaServer(): Promise<OtaServerResult> {\n throw new Error(\"The OTA server is only available in native apps.\")\n }\n\n async stopOtaServer(): Promise<void> {}\n\n async waitForWifiAddress(): Promise<string> {\n throw new Error(\"The OTA server is only available in native apps.\")\n }\n}\n\nexport default registerWebModule(MentraOtaServerModule, \"MentraOtaServer\")\n"]}
@@ -0,0 +1,3 @@
1
+ export { default } from "./MentraOtaServerModule";
2
+ export * from "./MentraOtaServer.types";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ota-server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,yBAAyB,CAAA;AAC/C,cAAc,yBAAyB,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { default } from "./MentraOtaServerModule";
2
+ export * from "./MentraOtaServer.types";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ota-server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,yBAAyB,CAAA;AAC/C,cAAc,yBAAyB,CAAA","sourcesContent":["export {default} from \"./MentraOtaServerModule\"\nexport * from \"./MentraOtaServer.types\"\n"]}
@@ -0,0 +1,67 @@
1
+ export type OtaTransportSubscription = {
2
+ remove(): void;
3
+ };
4
+ export type OtaLocalNetworkConnection = {
5
+ connected: boolean;
6
+ ssid: string;
7
+ localAddress?: string;
8
+ };
9
+ export type OtaLocalNetworkLostEvent = {
10
+ ssid: string;
11
+ };
12
+ export type OtaLocalNetworkResponse = {
13
+ status: number;
14
+ headers: Record<string, string>;
15
+ bodyBase64: string;
16
+ };
17
+ export type OtaLocalNetworkDownloadResult = {
18
+ statusCode: number;
19
+ bytesWritten: number;
20
+ headers: Record<string, string>;
21
+ };
22
+ export type OtaLocalNetworkDownloadProgress = {
23
+ requestId: string;
24
+ bytesWritten: number;
25
+ contentLength: number;
26
+ statusCode?: number;
27
+ headers?: Record<string, string>;
28
+ };
29
+ export type OtaArtifactDownloadProgress = {
30
+ destination: string;
31
+ bytesWritten: number;
32
+ contentLength: number;
33
+ };
34
+ export type OtaServerResult = {
35
+ baseUrl: string;
36
+ host: string;
37
+ manifestUrl: string;
38
+ port: number;
39
+ };
40
+ /**
41
+ * Scoped networking for traffic that must stay on a Mentra Live hotspot while
42
+ * the phone's default route remains on cellular or another Wi-Fi network.
43
+ *
44
+ * The module is optional because iOS uses its system Wi-Fi join flow instead.
45
+ */
46
+ export declare const otaLocalNetwork: Readonly<{
47
+ isAvailable: () => boolean;
48
+ connect: (ssid: string, password: string) => Promise<OtaLocalNetworkConnection>;
49
+ request: (requestId: string, url: string, method: string, headers: Record<string, string>, body: string | null, timeoutMs: number) => Promise<OtaLocalNetworkResponse>;
50
+ download: (requestId: string, url: string, destination: string, headers: Record<string, string>, connectionTimeoutMs: number, readTimeoutMs: number) => Promise<OtaLocalNetworkDownloadResult>;
51
+ cancel: (requestId: string) => Promise<void>;
52
+ disconnect: () => Promise<void>;
53
+ onDownloadProgress: (listener: (event: OtaLocalNetworkDownloadProgress) => void) => OtaTransportSubscription;
54
+ onNetworkLost: (listener: (event: OtaLocalNetworkLostEvent) => void) => OtaTransportSubscription;
55
+ }>;
56
+ /** Native HTTP server and artifact downloader used by the Engine OTA coordinator. */
57
+ export declare const otaServer: Readonly<{
58
+ start: (manifestJson: string, artifactPaths: Record<string, string>, host?: string | null) => Promise<OtaServerResult>;
59
+ stop: () => Promise<void>;
60
+ waitForWifiAddress: (gateway: string, timeoutMs: number) => Promise<string>;
61
+ downloadArtifact: (source: string, destination: string) => Promise<{
62
+ statusCode: number;
63
+ bytesWritten: number;
64
+ }>;
65
+ onArtifactDownloadProgress: (listener: (event: OtaArtifactDownloadProgress) => void) => OtaTransportSubscription;
66
+ }>;
67
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ota-transport/index.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,wBAAwB,GAAG;IAAC,MAAM,IAAI,IAAI,CAAA;CAAC,CAAA;AAEvD,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAA;AAErD,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,+BAA+B,GAAG;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe;uBACT,OAAO;oBACF,MAAM,YAAY,MAAM,KAAG,OAAO,CAAC,yBAAyB,CAAC;yBAKtE,MAAM,OACZ,MAAM,UACH,MAAM,WACL,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QACzB,MAAM,GAAG,IAAI,aACR,MAAM,KAChB,OAAO,CAAC,uBAAuB,CAAC;0BAKtB,MAAM,OACZ,MAAM,eACE,MAAM,WACV,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,uBACV,MAAM,iBACZ,MAAM,KACpB,OAAO,CAAC,6BAA6B,CAAC;wBAIf,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;sBAI1B,OAAO,CAAC,IAAI,CAAC;mCAIJ,CAAC,KAAK,EAAE,+BAA+B,KAAK,IAAI,KAAG,wBAAwB;8BAIhF,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,KAAG,wBAAwB;EAI9F,CAAA;AAEF,qFAAqF;AACrF,eAAO,MAAM,SAAS;0BAEJ,MAAM,iBACL,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,SAC9B,MAAM,GAAG,IAAI,KACnB,OAAO,CAAC,eAAe,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC;kCACO,MAAM,aAAa,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;+BAE9C,MAAM,eAAe,MAAM,KAAG,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,CAAC;2CAErE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,KAAG,wBAAwB;EAE9G,CAAA"}
@@ -0,0 +1,58 @@
1
+ // This public adapter is the package-owned boundary over its native implementation.
2
+ // eslint-disable-next-line no-restricted-imports
3
+ import MentraLocalNetwork from "../_private/MentraLocalNetworkModule";
4
+ // eslint-disable-next-line no-restricted-imports
5
+ import MentraOtaServer from "../ota-server";
6
+ /**
7
+ * Scoped networking for traffic that must stay on a Mentra Live hotspot while
8
+ * the phone's default route remains on cellular or another Wi-Fi network.
9
+ *
10
+ * The module is optional because iOS uses its system Wi-Fi join flow instead.
11
+ */
12
+ export const otaLocalNetwork = Object.freeze({
13
+ isAvailable: () => MentraLocalNetwork != null,
14
+ connect: async (ssid, password) => {
15
+ if (!MentraLocalNetwork)
16
+ throw new Error("Scoped local networking is not available in this native build");
17
+ return MentraLocalNetwork.connect(ssid, password);
18
+ },
19
+ request: async (requestId, url, method, headers, body, timeoutMs) => {
20
+ if (!MentraLocalNetwork)
21
+ throw new Error("Scoped local networking is not available in this native build");
22
+ return MentraLocalNetwork.request(requestId, url, method, headers, body, timeoutMs);
23
+ },
24
+ download: async (requestId, url, destination, headers, connectionTimeoutMs, readTimeoutMs) => {
25
+ if (!MentraLocalNetwork)
26
+ throw new Error("Scoped local networking is not available in this native build");
27
+ return MentraLocalNetwork.download(requestId, url, destination, headers, connectionTimeoutMs, readTimeoutMs);
28
+ },
29
+ cancel: async (requestId) => {
30
+ if (!MentraLocalNetwork)
31
+ return;
32
+ await MentraLocalNetwork.cancel(requestId);
33
+ },
34
+ disconnect: async () => {
35
+ if (!MentraLocalNetwork)
36
+ return;
37
+ await MentraLocalNetwork.disconnect();
38
+ },
39
+ onDownloadProgress: (listener) => {
40
+ if (!MentraLocalNetwork)
41
+ return { remove() { } };
42
+ return MentraLocalNetwork.addListener("downloadProgress", listener);
43
+ },
44
+ onNetworkLost: (listener) => {
45
+ if (!MentraLocalNetwork)
46
+ return { remove() { } };
47
+ return MentraLocalNetwork.addListener("networkLost", listener);
48
+ },
49
+ });
50
+ /** Native HTTP server and artifact downloader used by the Engine OTA coordinator. */
51
+ export const otaServer = Object.freeze({
52
+ start: (manifestJson, artifactPaths, host) => MentraOtaServer.startOtaServer(manifestJson, artifactPaths, host),
53
+ stop: () => MentraOtaServer.stopOtaServer(),
54
+ waitForWifiAddress: (gateway, timeoutMs) => MentraOtaServer.waitForWifiAddress(gateway, timeoutMs),
55
+ downloadArtifact: (source, destination) => MentraOtaServer.downloadArtifact(source, destination),
56
+ onArtifactDownloadProgress: (listener) => MentraOtaServer.addListener("artifactDownloadProgress", listener),
57
+ });
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ota-transport/index.ts"],"names":[],"mappings":"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","sourcesContent":["// This public adapter is the package-owned boundary over its native implementation.\n// eslint-disable-next-line no-restricted-imports\nimport MentraLocalNetwork from \"../_private/MentraLocalNetworkModule\"\n// eslint-disable-next-line no-restricted-imports\nimport MentraOtaServer from \"../ota-server\"\n\nexport type OtaTransportSubscription = {remove(): void}\n\nexport type OtaLocalNetworkConnection = {\n connected: boolean\n ssid: string\n localAddress?: string\n}\n\nexport type OtaLocalNetworkLostEvent = {ssid: string}\n\nexport type OtaLocalNetworkResponse = {\n status: number\n headers: Record<string, string>\n bodyBase64: string\n}\n\nexport type OtaLocalNetworkDownloadResult = {\n statusCode: number\n bytesWritten: number\n headers: Record<string, string>\n}\n\nexport type OtaLocalNetworkDownloadProgress = {\n requestId: string\n bytesWritten: number\n contentLength: number\n statusCode?: number\n headers?: Record<string, string>\n}\n\nexport type OtaArtifactDownloadProgress = {\n destination: string\n bytesWritten: number\n contentLength: number\n}\n\nexport type OtaServerResult = {\n baseUrl: string\n host: string\n manifestUrl: string\n port: number\n}\n\n/**\n * Scoped networking for traffic that must stay on a Mentra Live hotspot while\n * the phone's default route remains on cellular or another Wi-Fi network.\n *\n * The module is optional because iOS uses its system Wi-Fi join flow instead.\n */\nexport const otaLocalNetwork = Object.freeze({\n isAvailable: (): boolean => MentraLocalNetwork != null,\n connect: async (ssid: string, password: string): Promise<OtaLocalNetworkConnection> => {\n if (!MentraLocalNetwork) throw new Error(\"Scoped local networking is not available in this native build\")\n return MentraLocalNetwork.connect(ssid, password)\n },\n request: async (\n requestId: string,\n url: string,\n method: string,\n headers: Record<string, string>,\n body: string | null,\n timeoutMs: number,\n ): Promise<OtaLocalNetworkResponse> => {\n if (!MentraLocalNetwork) throw new Error(\"Scoped local networking is not available in this native build\")\n return MentraLocalNetwork.request(requestId, url, method, headers, body, timeoutMs)\n },\n download: async (\n requestId: string,\n url: string,\n destination: string,\n headers: Record<string, string>,\n connectionTimeoutMs: number,\n readTimeoutMs: number,\n ): Promise<OtaLocalNetworkDownloadResult> => {\n if (!MentraLocalNetwork) throw new Error(\"Scoped local networking is not available in this native build\")\n return MentraLocalNetwork.download(requestId, url, destination, headers, connectionTimeoutMs, readTimeoutMs)\n },\n cancel: async (requestId: string): Promise<void> => {\n if (!MentraLocalNetwork) return\n await MentraLocalNetwork.cancel(requestId)\n },\n disconnect: async (): Promise<void> => {\n if (!MentraLocalNetwork) return\n await MentraLocalNetwork.disconnect()\n },\n onDownloadProgress: (listener: (event: OtaLocalNetworkDownloadProgress) => void): OtaTransportSubscription => {\n if (!MentraLocalNetwork) return {remove() {}}\n return MentraLocalNetwork.addListener(\"downloadProgress\", listener)\n },\n onNetworkLost: (listener: (event: OtaLocalNetworkLostEvent) => void): OtaTransportSubscription => {\n if (!MentraLocalNetwork) return {remove() {}}\n return MentraLocalNetwork.addListener(\"networkLost\", listener)\n },\n})\n\n/** Native HTTP server and artifact downloader used by the Engine OTA coordinator. */\nexport const otaServer = Object.freeze({\n start: (\n manifestJson: string,\n artifactPaths: Record<string, string>,\n host?: string | null,\n ): Promise<OtaServerResult> => MentraOtaServer.startOtaServer(manifestJson, artifactPaths, host),\n stop: (): Promise<void> => MentraOtaServer.stopOtaServer(),\n waitForWifiAddress: (gateway: string, timeoutMs: number): Promise<string> =>\n MentraOtaServer.waitForWifiAddress(gateway, timeoutMs),\n downloadArtifact: (source: string, destination: string): Promise<{statusCode: number; bytesWritten: number}> =>\n MentraOtaServer.downloadArtifact(source, destination),\n onArtifactDownloadProgress: (listener: (event: OtaArtifactDownloadProgress) => void): OtaTransportSubscription =>\n MentraOtaServer.addListener(\"artifactDownloadProgress\", listener),\n})\n"]}
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "platforms": ["apple", "android"],
3
3
  "apple": {
4
- "modules": ["BluetoothSdkModule", "MentraPhotoReceiverModule"]
4
+ "modules": ["BluetoothSdkModule", "MentraPhotoReceiverModule", "MentraOtaServerModule"]
5
5
  },
6
6
  "android": {
7
7
  "modules": [
8
8
  "com.mentra.bluetoothsdk.BluetoothSdkModule",
9
9
  "com.mentra.bluetoothsdk.MentraLocalNetworkModule",
10
- "com.mentra.bluetoothsdk.photoreceiver.MentraPhotoReceiverModule"
10
+ "com.mentra.bluetoothsdk.photoreceiver.MentraPhotoReceiverModule",
11
+ "com.mentra.bluetoothsdk.otaserver.MentraOtaServerModule"
11
12
  ]
12
13
  }
13
14
  }
@@ -0,0 +1,125 @@
1
+ import Foundation
2
+
3
+ /// Background-capable, native artifact staging for hotspot OTA.
4
+ final class BackgroundOtaArtifactDownloader: NSObject, URLSessionDownloadDelegate, URLSessionTaskDelegate {
5
+ typealias ProgressHandler = (_ destination: String, _ written: Int64, _ total: Int64) -> Void
6
+
7
+ private struct Pending {
8
+ let continuation: CheckedContinuation<[String: Any], Error>
9
+ }
10
+
11
+ private let lock = NSLock()
12
+ private let onProgress: ProgressHandler
13
+ private var pending: [Int: Pending] = [:]
14
+ private lazy var session: URLSession = {
15
+ let configuration = URLSessionConfiguration.background(
16
+ withIdentifier: "com.mentra.bluetooth-sdk.hotspot-ota-artifacts"
17
+ )
18
+ configuration.sessionSendsLaunchEvents = true
19
+ configuration.isDiscretionary = false
20
+ configuration.waitsForConnectivity = true
21
+ return URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
22
+ }()
23
+
24
+ init(onProgress: @escaping ProgressHandler) {
25
+ self.onProgress = onProgress
26
+ super.init()
27
+ }
28
+
29
+ func download(from source: String, to destination: String) async throws -> [String: Any] {
30
+ guard let sourceUrl = URL(string: source),
31
+ sourceUrl.scheme == "https" || sourceUrl.scheme == "http"
32
+ else {
33
+ throw OtaServerError("Invalid artifact URL")
34
+ }
35
+
36
+ if FileManager.default.fileExists(atPath: destination) {
37
+ let size = fileSize(atPath: destination)
38
+ return ["statusCode": 200, "bytesWritten": size]
39
+ }
40
+
41
+ try FileManager.default.createDirectory(
42
+ at: URL(fileURLWithPath: destination).deletingLastPathComponent(),
43
+ withIntermediateDirectories: true
44
+ )
45
+
46
+ return try await withCheckedThrowingContinuation { continuation in
47
+ let task = session.downloadTask(with: sourceUrl)
48
+ task.taskDescription = destination
49
+ lock.lock()
50
+ pending[task.taskIdentifier] = Pending(continuation: continuation)
51
+ lock.unlock()
52
+ task.resume()
53
+ }
54
+ }
55
+
56
+ func urlSession(
57
+ _: URLSession,
58
+ downloadTask: URLSessionDownloadTask,
59
+ didWriteData _: Int64,
60
+ totalBytesWritten: Int64,
61
+ totalBytesExpectedToWrite: Int64
62
+ ) {
63
+ guard let destination = downloadTask.taskDescription else { return }
64
+ onProgress(destination, totalBytesWritten, totalBytesExpectedToWrite)
65
+ }
66
+
67
+ func urlSession(
68
+ _: URLSession,
69
+ downloadTask: URLSessionDownloadTask,
70
+ didFinishDownloadingTo location: URL
71
+ ) {
72
+ guard let destination = downloadTask.taskDescription else { return }
73
+ guard let response = downloadTask.response as? HTTPURLResponse,
74
+ (200 ... 299).contains(response.statusCode)
75
+ else {
76
+ let status = (downloadTask.response as? HTTPURLResponse)?.statusCode ?? 0
77
+ reject(
78
+ taskId: downloadTask.taskIdentifier,
79
+ error: OtaServerError("Artifact download failed with HTTP \(status)")
80
+ )
81
+ return
82
+ }
83
+ let destinationUrl = URL(fileURLWithPath: destination)
84
+ do {
85
+ try? FileManager.default.removeItem(at: destinationUrl)
86
+ try FileManager.default.moveItem(at: location, to: destinationUrl)
87
+ let size = fileSize(atPath: destination)
88
+ resolve(
89
+ taskId: downloadTask.taskIdentifier,
90
+ result: ["statusCode": response.statusCode, "bytesWritten": size]
91
+ )
92
+ } catch {
93
+ reject(taskId: downloadTask.taskIdentifier, error: error)
94
+ }
95
+ }
96
+
97
+ func urlSession(_: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
98
+ if let error {
99
+ reject(taskId: task.taskIdentifier, error: error)
100
+ }
101
+ }
102
+
103
+ private func resolve(taskId: Int, result: [String: Any]) {
104
+ lock.lock()
105
+ let item = pending.removeValue(forKey: taskId)
106
+ lock.unlock()
107
+ item?.continuation.resume(returning: result)
108
+ }
109
+
110
+ private func reject(taskId: Int, error: Error) {
111
+ lock.lock()
112
+ let item = pending.removeValue(forKey: taskId)
113
+ lock.unlock()
114
+ item?.continuation.resume(throwing: error)
115
+ }
116
+
117
+ private func fileSize(atPath path: String) -> Int64 {
118
+ guard let value = try? FileManager.default.attributesOfItem(atPath: path)[.size],
119
+ let number = value as? NSNumber
120
+ else {
121
+ return 0
122
+ }
123
+ return number.int64Value
124
+ }
125
+ }
@@ -46,6 +46,9 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
46
46
  "settings_ack",
47
47
  "version_info",
48
48
  "pair_failure",
49
+ "pairing_info",
50
+ "entering_pairing_mode",
51
+ "owner_replaced",
49
52
  "audio_pairing_needed",
50
53
  "audio_connected",
51
54
  "audio_disconnected",
@@ -57,6 +60,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
57
60
  "ws_bin",
58
61
  "mic_pcm",
59
62
  "mic_lc3",
63
+ "mic_health",
60
64
  "stream_status",
61
65
  "keep_alive_ack",
62
66
  "mtk_update_complete",
@@ -303,6 +307,11 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
303
307
  return try await sdk.setHotspotState(enabled: enabled).values
304
308
  }
305
309
 
310
+ AsyncFunction("setWifiAdbState") { (enabled: Bool) in
311
+ let sdk = await MainActor.run { self.bluetoothSdk() }
312
+ try await sdk.setWifiAdbState(enabled: enabled)
313
+ }
314
+
306
315
  AsyncFunction("setSystemTime") { (timestampMs: Double) in
307
316
  let maxTimestamp = Double(Int64.max).nextDown
308
317
  guard timestampMs.isFinite,
@@ -562,6 +571,11 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
562
571
  ).values
563
572
  }
564
573
 
574
+ AsyncFunction("queryVideoRecordingStatus") { (requestId: String) in
575
+ let sdk = await MainActor.run { self.bluetoothSdk() }
576
+ return try await sdk.queryVideoRecordingStatus(requestId: requestId).values
577
+ }
578
+
565
579
  // MARK: - Stream Commands
566
580
 
567
581
  AsyncFunction("startStream") { (params: [String: Any]) in
@@ -812,6 +826,8 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
812
826
  sendEvent("voice_activity_detection_status", status.values)
813
827
  case let .speakingStatus(status):
814
828
  sendEvent("speaking_status", status.values)
829
+ case let .micHealth(health):
830
+ sendEvent("mic_health", health.values)
815
831
  case let .wifiStatus(status):
816
832
  sendEvent("wifi_status_change", status.values)
817
833
  case let .hotspotStatus(status):
@@ -921,5 +937,3 @@ private extension ConnectOptions {
921
937
 
922
938
 
923
939
 
924
-
925
-