| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import Foundation
- // ══════════════════════════════════════════════════════════════════
- // Phase 2: Userspace API & Command Router
- // ══════════════════════════════════════════════════════════════════
- // ── Developers Public API Namespaces ──
- public struct ark {
- public struct system {
- public struct time {
- public static func getCurrentTime() -> String {
- let formatter = DateFormatter()
- formatter.timeStyle = .medium
- formatter.dateStyle = .medium
- return formatter.string(from: Date())
- }
-
- public static func getUptime() -> Double {
- if let data = try? String(contentsOfFile: "/proc/uptime") {
- let parts = data.split(separator: " ")
- if let first = parts.first, let uptimeVal = Double(first) {
- return uptimeVal
- }
- }
- return 0.0
- }
- }
-
- public struct network {
- public static func getIPAddress() -> String {
- return NetworkManager.getInterfaceIP()
- }
-
- public static func getWiFiNetworks() -> [String] {
- return NetworkManager.scanWiFi()
- }
- }
-
- public struct input {
- public static func readKey() -> Character? {
- return InputManager.readKeyStroke()
- }
- }
- }
- }
- // ── Header-Based Command Router ──
- public struct CommandRouter {
- // Command IDs
- public static let CMD_GET_TIME: UInt16 = 101
- public static let CMD_GET_IP: UInt16 = 102
- public static let CMD_GET_BATTERY: UInt16 = 103
- public static let CMD_GET_BLUETOOTH: UInt16 = 104
- public static let CMD_SHUTDOWN: UInt16 = 105
- public static let CMD_DUMP_LOGS: UInt16 = 106
-
- // Strict binary routing header format:
- // [Command_ID (2 Bytes)][Payload_Length (4 Bytes)][Payload_Data]
- public static func route(requestBuffer: UnsafeRawBufferPointer) -> Data {
- guard requestBuffer.count >= 6 else {
- LogManager.log("Router: Invalid request header (less than 6 bytes).")
- return makeResponse(cmdId: 0, payload: "ERROR: INVALID_HEADER")
- }
-
- // Zero-copy loading of header fields
- let cmdId = requestBuffer.load(fromByteOffset: 0, as: UInt16.self).bigEndian
- let payloadLen = requestBuffer.load(fromByteOffset: 2, as: UInt32.self).bigEndian
-
- guard requestBuffer.count >= 6 + Int(payloadLen) else {
- LogManager.log("Router: Payload size mismatch (expected \(payloadLen) bytes).")
- return makeResponse(cmdId: cmdId, payload: "ERROR: SIZE_MISMATCH")
- }
-
- // Zero-copy payload slicing
- let payloadBytes = UnsafeRawBufferPointer(rebasing: requestBuffer[6..<(6 + Int(payloadLen))])
- let payloadString = String(decoding: payloadBytes, as: UTF8.self)
-
- LogManager.log("Router: Received command \(cmdId), payload size \(payloadLen), payload: \(payloadString)")
-
- // Handle commands
- var responseString = ""
- switch cmdId {
- case CMD_GET_TIME:
- responseString = ark.system.time.getCurrentTime()
-
- case CMD_GET_IP:
- responseString = ark.system.network.getIPAddress()
-
- case CMD_GET_BATTERY:
- responseString = "\(PowerManager.getBatteryPercentage())%"
-
- case CMD_GET_BLUETOOTH:
- responseString = BluetoothManager.isEnabled() ? "ACTIVE" : "INACTIVE"
-
- case CMD_SHUTDOWN:
- PowerManager.shutdown()
- responseString = "SHUTTING_DOWN"
-
- case CMD_DUMP_LOGS:
- responseString = LogManager.dumpLogs().joined(separator: "\n")
-
- default:
- LogManager.log("Router: Unknown Command_ID \(cmdId)")
- responseString = "ERROR: UNKNOWN_COMMAND"
- }
-
- return makeResponse(cmdId: cmdId, payload: responseString)
- }
-
- // Construct response header and payload
- private static func makeResponse(cmdId: UInt16, payload: String) -> Data {
- let payloadData = payload.data(using: .utf8) ?? Data()
- var response = Data()
- response.reserveCapacity(6 + payloadData.count)
-
- var bigEndianCmd = cmdId.bigEndian
- var bigEndianLen = UInt32(payloadData.count).bigEndian
-
- withUnsafeBytes(of: &bigEndianCmd) { response.append(contentsOf: $0) }
- withUnsafeBytes(of: &bigEndianLen) { response.append(contentsOf: $0) }
- response.append(payloadData)
-
- return response
- }
- }
|