123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 |
- #include "SCFWrapper.h"
- #include <dlfcn.h>
- #include <iostream>
- #include <chrono>
- // 简单的日志函数
- 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<GetSCF_Proc>(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<ReleaseSCF_Proc>(
- 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<SCF>(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<char> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lock(m_instanceMutex);
- if (m_scfInstance && m_connected) {
- m_scfInstance->Disconnect();
- m_connected = false;
- LOG_INFO("Disconnected");
- }
- }
- bool SCFWrapper::IsConnected() {
- std::lock_guard<std::mutex> lock(m_instanceMutex);
- return m_scfInstance && m_connected;
- }
- std::string SCFWrapper::GetConnectionType() {
- std::lock_guard<std::mutex> lock(m_instanceMutex);
- if (m_scfInstance) {
- return m_scfInstance->GetConnectionType();
- }
- return "";
- }
- int SCFWrapper::Lock(unsigned int timeout) {
- std::lock_guard<std::mutex> lock(m_instanceMutex);
- if (m_scfInstance) {
- return m_scfInstance->SCFLock(timeout);
- }
- return SCF_FAILED;
- }
- void SCFWrapper::Unlock() {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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;
- }
|