using System; using System.Threading; namespace Card_Dispenser_Service { internal class CardManager { private Thread _workerThread; private bool _stopping = false; private readonly ManualResetEvent _shutdownEvent = new ManualResetEvent(false); public void Start(int port) { _stopping = false; _shutdownEvent.Reset(); // Start API Server listener API.StartListener(port); // Spin up background hardware loop thread _workerThread = new Thread(DoWork); _workerThread.IsBackground = true; _workerThread.Start(); } public void Stop() { API.StopListener(); _stopping = true; _shutdownEvent.Set(); // Gracefully wait for the thread loop to conclude if (_workerThread != null && !_workerThread.Join(TimeSpan.FromSeconds(5))) { #if !NETCOREAPP _workerThread.Abort(); // Legacy fallback for .NET Framework #endif } } // --- SHARED CORE HANDLER: Accessible by both the API thread loop and your UI forms --- public object ExecuteHardwareCommand(CardTaskResponse task) { if (task == null || string.IsNullOrEmpty(task.Command)) { return new { status = "error", message = "Empty command payload" }; } Utils.LogToFile($"Executing command: {task.Command}"); try { switch (task.Command) { case "Connect": bool isConnected = K720.Instance.Connect(task.Serial, task.BaudRate); return new { status = "success", isConnected = isConnected }; case "Disconnect": bool isDisconnected = K720.Instance.Disconnect(); return new { status = "success", isConnected = isDisconnected }; case "Write": if (task.Sector != 0 || task.Block != 0) { K720.Instance.Write_Command(task.Data, (byte)task.Sector, (byte)task.Block); } else { K720.Instance.Write_Command(task.Data); } return new { status = "success", message = "Data written successfully" }; case "Dispense": var dispenseResult = K720.Instance.SendCmd(K720.CardCommand.Dispense); return new { status = "success", hardwareResponse = dispenseResult }; case "Recycle": var recycleResult = K720.Instance.SendCmd(K720.CardCommand.Recycle); return new { status = "success", hardwareResponse = recycleResult }; case "Read": var readResult = K720.Instance.SendCmd(K720.CardCommand.Read); return new { status = "success", cardData = readResult }; case "Return": var returnResult = K720.Instance.SendCmd(K720.CardCommand.Return); return new { status = "success", hardwareResponse = returnResult }; default: return new { status = "error", message = $"Unknown command '{task.Command}' received" }; } } catch (Exception ex) { Utils.LogToFile($"Hardware error during {task.Command}: {ex.Message}"); return new { status = "error", message = ex.Message }; } } private void DoWork() { try { while (!_stopping) { var requestWrapper = API.WaitForRequestAsync().GetAwaiter().GetResult(); if (requestWrapper != null && requestWrapper.TaskData != null) { // 1. Process data using local core processor method object resultObj = ExecuteHardwareCommand(requestWrapper.TaskData); // 2. Serialize result mapping using public API object field format string responseJson = API._serializer.Serialize(resultObj); // 3. Respond back to HTTP client API.SendResponseAsync(requestWrapper.HttpContext, responseJson).GetAwaiter().GetResult(); } if (_shutdownEvent.WaitOne(TimeSpan.FromSeconds(1))) { break; } } } catch (Exception ex) { Utils.LogToFile("Critical error in service loop: " + ex.Message); } } } }