@mentra/bluetooth-sdk 3.1.0-dev.10 → 3.1.0-dev.101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -21
- package/android/src/main/java/com/mentra/bluetoothsdk/GeneratedChangelogCatalog.kt +7 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/GeneratedReleaseMetadata.kt +5 -5
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +15 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/ReleaseChangelog.kt +61 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +74 -25
- package/android/src/test/java/com/mentra/bluetoothsdk/ReleaseChangelogTest.kt +13 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/MentraLivePairingAdvertisementParserTest.kt +58 -0
- package/build/BluetoothSdk.types.d.ts +26 -0
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/changelogs.d.ts +7 -0
- package/build/changelogs.d.ts.map +1 -0
- package/build/changelogs.js +44 -0
- package/build/changelogs.js.map +1 -0
- package/build/generated/changelogCatalog.d.ts +6 -0
- package/build/generated/changelogCatalog.d.ts.map +1 -0
- package/build/generated/changelogCatalog.js +8 -0
- package/build/generated/changelogCatalog.js.map +1 -0
- package/build/generated/releaseMetadata.js +5 -5
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +14 -0
- package/build/index.js.map +1 -1
- package/build/ota-transport/index.d.ts +67 -0
- package/build/ota-transport/index.d.ts.map +1 -0
- package/build/ota-transport/index.js +58 -0
- package/build/ota-transport/index.js.map +1 -0
- package/ios/Source/BluetoothSdkDefaults.swift +1 -1
- package/ios/Source/GeneratedChangelogCatalog.swift +6 -0
- package/ios/Source/GeneratedReleaseMetadata.swift +5 -5
- package/ios/Source/MentraBluetoothSDK.swift +17 -0
- package/ios/Source/ReleaseChangelog.swift +65 -0
- package/ios/Source/sgcs/MentraLive.swift +56 -14
- package/ios/Tests/MentraLivePairingAdvertisementTests.swift +56 -0
- package/ios/Tests/ReleaseChangelogTests.swift +13 -0
- package/package.json +6 -1
- package/scripts/public-ota-api.test.mjs +37 -0
- package/src/BluetoothSdk.types.ts +28 -0
- package/src/changelogs.ts +44 -0
- package/src/generated/changelogCatalog.ts +9 -0
- package/src/generated/releaseMetadata.ts +5 -5
- package/src/index.ts +24 -0
- 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",
|
|
@@ -39,6 +40,8 @@ const PUBLIC_EVENT_NAMES = new Set([
|
|
|
39
40
|
"mic_lc3",
|
|
40
41
|
"mic_health",
|
|
41
42
|
"stream_status",
|
|
43
|
+
"mtk_update_complete",
|
|
44
|
+
"glasses_session_changed",
|
|
42
45
|
"ota_start_ack",
|
|
43
46
|
"ota_status",
|
|
44
47
|
"ar99_ota_status",
|
|
@@ -54,6 +57,9 @@ const addListener = (eventName, listener) => {
|
|
|
54
57
|
const startOtaUpdate = (otaVersionUrl) => {
|
|
55
58
|
return PrivateBluetoothSdkModule.startOtaUpdate(otaVersionUrl);
|
|
56
59
|
};
|
|
60
|
+
const queryOtaStatus = () => {
|
|
61
|
+
return PrivateBluetoothSdkModule.sendOtaQueryStatus();
|
|
62
|
+
};
|
|
57
63
|
const bindPublicMethod = (name) => {
|
|
58
64
|
const method = PrivateBluetoothSdkModule[name];
|
|
59
65
|
if (typeof method === "function") {
|
|
@@ -65,6 +71,10 @@ const bindPublicMethod = (name) => {
|
|
|
65
71
|
};
|
|
66
72
|
export const BluetoothSdk = Object.freeze({
|
|
67
73
|
addListener,
|
|
74
|
+
getGlassesStatus: bindPublicMethod("getGlassesStatus"),
|
|
75
|
+
getBluetoothStatus: bindPublicMethod("getBluetoothStatus"),
|
|
76
|
+
subscribeGlassesStatus: (listener) => PrivateBluetoothSdkModule.onGlassesStatus(listener),
|
|
77
|
+
subscribeBluetoothStatus: (listener) => PrivateBluetoothSdkModule.onBluetoothStatus(listener),
|
|
68
78
|
getDefaultDevice: bindPublicMethod("getDefaultDevice"),
|
|
69
79
|
setDefaultDevice: bindPublicMethod("setDefaultDevice"),
|
|
70
80
|
clearDefaultDevice: bindPublicMethod("clearDefaultDevice"),
|
|
@@ -83,10 +93,12 @@ export const BluetoothSdk = Object.freeze({
|
|
|
83
93
|
setHeadUpAngle: bindPublicMethod("setHeadUpAngle"),
|
|
84
94
|
setImuEnabled: bindPublicMethod("setImuEnabled"),
|
|
85
95
|
setScreenDisabled: bindPublicMethod("setScreenDisabled"),
|
|
96
|
+
ping: bindPublicMethod("ping"),
|
|
86
97
|
requestWifiScan: bindPublicMethod("requestWifiScan"),
|
|
87
98
|
sendWifiCredentials: bindPublicMethod("sendWifiCredentials"),
|
|
88
99
|
forgetWifiNetwork: bindPublicMethod("forgetWifiNetwork"),
|
|
89
100
|
setHotspotState: bindPublicMethod("setHotspotState"),
|
|
101
|
+
setSystemTime: bindPublicMethod("setSystemTime"),
|
|
90
102
|
setWifiAdbState: bindPublicMethod("setWifiAdbState"),
|
|
91
103
|
setGalleryModeEnabled: bindPublicMethod("setGalleryModeEnabled"),
|
|
92
104
|
setVoiceActivityDetectionEnabled: bindPublicMethod("setVoiceActivityDetectionEnabled"),
|
|
@@ -129,7 +141,9 @@ export const BluetoothSdk = Object.freeze({
|
|
|
129
141
|
setOtaVersionUrl: bindPublicMethod("setOtaVersionUrl"),
|
|
130
142
|
getOtaVersionUrl: bindPublicMethod("getOtaVersionUrl"),
|
|
131
143
|
checkForOtaUpdate: bindPublicMethod("checkForOtaUpdate"),
|
|
144
|
+
getReleaseChangelogs,
|
|
132
145
|
startOtaUpdate,
|
|
146
|
+
queryOtaStatus,
|
|
133
147
|
startAr99OtaFromFile: bindPublicMethod("startAr99OtaFromFile"),
|
|
134
148
|
cancelAr99Ota: bindPublicMethod("cancelAr99Ota"),
|
|
135
149
|
sendAr99FactoryReset: bindPublicMethod("sendAr99FactoryReset"),
|
package/build/index.js.map
CHANGED
|
@@ -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 \"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 \"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 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 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 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 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 PairFailureEvent,\n PairingInfoEvent,\n EnteringPairingModeEvent,\n OwnerReplacedEvent,\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,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"]}
|
|
@@ -11,7 +11,7 @@ enum BluetoothSdkDefaults {
|
|
|
11
11
|
static let voiceActivityDetectionEnabled = false
|
|
12
12
|
static let loudnessGateEnabled = true
|
|
13
13
|
private static let infoSdkVersionKey = "MentraBluetoothSdkVersion"
|
|
14
|
-
private static let swiftPackageSdkVersion = "3.1.0-dev.
|
|
14
|
+
private static let swiftPackageSdkVersion = "3.1.0-dev.101"
|
|
15
15
|
private static let swiftPackageSdkVersionPlaceholder = "__MENTRA" + "_BLUETOOTH_SDK_VERSION__"
|
|
16
16
|
|
|
17
17
|
private static func normalizedSdkVersion(_ value: String?) -> String? {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// Generated from /changelogs. Do not edit directly.
|
|
4
|
+
let generatedReleaseChangelogs: [ReleaseChangelog] = [
|
|
5
|
+
ReleaseChangelog(version: "3.1.0", markdown: "Software updates are more reliable, with clearer progress and recovery when the glasses restart.\n\n- MentraOS, Mentra Engine, the Bluetooth SDK, and the glasses client now share one coordinated release version.\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic."),
|
|
6
|
+
]
|
|
@@ -3,9 +3,9 @@ import Foundation
|
|
|
3
3
|
/// Generated by release CI. Do not edit in a release checkout.
|
|
4
4
|
enum GeneratedReleaseMetadata {
|
|
5
5
|
static let familyBaseVersion = "3.1.0"
|
|
6
|
-
static let releaseIdentity = "3.1.0-dev.
|
|
7
|
-
static let releaseSetId = "mentra-3.1.0-dev.
|
|
8
|
-
static let sourceCommit = "
|
|
9
|
-
static let otaManifestUrl = "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-v3.1.0
|
|
10
|
-
static let otaManifestSha256 = "
|
|
6
|
+
static let releaseIdentity = "3.1.0-dev.101"
|
|
7
|
+
static let releaseSetId = "mentra-3.1.0-dev.101"
|
|
8
|
+
static let sourceCommit = "7cbd0579aa228fcfd4d36adda6de1150c3a43647"
|
|
9
|
+
static let otaManifestUrl = "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.1.0/mentra-live-ota-3.1.0-dev.101.json"
|
|
10
|
+
static let otaManifestSha256 = "37c1d4399b7d7a9bf973138bca4035e930df80cf67da828a3e54049ed0034802"
|
|
11
11
|
}
|
|
@@ -311,6 +311,7 @@ public final class MentraBluetoothSDK {
|
|
|
311
311
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "project_name", device.projectName ?? "")
|
|
312
312
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_name", "")
|
|
313
313
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_address", "")
|
|
314
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_secure_pairing_capable", "")
|
|
314
315
|
finishDefaultDeviceApply(generation: generation)
|
|
315
316
|
}
|
|
316
317
|
|
|
@@ -324,6 +325,7 @@ public final class MentraBluetoothSDK {
|
|
|
324
325
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "project_name", "")
|
|
325
326
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_name", "")
|
|
326
327
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_address", "")
|
|
328
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_secure_pairing_capable", "")
|
|
327
329
|
finishDefaultDeviceApply(generation: generation)
|
|
328
330
|
}
|
|
329
331
|
|
|
@@ -401,6 +403,11 @@ public final class MentraBluetoothSDK {
|
|
|
401
403
|
} else if !isController {
|
|
402
404
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_name", device.name)
|
|
403
405
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_address", device.identifier ?? "")
|
|
406
|
+
DeviceStore.shared.apply(
|
|
407
|
+
ObservableStore.bluetoothCategory,
|
|
408
|
+
"pending_device_secure_pairing_capable",
|
|
409
|
+
device.securePairingCapable ?? ""
|
|
410
|
+
)
|
|
404
411
|
}
|
|
405
412
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_wearable", device.model.deviceType)
|
|
406
413
|
DeviceManager.shared.connectByName(device.name)
|
|
@@ -427,6 +434,7 @@ public final class MentraBluetoothSDK {
|
|
|
427
434
|
clearBluetoothRestoreIntent()
|
|
428
435
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_name", "")
|
|
429
436
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_address", "")
|
|
437
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_secure_pairing_capable", "")
|
|
430
438
|
DeviceManager.shared.disconnect()
|
|
431
439
|
}
|
|
432
440
|
|
|
@@ -439,6 +447,7 @@ public final class MentraBluetoothSDK {
|
|
|
439
447
|
clearBluetoothRestoreIntent()
|
|
440
448
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_name", "")
|
|
441
449
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_address", "")
|
|
450
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "pending_device_secure_pairing_capable", "")
|
|
442
451
|
DeviceManager.shared.disconnect()
|
|
443
452
|
}
|
|
444
453
|
|
|
@@ -1250,6 +1259,14 @@ public final class MentraBluetoothSDK {
|
|
|
1250
1259
|
)
|
|
1251
1260
|
}
|
|
1252
1261
|
|
|
1262
|
+
/// Return bundled release changelogs crossed between two coordinated product versions, newest first.
|
|
1263
|
+
public func getReleaseChangelogs(
|
|
1264
|
+
fromVersion: String? = nil,
|
|
1265
|
+
toVersion: String? = nil
|
|
1266
|
+
) throws -> [ReleaseChangelog] {
|
|
1267
|
+
try ReleaseChangelogCatalog.select(fromVersion: fromVersion, toVersion: toVersion)
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1253
1270
|
/// Ask connected Mentra Live glasses to report the current OTA install/session status.
|
|
1254
1271
|
private func queryOtaStatus() async throws -> OtaQueryResult {
|
|
1255
1272
|
try await performOtaQuery(operation: "OTA status query") {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// One coordinated Mentra release note authored in /changelogs/<version>.md.
|
|
4
|
+
public struct ReleaseChangelog: Equatable, Sendable {
|
|
5
|
+
public let version: String
|
|
6
|
+
public let markdown: String
|
|
7
|
+
|
|
8
|
+
public init(version: String, markdown: String) {
|
|
9
|
+
self.version = version
|
|
10
|
+
self.markdown = markdown
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
enum ReleaseChangelogCatalog {
|
|
15
|
+
static func select(fromVersion: String?, toVersion: String?) throws -> [ReleaseChangelog] {
|
|
16
|
+
let fallbackTarget = GeneratedReleaseMetadata.familyBaseVersion.isEmpty
|
|
17
|
+
? (generatedReleaseChangelogs.first?.version ?? "")
|
|
18
|
+
: GeneratedReleaseMetadata.familyBaseVersion
|
|
19
|
+
if fallbackTarget.isEmpty, toVersion == nil { return [] }
|
|
20
|
+
let target = try baseVersion(toVersion ?? fallbackTarget, label: "toVersion")
|
|
21
|
+
guard generatedReleaseChangelogs.contains(where: { $0.version == target }) else {
|
|
22
|
+
throw BluetoothSdkError(code: "missing_changelog", message: "No changelog is bundled for target version \(target).")
|
|
23
|
+
}
|
|
24
|
+
guard let fromVersion else {
|
|
25
|
+
return generatedReleaseChangelogs.filter { $0.version == target }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let source = try baseVersion(fromVersion, label: "fromVersion")
|
|
29
|
+
let direction = compareVersions(target, source)
|
|
30
|
+
return generatedReleaseChangelogs.filter { entry in
|
|
31
|
+
if direction == 0 { return entry.version == target }
|
|
32
|
+
if direction > 0 {
|
|
33
|
+
return compareVersions(entry.version, source) > 0 && compareVersions(entry.version, target) <= 0
|
|
34
|
+
}
|
|
35
|
+
return compareVersions(entry.version, source) < 0 && compareVersions(entry.version, target) >= 0
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private static func baseVersion(_ version: String, label: String) throws -> String {
|
|
40
|
+
let value = version.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
41
|
+
let suffixStart = value.firstIndex(where: { $0 == "-" || $0 == "+" }) ?? value.endIndex
|
|
42
|
+
let components = value[..<suffixStart].split(separator: ".", omittingEmptySubsequences: false)
|
|
43
|
+
let isValid = components.count == 3 && components.allSatisfy { component in
|
|
44
|
+
!component.isEmpty
|
|
45
|
+
&& (component == "0" || !component.hasPrefix("0"))
|
|
46
|
+
&& component.utf8.allSatisfy { byte in byte >= 48 && byte <= 57 }
|
|
47
|
+
}
|
|
48
|
+
guard isValid else {
|
|
49
|
+
throw BluetoothSdkError(
|
|
50
|
+
code: "invalid_changelog_version",
|
|
51
|
+
message: "\(label) must be a semantic version such as 3.1.0, 3.1.0-dev.4, or 3.1.0-beta.2."
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
return components.joined(separator: ".")
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private static func compareVersions(_ left: String, _ right: String) -> Int {
|
|
58
|
+
let a = left.split(separator: ".").map { Int($0) ?? 0 }
|
|
59
|
+
let b = right.split(separator: ".").map { Int($0) ?? 0 }
|
|
60
|
+
for index in 0 ..< 3 where a[index] != b[index] {
|
|
61
|
+
return a[index] - b[index]
|
|
62
|
+
}
|
|
63
|
+
return 0
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -25,6 +25,35 @@ struct MentraLiveDevice {
|
|
|
25
25
|
let address: String
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
enum MentraLivePendingPairingTarget {
|
|
29
|
+
static func matches(
|
|
30
|
+
connectedName: String,
|
|
31
|
+
connectedIdentifier: String,
|
|
32
|
+
pendingName: String,
|
|
33
|
+
pendingIdentifier: String
|
|
34
|
+
) -> Bool {
|
|
35
|
+
if !pendingIdentifier.isEmpty {
|
|
36
|
+
return connectedIdentifier.caseInsensitiveCompare(pendingIdentifier) == .orderedSame
|
|
37
|
+
}
|
|
38
|
+
return !pendingName.isEmpty && connectedName == pendingName
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static func shouldRecover(
|
|
42
|
+
isConnected: Bool,
|
|
43
|
+
connectedName: String,
|
|
44
|
+
connectedIdentifier: String,
|
|
45
|
+
pendingName: String,
|
|
46
|
+
pendingIdentifier: String
|
|
47
|
+
) -> Bool {
|
|
48
|
+
isConnected && matches(
|
|
49
|
+
connectedName: connectedName,
|
|
50
|
+
connectedIdentifier: connectedIdentifier,
|
|
51
|
+
pendingName: pendingName,
|
|
52
|
+
pendingIdentifier: pendingIdentifier
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
28
57
|
// MARK: - BlePhotoUploadService
|
|
29
58
|
|
|
30
59
|
class BlePhotoUploadService {
|
|
@@ -873,9 +902,10 @@ extension MentraLive: CBCentralManagerDelegate {
|
|
|
873
902
|
if !isReconnectTarget && advertisesPairingFlag(advertisementData)
|
|
874
903
|
&& !isPairingDiscoverable(advertisementData)
|
|
875
904
|
{
|
|
876
|
-
//
|
|
905
|
+
// Keep nearby secure units visible with pairing-mode guidance, while RN blocks
|
|
906
|
+
// the connection until a pairable advertisement arrives.
|
|
877
907
|
Bridge.log(
|
|
878
|
-
"LIVE: Nearby \(name) is secure firmware not in pairing mode —
|
|
908
|
+
"LIVE: Nearby \(name) is secure firmware not in pairing mode — exposing as non-pairable"
|
|
879
909
|
)
|
|
880
910
|
discoveredPeripherals[name] = peripheral
|
|
881
911
|
cacheAdvPairing(
|
|
@@ -967,6 +997,7 @@ extension MentraLive: CBCentralManagerDelegate {
|
|
|
967
997
|
self.isConnecting = false
|
|
968
998
|
self.connectingPeripheral = nil
|
|
969
999
|
self.connectedPeripheral = peripheral
|
|
1000
|
+
self.emitConnectedPendingDeviceForPairingScan()
|
|
970
1001
|
|
|
971
1002
|
// Save device name and address for future reconnection
|
|
972
1003
|
if let name = peripheral.name {
|
|
@@ -1618,6 +1649,7 @@ class MentraLive: NSObject, SGCManager {
|
|
|
1618
1649
|
|
|
1619
1650
|
// State Tracking
|
|
1620
1651
|
private var isScanning = false
|
|
1652
|
+
private var manualDiscoveryActive = false
|
|
1621
1653
|
private var isConnecting = false
|
|
1622
1654
|
private var isKilled = false
|
|
1623
1655
|
/// Glasses opened pairing window — stand down without forgetting identity/bonds.
|
|
@@ -1772,7 +1804,9 @@ class MentraLive: NSObject, SGCManager {
|
|
|
1772
1804
|
// clear the saved device name:
|
|
1773
1805
|
UserDefaults.standard.set("", forKey: PREFS_DEVICE_NAME)
|
|
1774
1806
|
|
|
1807
|
+
manualDiscoveryActive = true
|
|
1775
1808
|
startScan()
|
|
1809
|
+
emitConnectedPendingDeviceForPairingScan()
|
|
1776
1810
|
}
|
|
1777
1811
|
}
|
|
1778
1812
|
|
|
@@ -2364,10 +2398,6 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2364
2398
|
|
|
2365
2399
|
centralManager?.scanForPeripherals(withServices: nil, options: scanOptions)
|
|
2366
2400
|
|
|
2367
|
-
// Fresh advertisements refill pairing metadata. Re-emitting the last scan's
|
|
2368
|
-
// cache would keep a unit pairable after it left pairing mode.
|
|
2369
|
-
emitConnectedDeviceForPairingScan()
|
|
2370
|
-
|
|
2371
2401
|
// var dName = DeviceManager.shared.deviceName
|
|
2372
2402
|
// if dName.isEmpty {
|
|
2373
2403
|
// dName = "MENTRA_LIVE"
|
|
@@ -2385,6 +2415,7 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2385
2415
|
}
|
|
2386
2416
|
|
|
2387
2417
|
func stopScan() {
|
|
2418
|
+
manualDiscoveryActive = false
|
|
2388
2419
|
guard isScanning else { return }
|
|
2389
2420
|
|
|
2390
2421
|
centralManager?.stopScan()
|
|
@@ -5502,22 +5533,33 @@ class MentraLive: NSObject, SGCManager {
|
|
|
5502
5533
|
|
|
5503
5534
|
// MARK: - Event Emission
|
|
5504
5535
|
|
|
5505
|
-
///
|
|
5506
|
-
///
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5536
|
+
/// A selected pairing target can stop advertising once GATT connects, before readiness
|
|
5537
|
+
/// promotes it to the default device. Re-emit only that explicit pending target; an
|
|
5538
|
+
/// established owner's connected glasses have no pending identity and remain hidden.
|
|
5539
|
+
private func emitConnectedPendingDeviceForPairingScan() {
|
|
5540
|
+
guard manualDiscoveryActive, !pairingYieldActive, let peripheral = connectedPeripheral,
|
|
5541
|
+
let name = peripheral.name,
|
|
5542
|
+
MentraLivePendingPairingTarget.shouldRecover(
|
|
5543
|
+
isConnected: peripheral.state == .connected,
|
|
5544
|
+
connectedName: name,
|
|
5545
|
+
connectedIdentifier: peripheral.identifier.uuidString,
|
|
5546
|
+
pendingName: DeviceStore.shared.get("bluetooth", "pending_device_name") as? String ?? "",
|
|
5547
|
+
pendingIdentifier: DeviceStore.shared.get("bluetooth", "pending_device_address") as? String ?? ""
|
|
5548
|
+
)
|
|
5511
5549
|
else {
|
|
5512
5550
|
return
|
|
5513
5551
|
}
|
|
5514
|
-
|
|
5552
|
+
|
|
5553
|
+
Bridge.log("LIVE: Pairing scan: recovering connected pending target \(name) (\(peripheral.identifier))")
|
|
5515
5554
|
emitDiscoveredDevice(
|
|
5516
5555
|
name,
|
|
5517
5556
|
identifier: peripheral.identifier.uuidString,
|
|
5518
5557
|
pairingMode: true,
|
|
5519
5558
|
pairingCode: nil,
|
|
5520
|
-
securePairingCapable:
|
|
5559
|
+
securePairingCapable: DeviceStore.shared.get(
|
|
5560
|
+
"bluetooth",
|
|
5561
|
+
"pending_device_secure_pairing_capable"
|
|
5562
|
+
) as? Bool
|
|
5521
5563
|
)
|
|
5522
5564
|
}
|
|
5523
5565
|
|
|
@@ -3,6 +3,62 @@ import Foundation
|
|
|
3
3
|
import XCTest
|
|
4
4
|
|
|
5
5
|
final class MentraLivePairingAdvertisementTests: XCTestCase {
|
|
6
|
+
func testConnectedPairingRecoveryRequiresExplicitPendingTarget() {
|
|
7
|
+
XCTAssertFalse(
|
|
8
|
+
MentraLivePendingPairingTarget.matches(
|
|
9
|
+
connectedName: "MENTRA_LIVE_BLE_OWNER",
|
|
10
|
+
connectedIdentifier: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
|
|
11
|
+
pendingName: "",
|
|
12
|
+
pendingIdentifier: ""
|
|
13
|
+
)
|
|
14
|
+
)
|
|
15
|
+
XCTAssertTrue(
|
|
16
|
+
MentraLivePendingPairingTarget.matches(
|
|
17
|
+
connectedName: "MENTRA_LIVE_BLE_TARGET",
|
|
18
|
+
connectedIdentifier: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
|
|
19
|
+
pendingName: "MENTRA_LIVE_BLE_TARGET",
|
|
20
|
+
pendingIdentifier: ""
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
XCTAssertTrue(
|
|
24
|
+
MentraLivePendingPairingTarget.matches(
|
|
25
|
+
connectedName: "MENTRA_LIVE_BLE_TARGET",
|
|
26
|
+
connectedIdentifier: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
|
|
27
|
+
pendingName: "OTHER",
|
|
28
|
+
pendingIdentifier: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
XCTAssertFalse(
|
|
32
|
+
MentraLivePendingPairingTarget.matches(
|
|
33
|
+
connectedName: "MENTRA_LIVE_BLE_TARGET",
|
|
34
|
+
connectedIdentifier: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
|
|
35
|
+
pendingName: "MENTRA_LIVE_BLE_TARGET",
|
|
36
|
+
pendingIdentifier: "11111111-2222-3333-4444-555555555555"
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
func testConnectedPairingRecoveryRequiresActiveGattConnection() {
|
|
42
|
+
XCTAssertFalse(
|
|
43
|
+
MentraLivePendingPairingTarget.shouldRecover(
|
|
44
|
+
isConnected: false,
|
|
45
|
+
connectedName: "MENTRA_LIVE_BLE_TARGET",
|
|
46
|
+
connectedIdentifier: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
|
|
47
|
+
pendingName: "MENTRA_LIVE_BLE_TARGET",
|
|
48
|
+
pendingIdentifier: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
XCTAssertTrue(
|
|
52
|
+
MentraLivePendingPairingTarget.shouldRecover(
|
|
53
|
+
isConnected: true,
|
|
54
|
+
connectedName: "MENTRA_LIVE_BLE_TARGET",
|
|
55
|
+
connectedIdentifier: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
|
|
56
|
+
pendingName: "MENTRA_LIVE_BLE_TARGET",
|
|
57
|
+
pendingIdentifier: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
6
62
|
func testConnectionCallbackPolicyRejectsPairingYieldAndStaleAttempts() {
|
|
7
63
|
XCTAssertFalse(
|
|
8
64
|
MentraLiveConnectionAttemptPolicy.shouldAcceptDidConnect(
|