@mentra/bluetooth-sdk 0.1.13 → 0.1.16
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 +18 -8
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +48 -48
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +5 -20
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +360 -269
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +3 -7
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +152 -72
- package/android/src/main/java/com/mentra/bluetoothsdk/OtaManifest.kt +12 -12
- package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +25 -11
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +1 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +1 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +1 -22
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.kt +51 -8
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +1184 -800
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.kt +1 -5
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +423 -117
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +4 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Nimo.kt +2532 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +17 -5
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +3 -7
- package/android/src/main/java/com/mentra/bluetoothsdk/status/DeviceStatus.kt +0 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +16 -33
- package/android/src/main/java/com/mentra/bluetoothsdk/types/DeviceModels.kt +5 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +2 -1
- package/android/src/test/java/com/mentra/bluetoothsdk/camera/PhotoRequestTest.kt +60 -1
- package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoProtocolTest.kt +333 -0
- package/build/BluetoothSdk.types.d.ts +50 -24
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js +1 -0
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_internal.d.ts +4 -4
- package/build/_internal.js +4 -4
- package/build/_internal.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts +14 -8
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js +4 -3
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/build/_private/cameraRequestPayload.d.ts +4 -0
- package/build/_private/cameraRequestPayload.d.ts.map +1 -0
- package/build/_private/cameraRequestPayload.js +25 -0
- package/build/_private/cameraRequestPayload.js.map +1 -0
- package/build/_private/photoRequestPayload.d.ts.map +1 -1
- package/build/_private/photoRequestPayload.js +11 -3
- package/build/_private/photoRequestPayload.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +70 -61
- package/build/index.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +51 -28
- package/ios/Source/Bridge.swift +4 -16
- package/ios/Source/DeviceManager.swift +76 -22
- package/ios/Source/DeviceStore.swift +0 -4
- package/ios/Source/MentraBluetoothSDK.swift +144 -78
- package/ios/Source/OtaManifest.swift +13 -13
- package/ios/Source/camera/CameraModels.swift +82 -20
- package/ios/Source/controllers/ControllerManager.swift +1 -2
- package/ios/Source/controllers/R1.swift +1 -2
- package/ios/Source/errors/{BluetoothError.swift → BluetoothSdkError.swift} +1 -1
- package/ios/Source/events/BluetoothEvents.swift +5 -27
- package/ios/Source/internal/BluetoothAvailability.swift +5 -5
- package/ios/Source/sgcs/Frame.swift +0 -2
- package/ios/Source/sgcs/G1.swift +52 -4
- package/ios/Source/sgcs/G2.swift +643 -204
- package/ios/Source/sgcs/Mach1.swift +1 -3
- package/ios/Source/sgcs/MentraLive.swift +64 -77
- package/ios/Source/sgcs/MentraNex.swift +1 -3
- package/ios/Source/sgcs/Nimo.swift +1928 -0
- package/ios/Source/sgcs/SGCManager.swift +16 -10
- package/ios/Source/sgcs/Simulated.swift +2 -6
- package/ios/Source/status/DeviceStatus.swift +0 -8
- package/ios/Source/streaming/StreamModels.swift +7 -32
- package/ios/Source/stt/STTTools.swift +1 -1
- package/ios/Source/types/DeviceModels.swift +5 -0
- package/ios/Source/utils/Constants.swift +2 -0
- package/package.json +6 -1
- package/src/BluetoothSdk.types.ts +54 -28
- package/src/_internal.ts +4 -4
- package/src/_private/BluetoothSdkModule.ts +20 -11
- package/src/_private/cameraRequestPayload.ts +29 -0
- package/src/_private/photoRequestPayload.ts +12 -3
- package/src/index.ts +77 -67
|
@@ -34,8 +34,6 @@ class Mach1: UltraliteBaseViewController, SGCManager {
|
|
|
34
34
|
|
|
35
35
|
func sendButtonMaxRecordingTime(_: Int) {}
|
|
36
36
|
|
|
37
|
-
func sendButtonCameraLedSetting() {}
|
|
38
|
-
|
|
39
37
|
func sendCameraFovSetting() {}
|
|
40
38
|
|
|
41
39
|
func exit() {}
|
|
@@ -87,7 +85,7 @@ class Mach1: UltraliteBaseViewController, SGCManager {
|
|
|
87
85
|
|
|
88
86
|
func sendStreamKeepAlive(_: [String: Any]) {}
|
|
89
87
|
|
|
90
|
-
func startVideoRecording(requestId _: String, save _: Bool,
|
|
88
|
+
func startVideoRecording(requestId _: String, save _: Bool, sound _: Bool) {}
|
|
91
89
|
|
|
92
90
|
func stopVideoRecording(requestId _: String) {}
|
|
93
91
|
|
|
@@ -1616,13 +1616,12 @@ class MentraLive: NSObject, SGCManager {
|
|
|
1616
1616
|
|
|
1617
1617
|
func requestPhoto(_ request: PhotoRequest) {
|
|
1618
1618
|
Bridge.log(
|
|
1619
|
-
"LIVE: PHOTO PIPELINE [5/6] requestPhoto() entry requestId=\(request.requestId)
|
|
1619
|
+
"LIVE: PHOTO PIPELINE [5/6] requestPhoto() entry requestId=\(request.requestId) save=\(request.save) sound=\(request.sound) iso=\(request.iso.map { String($0) } ?? "auto") aeDivisor=\(request.aeExposureDivisor.map { String($0) } ?? "nil")"
|
|
1620
1620
|
)
|
|
1621
1621
|
|
|
1622
1622
|
var json: [String: Any] = [
|
|
1623
1623
|
"type": "take_photo",
|
|
1624
1624
|
"requestId": request.requestId,
|
|
1625
|
-
"appId": request.appId,
|
|
1626
1625
|
]
|
|
1627
1626
|
|
|
1628
1627
|
// Always generate BLE ID for potential fallback
|
|
@@ -1656,7 +1655,6 @@ class MentraLive: NSObject, SGCManager {
|
|
|
1656
1655
|
json["size"] = allowedSizes.contains(size) ? size : "medium"
|
|
1657
1656
|
|
|
1658
1657
|
json["compress"] = request.compress?.rawValue ?? "none"
|
|
1659
|
-
json["flash"] = request.flash
|
|
1660
1658
|
json["save"] = request.save
|
|
1661
1659
|
json["sound"] = request.sound
|
|
1662
1660
|
|
|
@@ -1676,6 +1674,32 @@ class MentraLive: NSObject, SGCManager {
|
|
|
1676
1674
|
sendJson(json, wakeUp: true)
|
|
1677
1675
|
}
|
|
1678
1676
|
|
|
1677
|
+
func warmUpCamera(
|
|
1678
|
+
requestId: String,
|
|
1679
|
+
size: PhotoSize,
|
|
1680
|
+
exposureTimeNs: Double?,
|
|
1681
|
+
durationMs: Int
|
|
1682
|
+
) {
|
|
1683
|
+
Bridge.log(
|
|
1684
|
+
"LIVE: warmUpCamera() entry requestId=\(requestId) size=\(size.rawValue) durationMs=\(durationMs)"
|
|
1685
|
+
)
|
|
1686
|
+
|
|
1687
|
+
let allowedSizes = ["low", "medium", "high", "max"]
|
|
1688
|
+
let sizeRaw = size.rawValue
|
|
1689
|
+
var json: [String: Any] = [
|
|
1690
|
+
"type": "camera_warm_up",
|
|
1691
|
+
"requestId": requestId,
|
|
1692
|
+
"size": allowedSizes.contains(sizeRaw) ? sizeRaw : "medium",
|
|
1693
|
+
"durationMs": durationMs > 0 ? durationMs : 15000,
|
|
1694
|
+
]
|
|
1695
|
+
|
|
1696
|
+
if let e = exposureTimeNs, e.isFinite, e > 0, e <= Double(Int64.max) {
|
|
1697
|
+
json["exposureTimeNs"] = Int64(e)
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
sendJson(json, wakeUp: true)
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1679
1703
|
func startStream(_ message: [String: Any]) {
|
|
1680
1704
|
Bridge.log("Starting stream")
|
|
1681
1705
|
var json = message
|
|
@@ -2173,6 +2197,9 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2173
2197
|
case "photo_status":
|
|
2174
2198
|
emitPhotoStatus(json)
|
|
2175
2199
|
|
|
2200
|
+
case "camera_status":
|
|
2201
|
+
emitCameraStatus(json)
|
|
2202
|
+
|
|
2176
2203
|
case "photo_response":
|
|
2177
2204
|
emitPhotoResponse(json)
|
|
2178
2205
|
|
|
@@ -2284,32 +2311,6 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2284
2311
|
// Send to React Native via Bridge
|
|
2285
2312
|
Bridge.sendMtkUpdateComplete(message: updateMessage, timestamp: timestamp)
|
|
2286
2313
|
|
|
2287
|
-
case "ota_update_available":
|
|
2288
|
-
// Process OTA update available notification from glasses (background mode)
|
|
2289
|
-
Bridge.log("📱 Received ota_update_available from glasses")
|
|
2290
|
-
|
|
2291
|
-
let versionCode = json["version_code"] as? Int64 ?? 0
|
|
2292
|
-
let versionName = json["version_name"] as? String ?? ""
|
|
2293
|
-
let totalSize = json["total_size"] as? Int64 ?? 0
|
|
2294
|
-
|
|
2295
|
-
// Parse updates array
|
|
2296
|
-
var updates: [String] = []
|
|
2297
|
-
if let updatesArray = json["updates"] as? [String] {
|
|
2298
|
-
updates = updatesArray
|
|
2299
|
-
}
|
|
2300
|
-
|
|
2301
|
-
Bridge.log(
|
|
2302
|
-
"📱 OTA available - version: \(versionName) (\(versionCode)), updates: \(updates), size: \(totalSize) bytes"
|
|
2303
|
-
)
|
|
2304
|
-
|
|
2305
|
-
// Send to React Native
|
|
2306
|
-
Bridge.sendOtaUpdateAvailable(
|
|
2307
|
-
versionCode: versionCode,
|
|
2308
|
-
versionName: versionName,
|
|
2309
|
-
updates: updates,
|
|
2310
|
-
totalSize: totalSize
|
|
2311
|
-
)
|
|
2312
|
-
|
|
2313
2314
|
case "ota_start_ack":
|
|
2314
2315
|
// Glasses acknowledged receipt of ota_start — phone can cancel its retry timer
|
|
2315
2316
|
Bridge.log("LIVE: 📱 Received ota_start_ack from glasses")
|
|
@@ -2905,17 +2906,6 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2905
2906
|
sendJson(json, wakeUp: true)
|
|
2906
2907
|
}
|
|
2907
2908
|
|
|
2908
|
-
func sendOtaRetryVersionCheck() {
|
|
2909
|
-
Bridge.log("LIVE: ⏰ Sending ota_retry_version_check command to glasses")
|
|
2910
|
-
|
|
2911
|
-
let json: [String: Any] = [
|
|
2912
|
-
"type": "ota_retry_version_check",
|
|
2913
|
-
"timestamp": Int(Date().timeIntervalSince1970 * 1000),
|
|
2914
|
-
]
|
|
2915
|
-
|
|
2916
|
-
sendJson(json, wakeUp: true)
|
|
2917
|
-
}
|
|
2918
|
-
|
|
2919
2909
|
func keepAwake() {
|
|
2920
2910
|
Bridge.log("LIVE: 📱 Sending keep_awake command to glasses")
|
|
2921
2911
|
|
|
@@ -4347,6 +4337,10 @@ class MentraLive: NSObject, SGCManager {
|
|
|
4347
4337
|
Bridge.sendPhotoStatus(json)
|
|
4348
4338
|
}
|
|
4349
4339
|
|
|
4340
|
+
private func emitCameraStatus(_ json: [String: Any]) {
|
|
4341
|
+
Bridge.sendCameraStatus(json)
|
|
4342
|
+
}
|
|
4343
|
+
|
|
4350
4344
|
private func emitPhotoResponse(_ json: [String: Any]) {
|
|
4351
4345
|
Bridge.sendPhotoResponse(json)
|
|
4352
4346
|
}
|
|
@@ -5085,9 +5079,6 @@ extension MentraLive {
|
|
|
5085
5079
|
// Send button photo settings
|
|
5086
5080
|
sendButtonPhotoSettings()
|
|
5087
5081
|
|
|
5088
|
-
// Send button camera LED setting
|
|
5089
|
-
sendButtonCameraLedSetting()
|
|
5090
|
-
|
|
5091
5082
|
// Send camera FOV setting (K900 / Mentra Live)
|
|
5092
5083
|
sendCameraFovSetting()
|
|
5093
5084
|
|
|
@@ -5197,7 +5188,9 @@ extension MentraLive {
|
|
|
5197
5188
|
}
|
|
5198
5189
|
|
|
5199
5190
|
func sendButtonPhotoSettings() {
|
|
5200
|
-
let size = DeviceStore.shared.get("bluetooth", "button_photo_size") as? String
|
|
5191
|
+
let size = (DeviceStore.shared.get("bluetooth", "button_photo_size") as? String).flatMap { rawSize in
|
|
5192
|
+
rawSize.isEmpty ? nil : PhotoSize(normalizedRawValue: rawSize)
|
|
5193
|
+
}
|
|
5201
5194
|
let mfnr = DeviceStore.shared.get("bluetooth", "button_photo_mfnr") as? Bool
|
|
5202
5195
|
let zsl = DeviceStore.shared.get("bluetooth", "button_photo_zsl") as? Bool
|
|
5203
5196
|
let noiseReduction = DeviceStore.shared.get("bluetooth", "button_photo_noise_reduction") as? Bool
|
|
@@ -5209,8 +5202,8 @@ extension MentraLive {
|
|
|
5209
5202
|
let compressStr = DeviceStore.shared.get("bluetooth", "button_photo_compress") as? String
|
|
5210
5203
|
let sound = DeviceStore.shared.get("bluetooth", "button_photo_sound") as? Bool
|
|
5211
5204
|
|
|
5212
|
-
let settings =
|
|
5213
|
-
size:
|
|
5205
|
+
let settings = PhotoCaptureDefaults(
|
|
5206
|
+
size: size,
|
|
5214
5207
|
mfnr: mfnr,
|
|
5215
5208
|
zsl: zsl,
|
|
5216
5209
|
noiseReduction: noiseReduction,
|
|
@@ -5228,10 +5221,10 @@ extension MentraLive {
|
|
|
5228
5221
|
}
|
|
5229
5222
|
|
|
5230
5223
|
func sendButtonPhotoSettings(requestId: String?, size: String) {
|
|
5231
|
-
sendButtonPhotoSettings(requestId: requestId, settings:
|
|
5224
|
+
sendButtonPhotoSettings(requestId: requestId, settings: PhotoCaptureDefaults(size: PhotoSize(normalizedRawValue: size)))
|
|
5232
5225
|
}
|
|
5233
5226
|
|
|
5234
|
-
func sendButtonPhotoSettings(requestId: String?, settings:
|
|
5227
|
+
func sendButtonPhotoSettings(requestId: String?, settings: PhotoCaptureDefaults) {
|
|
5235
5228
|
var details = settings.size.map { "size=\($0.rawValue)" } ?? "size=unchanged"
|
|
5236
5229
|
if let mfnr = settings.mfnr {
|
|
5237
5230
|
details += ", mfnr=\(mfnr)"
|
|
@@ -5315,29 +5308,6 @@ extension MentraLive {
|
|
|
5315
5308
|
sendJson(json, wakeUp: true)
|
|
5316
5309
|
}
|
|
5317
5310
|
|
|
5318
|
-
func sendButtonCameraLedSetting() {
|
|
5319
|
-
let enabled = DeviceStore.shared.get("bluetooth", "button_camera_led") as! Bool
|
|
5320
|
-
sendButtonCameraLedSetting(requestId: nil, enabled: enabled)
|
|
5321
|
-
}
|
|
5322
|
-
|
|
5323
|
-
func sendButtonCameraLedSetting(requestId: String?, enabled: Bool) {
|
|
5324
|
-
Bridge.log("Sending button camera LED setting: \(enabled)")
|
|
5325
|
-
|
|
5326
|
-
guard connectionState == ConnTypes.CONNECTED else {
|
|
5327
|
-
Bridge.log("Cannot send button camera LED setting - not connected")
|
|
5328
|
-
return
|
|
5329
|
-
}
|
|
5330
|
-
|
|
5331
|
-
var json: [String: Any] = [
|
|
5332
|
-
"type": "button_camera_led",
|
|
5333
|
-
"enabled": enabled,
|
|
5334
|
-
]
|
|
5335
|
-
if let requestId, !requestId.isEmpty {
|
|
5336
|
-
json["request_id"] = requestId
|
|
5337
|
-
}
|
|
5338
|
-
sendJson(json, wakeUp: true)
|
|
5339
|
-
}
|
|
5340
|
-
|
|
5341
5311
|
func sendCameraFovSetting() {
|
|
5342
5312
|
let settings = DeviceStore.shared.get("bluetooth", "camera_fov") as? [String: Any] ?? ["fov": 118, "roi_position": 0]
|
|
5343
5313
|
let fov = settings["fov"] as? Int ?? 118
|
|
@@ -5366,9 +5336,28 @@ extension MentraLive {
|
|
|
5366
5336
|
sendJson(json, wakeUp: true)
|
|
5367
5337
|
}
|
|
5368
5338
|
|
|
5369
|
-
func
|
|
5339
|
+
func sendCameraTuningConfig(requestId: String?, anrOn: Bool, gainOn: Bool) {
|
|
5340
|
+
Bridge.log("Sending camera tuning config: anr=\(anrOn), gain=\(gainOn)")
|
|
5341
|
+
|
|
5342
|
+
guard connectionState == ConnTypes.CONNECTED else {
|
|
5343
|
+
Bridge.log("Cannot send camera tuning config - not connected")
|
|
5344
|
+
return
|
|
5345
|
+
}
|
|
5346
|
+
|
|
5347
|
+
var json: [String: Any] = [
|
|
5348
|
+
"type": "camera_tuning_config",
|
|
5349
|
+
"anr": anrOn,
|
|
5350
|
+
"gain": gainOn,
|
|
5351
|
+
]
|
|
5352
|
+
if let requestId, !requestId.isEmpty {
|
|
5353
|
+
json["request_id"] = requestId
|
|
5354
|
+
}
|
|
5355
|
+
sendJson(json, wakeUp: true)
|
|
5356
|
+
}
|
|
5357
|
+
|
|
5358
|
+
func startVideoRecording(requestId: String, save: Bool, sound: Bool) {
|
|
5370
5359
|
startVideoRecording(
|
|
5371
|
-
requestId: requestId, save: save,
|
|
5360
|
+
requestId: requestId, save: save, sound: sound, width: 0, height: 0, fps: 0,
|
|
5372
5361
|
maxRecordingTimeMinutes: 0
|
|
5373
5362
|
)
|
|
5374
5363
|
}
|
|
@@ -5380,11 +5369,11 @@ extension MentraLive {
|
|
|
5380
5369
|
}
|
|
5381
5370
|
|
|
5382
5371
|
func startVideoRecording(
|
|
5383
|
-
requestId: String, save: Bool,
|
|
5372
|
+
requestId: String, save: Bool, sound: Bool, width: Int, height: Int, fps: Int,
|
|
5384
5373
|
maxRecordingTimeMinutes: Int
|
|
5385
5374
|
) {
|
|
5386
5375
|
Bridge.log(
|
|
5387
|
-
"Starting video recording on glasses: requestId=\(requestId), save=\(save),
|
|
5376
|
+
"Starting video recording on glasses: requestId=\(requestId), save=\(save), sound=\(sound), resolution=\(width)x\(height)@\(fps)fps, maxRecordingTimeMinutes=\(maxRecordingTimeMinutes)"
|
|
5388
5377
|
)
|
|
5389
5378
|
|
|
5390
5379
|
guard connectionState == ConnTypes.CONNECTED else {
|
|
@@ -5396,10 +5385,8 @@ extension MentraLive {
|
|
|
5396
5385
|
"type": "start_video_recording",
|
|
5397
5386
|
"requestId": requestId,
|
|
5398
5387
|
"save": save,
|
|
5399
|
-
"flash": flash,
|
|
5400
5388
|
"sound": sound,
|
|
5401
5389
|
]
|
|
5402
|
-
|
|
5403
5390
|
// Auto-stop timer; only sent when set (> 0). 0 = record until stopped.
|
|
5404
5391
|
if maxRecordingTimeMinutes > 0 {
|
|
5405
5392
|
json["maxRecordingTimeMinutes"] = maxRecordingTimeMinutes
|
|
@@ -59,7 +59,7 @@ class MentraNexSGC: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate, SG
|
|
|
59
59
|
|
|
60
60
|
func sendStreamKeepAlive(_: [String: Any]) {}
|
|
61
61
|
|
|
62
|
-
func startVideoRecording(requestId _: String, save _: Bool,
|
|
62
|
+
func startVideoRecording(requestId _: String, save _: Bool, sound _: Bool) {}
|
|
63
63
|
|
|
64
64
|
func stopVideoRecording(requestId _: String) {}
|
|
65
65
|
|
|
@@ -69,8 +69,6 @@ class MentraNexSGC: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate, SG
|
|
|
69
69
|
|
|
70
70
|
func sendButtonMaxRecordingTime() {}
|
|
71
71
|
|
|
72
|
-
func sendButtonCameraLedSetting() {}
|
|
73
|
-
|
|
74
72
|
func sendCameraFovSetting() {}
|
|
75
73
|
|
|
76
74
|
func setBrightness(_ level: Int, autoMode: Bool) {
|