mirror of
https://github.com/seemoo-lab/openhaystack.git
synced 2026-02-25 15:03:48 +00:00
68 lines
2.2 KiB
Swift
68 lines
2.2 KiB
Swift
//
|
||
// OpenHaystack – Tracking personal Bluetooth devices via Apple's Find My network
|
||
//
|
||
// Copyright © 2021 Secure Mobile Networking Lab (SEEMOO)
|
||
// Copyright © 2021 The Open Wireless Link Project
|
||
//
|
||
// SPDX-License-Identifier: AGPL-3.0-only
|
||
//
|
||
|
||
import Foundation
|
||
|
||
struct ESP32Controller {
|
||
static var espFirmwareDirectory: URL? {
|
||
Bundle.main.resourceURL?.appendingPathComponent("ESP32")
|
||
}
|
||
|
||
/// Tries to find the port / path at which the ESP32 module is attached
|
||
static func findPort() -> [URL] {
|
||
// List all ports
|
||
let ports = try? FileManager.default.contentsOfDirectory(atPath: "/dev").filter({ $0.contains("cu.") })
|
||
|
||
let portURLs = ports?.map({ URL(fileURLWithPath: "/dev/\($0)") })
|
||
|
||
return portURLs ?? []
|
||
}
|
||
|
||
/// Runs the script to flash the firmware on an ESP32
|
||
static func flashToESP32(accessory: Accessory, port: URL, completion: @escaping (Result<Void, Error>) -> Void) throws {
|
||
|
||
// Copy firmware to a temporary directory
|
||
let temp = NSTemporaryDirectory() + "OpenHaystack"
|
||
let urlTemp = URL(fileURLWithPath: temp)
|
||
try? FileManager.default.removeItem(at: urlTemp)
|
||
|
||
try? FileManager.default.createDirectory(atPath: temp, withIntermediateDirectories: false, attributes: nil)
|
||
|
||
guard let espDirectory = espFirmwareDirectory else { return }
|
||
|
||
try FileManager.default.copyFolder(from: espDirectory, to: urlTemp)
|
||
let scriptPath = urlTemp.appendingPathComponent("flash_esp32.sh")
|
||
|
||
let key = try accessory.getAdvertisementKey().base64EncodedString()
|
||
let arguments = ["-p", "\(port.path)", key]
|
||
|
||
let task = try NSUserUnixTask(url: scriptPath)
|
||
task.execute(withArguments: arguments) { e in
|
||
DispatchQueue.main.async {
|
||
if let error = e {
|
||
completion(.failure(error))
|
||
} else {
|
||
completion(.success(()))
|
||
}
|
||
|
||
// Delete the temporary folder
|
||
try? FileManager.default.removeItem(at: urlTemp)
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
enum FirmwareFlashError: Error {
|
||
/// Missing files for flashing
|
||
case notFound
|
||
/// Flashing / writing failed
|
||
case flashFailed
|
||
}
|