145 lines
4.3 KiB
Swift
145 lines
4.3 KiB
Swift
import Crypto
|
|
import Foundation
|
|
import FoundationNetworking
|
|
import IoT_Simulator_Core
|
|
import MessageUtils
|
|
|
|
public func configureSimulator() async throws {
|
|
|
|
guard
|
|
let configurationFilePath: String = ProcessInfo.processInfo.environment[
|
|
"CONFIGURATION_FILE"]
|
|
else {
|
|
throw ParsingError.ConfigFileNotExistent
|
|
}
|
|
|
|
let jsonData: Data = try Data(contentsOf: URL(filePath: configurationFilePath))
|
|
|
|
guard
|
|
let jsonObject: [String: Any] = try JSONSerialization.jsonObject(with: jsonData)
|
|
as? [String: Any]
|
|
else {
|
|
throw ParsingError.MalformedJSON(reason: "This is not a JSON file")
|
|
}
|
|
|
|
try await jsonConfigurationParser(jsonObject)
|
|
|
|
}
|
|
|
|
private func jsonConfigurationParser(_ json: [String: Any]) async throws {
|
|
|
|
guard
|
|
let version = json["version"] as? Int,
|
|
let environments = json["environments"] as? [[String: Any]]
|
|
else {
|
|
throw ParsingError.MalformedJSON(reason: "Missing either version or environemnt")
|
|
}
|
|
|
|
for environmentJSON in environments {
|
|
|
|
let env = try await json2env(environmentJSON)
|
|
|
|
await IoTSimulatorCore.addEnv(environment: env)
|
|
|
|
if let devices = environmentJSON["devices"] as? [[String: Any]] {
|
|
for deviceJSON in devices {
|
|
let devices = try await json2edge_dev(deviceJSON)
|
|
|
|
for dev in devices {
|
|
await try IoTSimulatorCore.addDevice(location: env.location, device: dev) { msg in
|
|
// UGLY: But fast
|
|
// TODO: add sending code here
|
|
let backendURL = ProcessInfo.processInfo.environment["BACKEND_URL"]!
|
|
|
|
var httpRequest = URLRequest(url: URL(string: backendURL)!)
|
|
httpRequest.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type")
|
|
httpRequest.httpMethod = "POST"
|
|
|
|
httpRequest.httpBody = msg
|
|
let _ = try await URLSession.shared.upload(for: httpRequest, from: msg)
|
|
|
|
} failure: {
|
|
print("Failed")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private func json2env(_ json: [String: Any]) async throws -> PhysicalEnvironment {
|
|
|
|
guard
|
|
let envName = json["name"] as? String
|
|
else {
|
|
throw ParsingError.MalformedJSON(reason: "Missing name of environment")
|
|
}
|
|
|
|
let environment = PhysicalEnvironment(envName)
|
|
|
|
if let physicalData = json["physicalData"] as? [[String: Any]] {
|
|
|
|
for physicalDatum in physicalData {
|
|
guard
|
|
let dataTypeString = physicalDatum["dataType"] as? String,
|
|
let value = physicalDatum["value"] as? Double,
|
|
let dataType = DataType(rawValue: dataTypeString)
|
|
else {
|
|
throw ParsingError.MalformedJSON(reason: "Physical Data is Misconfigured")
|
|
}
|
|
|
|
let datum = PhysicalData(dataType, Float(value))
|
|
await environment.setPhysicalData(datum.type, datum)
|
|
}
|
|
|
|
}
|
|
|
|
return environment
|
|
}
|
|
|
|
private func json2edge_dev(_ json: [String: Any]) async throws -> [EdgeDevice] {
|
|
|
|
var devices: [EdgeDevice] = []
|
|
|
|
guard
|
|
let _dataType = json["dataType"] as? String,
|
|
let dataType = DataType(rawValue: _dataType)
|
|
else {
|
|
throw ParsingError.MalformedJSON(reason: "Data Type missing in one device")
|
|
}
|
|
|
|
if let number = json["number"] as? UInt {
|
|
for _ in 0..<number {
|
|
let deviceID = try DeviceFactory.getUnusedID()
|
|
let privateKey = try await fetchPrivateP256Key(deviceID: UInt(deviceID))
|
|
|
|
// TODO: Get ID from DeviceFactory and push ID inside
|
|
devices.append(
|
|
try await DeviceFactory.createEdgeDevice(
|
|
deviceID: deviceID,
|
|
dataType: dataType,
|
|
privateKey: privateKey
|
|
)
|
|
)
|
|
}
|
|
// UGLY: Silent Bug, coul dhave both deviceID and number, but other properties would
|
|
// UGLY: be ignored
|
|
return devices
|
|
}
|
|
|
|
guard
|
|
let deviceID = json["deviceID"] as? UInt
|
|
else {
|
|
throw ParsingError.MalformedJSON(
|
|
reason: "Missing deviceID and number properties"
|
|
)
|
|
}
|
|
|
|
// TODO: check for other optionals
|
|
|
|
return devices
|
|
|
|
}
|