#include "SCFWrapper.h" #include #include #include // 简单的日志函数 void LogMessage(const std::string& level, const std::string& message) { // 获取当前时间 std::time_t now = std::time(nullptr); char timeStr[20]; std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", std::localtime(&now)); std::cout << "[" << timeStr << "] [" << level << "] " << message << std::endl; } #define LOG_DEBUG(msg) LogMessage("DEBUG", msg) #define LOG_INFO(msg) LogMessage("INFO", msg) #define LOG_WARNING(msg) LogMessage("WARNING", msg) #define LOG_ERROR(msg) LogMessage("ERROR", msg) SCFWrapper::SCFWrapper() : m_libraryHandle(nullptr) , m_connected(false) , m_autoReceiveRunning(false) , m_transferType(SCF_NORMAL_TRANSFER) , m_communicateTimeout(3000) { } SCFWrapper::SCFWrapper(const SCFWrapper& other) { CopyFrom(other); } SCFWrapper& SCFWrapper::operator=(const SCFWrapper& other) { if (this != &other) { // 先停止当前实例的运行 StopAutoReceive(); Disconnect(); UnloadSCFLibrary(); // 复制内部状态 CopyFrom(other); } return *this; } SCFWrapper::~SCFWrapper() { StopAutoReceive(); Disconnect(); UnloadSCFLibrary(); } bool SCFWrapper::Initialize(const std::string& dllName) { return LoadSCFLibrary(dllName); } bool SCFWrapper::LoadSCFLibrary(const std::string& dllName) { // 先卸载已加载的库 UnloadSCFLibrary(); // 加载指定的库 m_libraryHandle = dlopen(dllName.c_str(), RTLD_LAZY); if (!m_libraryHandle) { m_lastError = "Failed to load library: " + dllName + ", error: " + dlerror(); LOG_ERROR(m_lastError); return false; } m_libraryType = dllName; // 获取GetSCF函数 GetSCF_Proc getSCF = reinterpret_cast(dlsym(m_libraryHandle, "GetSCF")); if (!getSCF) { m_lastError = "Failed to find GetSCF function, error: " + std::string(dlerror()); LOG_ERROR(m_lastError); dlclose(m_libraryHandle); m_libraryHandle = nullptr; return false; } // 使用自定义删除器,确保正确释放 SCF 实例 auto deleter = [this](SCF* ptr) { if (ptr && m_libraryHandle) { ReleaseSCF_Proc releaseSCF = reinterpret_cast( dlsym(m_libraryHandle, "ReleaseSCF")); if (releaseSCF) { releaseSCF(ptr); } else { delete ptr; } } }; SCF* rawPtr = getSCF(); if (!rawPtr) { m_lastError = "Failed to create SCF instance"; LOG_ERROR(m_lastError); dlclose(m_libraryHandle); m_libraryHandle = nullptr; return false; } m_scfInstance = std::shared_ptr(rawPtr, deleter); LOG_INFO("SCF library loaded successfully: " + dllName); return true; } void SCFWrapper::UnloadSCFLibrary() { m_scfInstance.reset(); // 释放 SCF 实例 if (m_libraryHandle) { dlclose(m_libraryHandle); m_libraryHandle = nullptr; } LOG_INFO("SCF library unloaded"); m_connected = false; } void SCFWrapper::AutoReceiveThread() { const size_t bufferSize = 4096; std::vector buffer(bufferSize); unsigned int bytesReceived = 0; LOG_INFO("Auto receive thread started"); while (m_autoReceiveRunning && m_connected) { if (!IsConnected()) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); continue; } // 接收数据 int result = ReceivePacket(buffer.data(), bufferSize, 100, bytesReceived); if (result == SCF_SUCCEED && bytesReceived > 0) { // 调用数据接收回调 std::lock_guard lock(m_callbackMutex); if (m_dataReceivedCallback) { try { m_dataReceivedCallback(buffer.data(), bytesReceived); } catch (const std::exception& e) { LOG_ERROR("Exception in data received callback: " + std::string(e.what())); } catch (...) { LOG_ERROR("Unknown exception in data received callback"); } } } else if (result == SCF_DISCONNETED) { LOG_ERROR("Device disconnected in auto receive thread"); { std::lock_guard lock(m_instanceMutex); m_connected = false; } break; } else if (result != SCF_TIMEOUT) { // std::cerr << "Error in auto receive thread: " << result << std::endl; // 短暂延时后继续尝试 std::this_thread::sleep_for(std::chrono::milliseconds(10)); } // 短暂延时,避免CPU占用过高 std::this_thread::sleep_for(std::chrono::milliseconds(1)); } LOG_INFO("Auto receive thread stopped"); } int SCFWrapper::ReadDataImpl(char* pPacket, uint32_t length, uint32_t timeout) { return 0; } void SCFWrapper::CopyFrom(const SCFWrapper& other) { // 复制基本状态 std::lock_guard lock(other.m_instanceMutex); m_lastError = other.m_lastError; m_connected.store(other.m_connected.load()); m_libraryType = other.m_libraryType; m_connectionParams = other.m_connectionParams; m_packetParserCallback = other.m_packetParserCallback; m_transferType = other.m_transferType; m_communicateTimeout = other.m_communicateTimeout; m_dataReceivedCallback = other.m_dataReceivedCallback; // 如果源对象有加载库,我们也需要加载相同的库 if (other.m_libraryHandle && other.m_scfInstance) { // 重新加载库并连接 LoadSCFLibrary(m_libraryType); // 重新连接 if (m_connected) { Connect(m_connectionParams, m_packetParserCallback, m_transferType, m_communicateTimeout); } } } int SCFWrapper::Connect(const ResDataObject& connectionParams, PacketParserCallback callback, SCF_TRANSFERTYPE transferType, unsigned int timeout) { std::lock_guard lock(m_instanceMutex); if (!m_scfInstance) { m_lastError = "SCF instance not initialized"; LOG_ERROR(m_lastError); return SCF_FAILED; } // 保存连接参数和回调 m_connectionParams = connectionParams; m_packetParserCallback = callback; m_transferType = transferType; m_communicateTimeout = timeout; // 创建静态包装函数,将C++回调转换为C回调 static PacketParserCallback s_callback; s_callback = callback; static auto staticPacketParser = [](const char* pRecData, uint32_t nLength, uint32_t& PacketLength) -> PACKET_RET { if (s_callback) { return s_callback(pRecData, nLength, PacketLength); } return PACKET_NOPACKET; }; // 在调用Connect的地方,创建非const副本 ResDataObject nonConstConnParams = connectionParams; // 复制const对象到非const副本 int result; if (callback) { result = m_scfInstance->Connect( nonConstConnParams, // 传递非const副本 staticPacketParser, transferType, timeout ); } else { result = m_scfInstance->Connect( nonConstConnParams, // 传递非const副本 nullptr, transferType, timeout ); } m_connected = (result == SCF_SUCCEED); if (m_connected) { LOG_INFO("Connected successfully"); } else { LOG_ERROR("Failed to connect: " + std::to_string(result)); } return result; } void SCFWrapper::Disconnect() { StopAutoReceive(); std::lock_guard lock(m_instanceMutex); if (m_scfInstance && m_connected) { m_scfInstance->Disconnect(); m_connected = false; LOG_INFO("Disconnected"); } } bool SCFWrapper::IsConnected() { std::lock_guard lock(m_instanceMutex); return m_scfInstance && m_connected; } std::string SCFWrapper::GetConnectionType() { std::lock_guard lock(m_instanceMutex); if (m_scfInstance) { return m_scfInstance->GetConnectionType(); } return ""; } int SCFWrapper::Lock(unsigned int timeout) { std::lock_guard lock(m_instanceMutex); if (m_scfInstance) { return m_scfInstance->SCFLock(timeout); } return SCF_FAILED; } void SCFWrapper::Unlock() { std::lock_guard lock(m_instanceMutex); if (m_scfInstance) { m_scfInstance->SCFUnLock(); } } int SCFWrapper::SendPacket(const char* data, unsigned int length, unsigned int timeout, unsigned int& retLength) { std::lock_guard lock(m_instanceMutex); if (!m_scfInstance || !m_connected) { m_lastError = "Not connected or instance invalid"; LOG_ERROR(m_lastError); return SCF_DISCONNETED; } if (data == nullptr) { m_lastError = "SendPacket: data is null"; LOG_ERROR(m_lastError); return SCF_PARAMETER_ERR; } if (length == 0) { m_lastError = "SendPacket: length is zero"; LOG_ERROR(m_lastError); return SCF_PARAMETER_ERR; } try { int result = m_scfInstance->SendPacket(data, length, timeout); if (result >= 0) { retLength = result; LOG_DEBUG("SendPacket succeeded: " + std::to_string(result) + " bytes"); return SCF_SUCCEED; } else { m_lastError = "SendPacket failed: " + std::to_string(result); LOG_ERROR(m_lastError); return result; } } catch (const std::exception& e) { m_lastError = "Exception in SendPacket: " + std::string(e.what()); LOG_ERROR(m_lastError); return SCF_UNKNOWN; } catch (...) { m_lastError = "Unknown exception in SendPacket"; LOG_ERROR(m_lastError); return SCF_UNKNOWN; } } int SCFWrapper::SendPacket(SCFPacket* packet, unsigned int timeout) { std::lock_guard lock(m_instanceMutex); if (!m_scfInstance || !m_connected) { m_lastError = "Not connected or instance invalid"; LOG_ERROR(m_lastError); return SCF_DISCONNETED; } if (packet == nullptr) { m_lastError = "SendPacket: packet is null"; LOG_ERROR(m_lastError); return SCF_PARAMETER_ERR; } try { return m_scfInstance->SendPacket(packet, timeout); } catch (const std::exception& e) { m_lastError = "Exception in SendPacket: " + std::string(e.what()); LOG_ERROR(m_lastError); return SCF_UNKNOWN; } catch (...) { m_lastError = "Unknown exception in SendPacket"; LOG_ERROR(m_lastError); return SCF_UNKNOWN; } } int SCFWrapper::ReceivePacket(char* buffer, unsigned int length, unsigned int timeout, unsigned int& retLength) { std::lock_guard lock(m_instanceMutex); // 详细的参数检查 if (buffer == nullptr) { m_lastError = "ReceivePacket: buffer is null"; LOG_ERROR(m_lastError); return SCF_PARAMETER_ERR; } if (length == 0) { m_lastError = "ReceivePacket: length is zero"; LOG_ERROR(m_lastError); return SCF_PARAMETER_ERR; } if (!m_scfInstance) { m_lastError = "ReceivePacket: SCF instance is null"; LOG_ERROR(m_lastError); return SCF_DISCONNETED; } if (!m_connected) { m_lastError = "ReceivePacket: not connected"; LOG_ERROR(m_lastError); return SCF_DISCONNETED; } try { int result = m_scfInstance->ReceivePacket(buffer, length, timeout); if (result >= 0) { retLength = result; LOG_DEBUG("ReceivePacket succeeded: " + std::to_string(result) + " bytes"); return SCF_SUCCEED; } else { return result; } } catch (const std::exception& e) { m_lastError = "Exception in ReceivePacket: " + std::string(e.what()); LOG_ERROR(m_lastError); return SCF_UNKNOWN; } catch (...) { m_lastError = "Unknown exception in ReceivePacket"; LOG_ERROR(m_lastError); return SCF_UNKNOWN; } } int SCFWrapper::ReceivePacket(SCFPacket* packet, unsigned int timeout) { std::lock_guard lock(m_instanceMutex); if (!m_scfInstance || !m_connected) { m_lastError = "Not connected or instance invalid"; LOG_ERROR(m_lastError); return SCF_DISCONNETED; } if (packet == nullptr) { m_lastError = "ReceivePacket: packet is null"; LOG_ERROR(m_lastError); return SCF_PARAMETER_ERR; } try { return m_scfInstance->ReceivePacket(packet, timeout); } catch (const std::exception& e) { m_lastError = "Exception in ReceivePacket: " + std::string(e.what()); LOG_ERROR(m_lastError); return SCF_UNKNOWN; } catch (...) { m_lastError = "Unknown exception in ReceivePacket"; LOG_ERROR(m_lastError); return SCF_UNKNOWN; } } void SCFWrapper::SetDataReceivedCallback(DataReceivedCallback callback) { std::lock_guard lock(m_callbackMutex); m_dataReceivedCallback = callback; } bool SCFWrapper::StartAutoReceive() { if (!m_connected) { m_lastError = "Not connected"; LOG_ERROR(m_lastError); return false; } if (m_autoReceiveRunning) { m_lastError = "Auto receive already running"; LOG_ERROR(m_lastError); return true; } m_autoReceiveRunning = true; m_autoReceiveThread = std::thread(&SCFWrapper::AutoReceiveThread, this); return true; } void SCFWrapper::StopAutoReceive() { m_autoReceiveRunning = false; if (m_autoReceiveThread.joinable()) { m_autoReceiveThread.join(); } LOG_INFO("Auto receive stopped"); } std::string SCFWrapper::GetLastError() const { return m_lastError; }