You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.9 KiB
127 lines
3.9 KiB
import Foundation
|
|
|
|
#if canImport(JL_BLEKit)
|
|
import JL_BLEKit
|
|
#endif
|
|
#if canImport(JL_OTALib)
|
|
import JL_OTALib
|
|
#endif
|
|
|
|
/// OTA via JL_OTALib + `JL_BLEMultiple.otaFunc...`. Mirrors Android
|
|
/// `feature/ota/OtaFeature.kt`.
|
|
///
|
|
/// Drives `JL_BLEMultiple.otaFunc(withEntityM:withFilePath:Result:)` (the
|
|
/// "simple" path used by the iOS demo) and remaps the `JL_OTAResult` /
|
|
/// progress callback into the same `otaState` / `otaError` event shapes
|
|
/// the Android side publishes — Dart `_parseOtaState(...)` keeps working
|
|
/// unchanged.
|
|
public class OtaFeature {
|
|
|
|
weak var server: JieliHomeServer?
|
|
init(server: JieliHomeServer) { self.server = server }
|
|
|
|
private var running: Bool = false
|
|
|
|
public func isRunning() -> Bool { running }
|
|
|
|
public func start(
|
|
address: String?,
|
|
firmwareFilePath: String,
|
|
blockSize: Int,
|
|
fileFlag: Data?
|
|
) {
|
|
if running { return }
|
|
#if canImport(JL_BLEKit)
|
|
guard let server = server,
|
|
let entity = server.connectFeature.currentEntity() as? JL_EntityM else {
|
|
server?.dispatcher.send([
|
|
"type": "otaError",
|
|
"code": -1,
|
|
"message": "no active session",
|
|
])
|
|
return
|
|
}
|
|
running = true
|
|
server.dispatcher.send([
|
|
"type": "otaState",
|
|
"state": "INQUIRING",
|
|
"sent": 0, "total": 0, "percent": -1, "tsMs": Self.tsMs(),
|
|
])
|
|
server.bleMultiple.otaFunc(withEntityM: entity, withFilePath: firmwareFilePath) { [weak self] result, progress in
|
|
self?.onOtaCallback(result: result, progress: progress)
|
|
}
|
|
#else
|
|
server?.dispatcher.send([
|
|
"type": "otaError",
|
|
"code": -1,
|
|
"message": "JL_OTALib not linked",
|
|
])
|
|
#endif
|
|
}
|
|
|
|
public func cancel() {
|
|
if !running { return }
|
|
running = false
|
|
server?.dispatcher.send([
|
|
"type": "otaState",
|
|
"state": "CANCELLED",
|
|
"sent": 0, "total": 0, "percent": -1, "tsMs": Self.tsMs(),
|
|
])
|
|
}
|
|
|
|
#if canImport(JL_OTALib)
|
|
/// Map `JL_OTAResult` (~30 distinct cases) to the smaller Android-style
|
|
/// state machine used by Dart. We funnel "in-progress / preparing /
|
|
/// upgrading" into TRANSFERRING with the float `progress` (0..1) scaled
|
|
/// to 0..100, terminal success → DONE, anything else → FAILED.
|
|
private func onOtaCallback(result: JL_OTAResult, progress: Float) {
|
|
guard let server = server else { return }
|
|
switch result {
|
|
case .preparing, .prepared:
|
|
server.dispatcher.send([
|
|
"type": "otaState", "state": "ENTERING",
|
|
"sent": 0, "total": 0, "percent": -1, "tsMs": Self.tsMs(),
|
|
])
|
|
case .upgrading:
|
|
let percent = max(0, min(100, Int(progress * 100)))
|
|
server.dispatcher.send([
|
|
"type": "otaState", "state": "TRANSFERRING",
|
|
"sent": 0, "total": 0, "percent": percent, "tsMs": Self.tsMs(),
|
|
])
|
|
case .reboot, .reconnect, .reconnectWithMacAddr, .reconnectUpdateSource:
|
|
server.dispatcher.send([
|
|
"type": "otaState", "state": "REBOOTING",
|
|
"sent": 0, "total": 0, "percent": 100, "tsMs": Self.tsMs(),
|
|
])
|
|
case .success:
|
|
running = false
|
|
server.dispatcher.send([
|
|
"type": "otaState", "state": "DONE",
|
|
"sent": 0, "total": 0, "percent": 100, "tsMs": Self.tsMs(),
|
|
])
|
|
case .cancel:
|
|
running = false
|
|
server.dispatcher.send([
|
|
"type": "otaState", "state": "CANCELLED",
|
|
"sent": 0, "total": 0, "percent": -1, "tsMs": Self.tsMs(),
|
|
])
|
|
default:
|
|
// Anything else from the JL_OTAResult enum is a terminal failure.
|
|
running = false
|
|
server.dispatcher.send([
|
|
"type": "otaState", "state": "FAILED",
|
|
"sent": 0, "total": 0, "percent": -1, "tsMs": Self.tsMs(),
|
|
])
|
|
server.dispatcher.send([
|
|
"type": "otaError",
|
|
"code": Int(result.rawValue),
|
|
"message": "JL_OTAResult=\(result.rawValue)",
|
|
])
|
|
}
|
|
}
|
|
#endif
|
|
|
|
private static func tsMs() -> Int {
|
|
Int(Date().timeIntervalSince1970 * 1000)
|
|
}
|
|
}
|
|
|