#include "reader_service.h" #include "../utils.h" #include #include #include #include #include void PrintLogMessage(const std::string &message) { CreateAndAttachConsole(); std::cout << message << std::endl; } ReaderService *ReaderService::GetInstance() { static ReaderService instance; return &instance; } std::vector ReaderService::ScanUsb() { PrintLogMessage("Scanning USB..."); std::vector usb_devices; int iHidNum = SWHid_GetUsbCount(); for (int i = 0; i < iHidNum; i++) { char arrHidName[256]; SWHid_GetUsbInfo(static_cast(i), arrHidName); usb_devices.push_back(arrHidName); } return usb_devices; } bool ReaderService::Connect(int deviceIndex) { unsigned char arrBuffer[256] = {0}; // Close previous connection (if exists) if (connected_) { SWHid_SetCallback(NULL); SWHid_CloseDevice(); } if (SWHid_OpenDevice(static_cast(deviceIndex)) == FALSE) { PrintLogMessage("Failed to connect to device!"); return false; } // Get device information if (SWHid_GetDeviceSystemInfo(0xFF, arrBuffer) == false) // failed { Sleep(10); if (SWHid_GetDeviceSystemInfo(0xFF, arrBuffer) == false) // failed { SWHid_CloseDevice(); PrintLogMessage("Failed to get device info!"); return false; } } connected_ = true; // Set callback function // SWHid_SetCallback(ReaderService::DeviceCallback); // Extract device info int softVer = static_cast(arrBuffer[0]); int hardVer = static_cast(arrBuffer[1]); std::string softVersion = std::to_string(softVer >> 4) + "." + std::to_string(softVer & 0x0F); std::string hardVersion = std::to_string(hardVer >> 4) + "." + std::to_string(hardVer & 0x0F); // Extract device SN from buffer[2] to buffer[9] (8 bytes) std::string deviceSN = ""; for (int i = 2; i < 10; i++) { char hex[3]; sprintf_s(hex, sizeof(hex), "%.2X", arrBuffer[i]); deviceSN += hex; } std::string log_message = "Connected to device successfully! SN: " + deviceSN + ", SoftVer: " + softVersion + ", HardVer: " + hardVersion; PrintLogMessage(log_message); return true; } void ReaderService::Disconnect() { if (connected_) { StopRead(); // Stop reading SWHid_SetCallback(NULL); SWHid_CloseDevice(); connected_ = false; PrintLogMessage("Disconnected from device."); } } bool ReaderService::StartRead() { if (!connected_) { PrintLogMessage("Not connected to any device!"); return false; } // SWHid_SetDeviceOneParam(0xFF, 0x02, 0x01); // Set Workmode as Activemode // Set working mode to answer mode if (SWHid_SetDeviceOneParam(0xFF, 0x02, 0x00) == false) // Set Workmode as Answermode { PrintLogMessage("Failed to set device to answer mode!"); return false; } reading_ = true; timer_running_ = true; tags_.clear(); // Start timer thread to periodically call AnswerMode timer_thread_ = std::make_unique(&ReaderService::RunTimer, this); // Start a thread to periodically send tag list to UI callback_thread_ = std::make_unique([this]() { while (timer_running_) { SendTagList(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); } }); // // Start a separate thread to automatically stop reading after 3 seconds // auto stop_thread = std::make_unique([this]() { // std::this_thread::sleep_for(std::chrono::seconds(3)); // if (reading_) { // StopRead(); // PrintLogMessage("Automatically stopped reading after 3 seconds."); // } // }); // // Detach the thread to run independently and clean up resources // stop_thread->detach(); PrintLogMessage("Started reading in answer mode. Will auto-stop after 3 seconds."); return true; } void ReaderService::StopRead() { if (reading_) { // Stop the timer thread if (timer_running_) { timer_running_ = false; if (timer_thread_ && timer_thread_->joinable()) { timer_thread_->join(); } if (callback_thread_ && callback_thread_->joinable()) { callback_thread_->join(); } } reading_ = false; PrintLogMessage("Stopped reading."); } } void ReaderService::RunTimer() { while (timer_running_) { AnswerMode(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Sleep for 100ms, similar to the demo } } std::string ReaderService::GetDeviceInfo() { if (!connected_) { return ""; } unsigned char arrBuffer[256] = {0}; if (SWHid_GetDeviceSystemInfo(0xFF, arrBuffer) == false) { Sleep(10); if (SWHid_GetDeviceSystemInfo(0xFF, arrBuffer) == false) { return ""; } } // Extract device info int softVer = static_cast(arrBuffer[0]); int hardVer = static_cast(arrBuffer[1]); std::string softVersion = std::to_string(softVer >> 4) + "." + std::to_string(softVer & 0x0F); std::string hardVersion = std::to_string(hardVer >> 4) + "." + std::to_string(hardVer & 0x0F); // Extract device SN from buffer[2] to buffer[9] (8 bytes) std::string deviceSN = ""; for (int i = 2; i < 10; i++) { char hex[3]; sprintf_s(hex, sizeof(hex), "%.2X", arrBuffer[i]); deviceSN += hex; } // Create a formatted string with all device info std::string deviceInfo = "SN:" + deviceSN + ",SoftVer:" + softVersion + ",HardVer:" + hardVersion; std::string log_message = "Device Info - " + deviceInfo; PrintLogMessage(log_message); return deviceInfo; } // 新增功率查询功能 bool ReaderService::GetPower(unsigned char &power) { if (!connected_) { PrintLogMessage("Not connected to any device!"); return false; } unsigned char bValue = 0; unsigned char bParamAddr = 0x05; // RFPower parameter address if (SWHid_ReadDeviceOneParam(0xFF, bParamAddr, &bValue) == false) { PrintLogMessage("Failed to read power!"); return false; } power = bValue; std::string log_message = "Power read successfully: " + std::to_string(power); PrintLogMessage(log_message); return true; } // 新增功率设置功能 bool ReaderService::SetPower(unsigned char power) { if (!connected_) { PrintLogMessage("Not connected to any device!"); return false; } // Check if power is within valid range (based on demo: 5-30) if (power < 5 || power > 30) { std::string log_message = "Invalid power value: " + std::to_string(power) + " (must be between 5-30)"; PrintLogMessage(log_message); return false; } unsigned char bParamAddr = 0x05; // RFPower parameter address if (SWHid_SetDeviceOneParam(0xFF, bParamAddr, power) == false) { PrintLogMessage("Failed to set power!"); return false; } std::string log_message = "Power set successfully to: " + std::to_string(power); PrintLogMessage(log_message); return true; } void ReaderService::DeviceCallback(int msg, int param1, unsigned char *param2, int param3, unsigned char *param4) { ReaderService *instance = ReaderService::GetInstance(); if (msg == 2) // Data { PrintLogMessage("Data received."); unsigned short iTagLength = 0; unsigned short iTagNumber = 0; iTagLength = static_cast(param3); iTagNumber = static_cast(param1); unsigned char *pBuffer = NULL; pBuffer = (unsigned char *)param2; if (iTagNumber == 0) return; int iIndex = 0; int iLength = 0; unsigned char *pID; unsigned char bPackLength = 0; int iIDLen = 0; for (iIndex = 0; iIndex < iTagNumber; iIndex++) { bPackLength = pBuffer[iLength]; pID = (unsigned char *)&pBuffer[1 + iLength]; std::string str2 = ""; char buffer[256]; sprintf_s(buffer, sizeof(buffer), "Type:%.2X ", pID[0]); str2 += buffer; if ((pID[0] & 0x80) == 0x80) // with TimeStamp { iIDLen = bPackLength - 7; } else iIDLen = bPackLength - 1; sprintf_s(buffer, sizeof(buffer), "Ant:%.2X Tag:", pID[1]); str2 += buffer; for (int i = 2; i < iIDLen; i++) { sprintf_s(buffer, sizeof(buffer), "%.2X ", pID[i]); str2 += buffer; } sprintf_s(buffer, sizeof(buffer), "RSSI:%.2X", pID[iIDLen]); str2 += buffer; // Notify UI of new data if (instance->data_callback_) { instance->data_callback_(str2); } iLength = iLength + bPackLength + 1; } } else if (msg == 1) // Device Out { PrintLogMessage("Device removed."); if (instance->data_callback_) { instance->data_callback_("Device Out"); } } else if (msg == 0) // Device Insert { PrintLogMessage("Device inserted."); if (instance->data_callback_) { instance->data_callback_("Device Insert"); } } } void ReaderService::AnswerMode() { unsigned char arrBuffer[2048] = {0}; unsigned short iTagLength = 0; unsigned short iTagNumber = 0; if (SWHid_InventoryG2(0xFF, arrBuffer, &iTagLength, &iTagNumber) == false) { PrintLogMessage("Failed to inventory!"); return; } if (iTagNumber == 0) { // PrintLogMessage("No data!"); return; } ReaderService *instance = ReaderService::GetInstance(); int iIndex = 0; int iLength = 0; unsigned char *pID; unsigned char bPackLength = 0; int iIDLen = 0; for (iIndex = 0; iIndex < iTagNumber; iIndex++) { bPackLength = arrBuffer[iLength]; pID = (unsigned char *)&arrBuffer[1 + iLength]; std::string str2 = "", tag = ""; char buffer[256]; sprintf_s(buffer, sizeof(buffer), "Type:%.2X ", pID[0]); str2 += buffer; if ((pID[0] & 0x80) == 0x80) // with TimeStamp { iIDLen = bPackLength - 7; } else iIDLen = bPackLength - 1; sprintf_s(buffer, sizeof(buffer), "Ant:%.2X Tag:", pID[1]); str2 += buffer; for (int i = 2; i < iIDLen; i++) { sprintf_s(buffer, sizeof(buffer), "%.2X", pID[i]); str2 += buffer; str2 += " "; tag += buffer; } sprintf_s(buffer, sizeof(buffer), "RSSI:%.2X", pID[iIDLen]); str2 += buffer; PrintLogMessage(str2); // Store the tag without spaces if (!tag.empty()) { std::lock_guard lock(instance->tags_mutex_); instance->tags_.insert(tag); } iLength = iLength + bPackLength + 1; } } void ReaderService::SendTagList() { if (data_callback_ && !tags_.empty()) { // Convert the set of tags to a JSON string std::string tag_list_json = "["; bool first = true; for (const auto &tag : tags_) { if (!first) { tag_list_json += ","; } tag_list_json += "\"" + tag + "\""; first = false; } tag_list_json += "]"; data_callback_(tag_list_json); } } ReaderService::~ReaderService() { // Disconnect during destruction Disconnect(); }