1142 lines
42 KiB
C++
1142 lines
42 KiB
C++
// dllmain.cpp : Defines the entry point for the DLL application.
|
|
#include "pch.h"
|
|
#include "iobox_api.h"
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <condition_variable>
|
|
#include <mutex>
|
|
|
|
// Handle registry with refcount — prevents use-after-free when
|
|
// ReleaseANSIOHandle is called while an operation is still running.
|
|
static std::unordered_map<ANSCENTER::iobox_api*, int>& IOHandleRegistry() {
|
|
static std::unordered_map<ANSCENTER::iobox_api*, int> s;
|
|
return s;
|
|
}
|
|
static std::mutex& IOHandleRegistryMutex() {
|
|
static std::mutex m;
|
|
return m;
|
|
}
|
|
static std::condition_variable& IOHandleRegistryCV() {
|
|
static std::condition_variable cv;
|
|
return cv;
|
|
}
|
|
|
|
static void RegisterIOHandle(ANSCENTER::iobox_api* h) {
|
|
std::lock_guard<std::mutex> lk(IOHandleRegistryMutex());
|
|
IOHandleRegistry()[h] = 1;
|
|
}
|
|
|
|
static ANSCENTER::iobox_api* AcquireIOHandle(ANSCENTER::iobox_api* h) {
|
|
std::lock_guard<std::mutex> lk(IOHandleRegistryMutex());
|
|
auto it = IOHandleRegistry().find(h);
|
|
if (it == IOHandleRegistry().end()) return nullptr;
|
|
it->second++;
|
|
return h;
|
|
}
|
|
|
|
static bool ReleaseIOHandleRef(ANSCENTER::iobox_api* h) {
|
|
std::lock_guard<std::mutex> lk(IOHandleRegistryMutex());
|
|
auto it = IOHandleRegistry().find(h);
|
|
if (it == IOHandleRegistry().end()) return false;
|
|
it->second--;
|
|
if (it->second <= 0) {
|
|
IOHandleRegistry().erase(it);
|
|
IOHandleRegistryCV().notify_all();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool UnregisterIOHandle(ANSCENTER::iobox_api* h) {
|
|
std::unique_lock<std::mutex> lk(IOHandleRegistryMutex());
|
|
auto it = IOHandleRegistry().find(h);
|
|
if (it == IOHandleRegistry().end()) return false;
|
|
it->second--;
|
|
bool ok = IOHandleRegistryCV().wait_for(lk, std::chrono::seconds(30), [&]() {
|
|
auto it2 = IOHandleRegistry().find(h);
|
|
return it2 == IOHandleRegistry().end() || it2->second <= 0;
|
|
});
|
|
if (!ok) {
|
|
OutputDebugStringA("WARNING: UnregisterIOHandle timed out waiting for in-flight operations\n");
|
|
}
|
|
IOHandleRegistry().erase(h);
|
|
return true;
|
|
}
|
|
|
|
// RAII guard — ensures ReleaseIOHandleRef is always called
|
|
class IOHandleGuard {
|
|
ANSCENTER::iobox_api* engine;
|
|
public:
|
|
explicit IOHandleGuard(ANSCENTER::iobox_api* e) : engine(e) {}
|
|
~IOHandleGuard() { if (engine) ReleaseIOHandleRef(engine); }
|
|
ANSCENTER::iobox_api* get() const { return engine; }
|
|
explicit operator bool() const { return engine != nullptr; }
|
|
IOHandleGuard(const IOHandleGuard&) = delete;
|
|
IOHandleGuard& operator=(const IOHandleGuard&) = delete;
|
|
};
|
|
|
|
BOOL APIENTRY DllMain( HMODULE hModule,
|
|
DWORD ul_reason_for_call,
|
|
LPVOID lpReserved
|
|
) noexcept
|
|
{
|
|
switch (ul_reason_for_call)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
case DLL_PROCESS_DETACH:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Helper: safely copy a std::string into a LabVIEW LStrHandle.
|
|
// Returns 1 on success, 0 on failure (empty string or allocation error).
|
|
static int CopyToLStrHandle(LStrHandle handle, const std::string& str) noexcept {
|
|
if (str.empty() || handle == nullptr) return 0;
|
|
const auto size = static_cast<int32>(str.length());
|
|
MgErr error = DSSetHandleSize(handle, sizeof(int32) + size * sizeof(uChar));
|
|
if (error != noErr) return 0;
|
|
(*handle)->cnt = size;
|
|
memcpy((*handle)->str, str.c_str(), static_cast<size_t>(size));
|
|
return 1;
|
|
}
|
|
|
|
// Helper: join a vector of strings with semicolon separator.
|
|
static std::string JoinStrings(const std::vector<std::string>& items) {
|
|
std::string result;
|
|
for (size_t i = 0; i < items.size(); ++i) {
|
|
if (i > 0) result += ";";
|
|
result += items[i];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
extern "C" ANSIO_API int CreateANSIOHandle(ANSCENTER::iobox_api** Handle, const char* multicastIPAddress, int multicastPort) {
|
|
if (Handle == nullptr || multicastIPAddress == nullptr) return 0;
|
|
try {
|
|
// Release existing handle if called twice (prevents leak from LabVIEW)
|
|
if (*Handle) {
|
|
if (UnregisterIOHandle(*Handle)) {
|
|
delete *Handle;
|
|
}
|
|
*Handle = nullptr;
|
|
}
|
|
|
|
// std::unique_ptr ensures automatic cleanup on any failure path
|
|
auto ptr = std::make_unique<ANSCENTER::iobox_api>(multicastIPAddress, multicastPort);
|
|
// Transfer ownership to caller on success
|
|
*Handle = ptr.release();
|
|
RegisterIOHandle(*Handle);
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
if (Handle) *Handle = nullptr;
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
if (Handle) *Handle = nullptr;
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int ConnectANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int ioBoxPort, const char* userName, const char* passWord, LStrHandle deviceStr) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || userName == nullptr || passWord == nullptr) return 0;
|
|
try {
|
|
return CopyToLStrHandle(deviceStr, guard.get()->connectToIobox(ioBoxIP, ioBoxPort, userName, passWord));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int AdvancedConnectANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int ioBoxPort, const char* ioBoxSN, const char* userName, const char* passWord, LStrHandle deviceStr) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || ioBoxSN == nullptr || userName == nullptr || passWord == nullptr) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->advancedConnectToIobox(ioBoxIP, ioBoxPort, ioBoxSN, userName, passWord);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(deviceStr, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int DisconnectANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
return guard.get()->disconnectToIoboxWithResetOutputs(ioBoxIP) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
static int ReleaseANSIOHandle_Impl(ANSCENTER::iobox_api** Handle) {
|
|
try {
|
|
if (!Handle || !*Handle) return 1;
|
|
if (!UnregisterIOHandle(*Handle)) {
|
|
*Handle = nullptr;
|
|
return 1;
|
|
}
|
|
delete *Handle;
|
|
*Handle = nullptr;
|
|
return 1;
|
|
}
|
|
catch (...) {
|
|
if (Handle) *Handle = nullptr;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int ReleaseANSIOHandle(ANSCENTER::iobox_api** Handle)
|
|
{
|
|
__try {
|
|
return ReleaseANSIOHandle_Impl(Handle);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
if (Handle) *Handle = nullptr;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int SetValueANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, const char* value) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr || value == nullptr) return 0;
|
|
try {
|
|
return guard.get()->setValue(ioBoxIP, channelName, value) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int GetValueANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, LStrHandle lStrValue) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr) return 0;
|
|
try {
|
|
std::string st = "fail";
|
|
bool success = guard.get()->getValue(ioBoxIP, channelName, st);
|
|
if (!success || st.empty() || st == "fail") return 0;
|
|
return CopyToLStrHandle(lStrValue, st);
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int SetAuthenticationANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* userName, const char* passWord) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || userName == nullptr || passWord == nullptr) return 0;
|
|
try {
|
|
return guard.get()->setAuthenticationIobox(ioBoxIP, userName, passWord) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int ScanANSIOHandle(ANSCENTER::iobox_api** Handle, int timeout, LStrHandle ipAddresses) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->scanNetworkDevicesMulticast(timeout);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(ipAddresses, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int ScanANSIOUnicastHandle(ANSCENTER::iobox_api** Handle, int timeout, LStrHandle ipAddresses) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->scanNetworkDevicesManually(timeout);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(ipAddresses, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int AdvancedScanANSIOHandle(ANSCENTER::iobox_api** Handle, int timeout, LStrHandle deviceInfos) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->advancedScan(timeout);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(deviceInfos, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int AdvancedStaticScanANSIOHandle(int timeout, LStrHandle deviceInfos) {
|
|
try {
|
|
ANSCENTER::iobox_api iobox_api("239.255.255.250", 12345);
|
|
std::vector<std::string> st = iobox_api.advancedScan(timeout);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(deviceInfos, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int ScanANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, int timeout, std::string& ipAddresses) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->scanNetworkDevicesMulticast(timeout);
|
|
if (st.empty()) return 0;
|
|
ipAddresses = JoinStrings(st);
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int ScanANSIOUnicastHandle_CPP(ANSCENTER::iobox_api** Handle, int timeout, std::string& ipAddresses) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->scanNetworkDevicesManually(timeout);
|
|
if (st.empty()) return 0;
|
|
ipAddresses = JoinStrings(st);
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int AdvancedScanANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, int timeout, std::string& deviceInfos) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->advancedScan(timeout);
|
|
if (st.empty()) return 0;
|
|
deviceInfos = JoinStrings(st);
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int AdvancedStaticScanANSIOHandle_CPP(int timeout, std::string& deviceInfos)
|
|
{
|
|
try {
|
|
ANSCENTER::iobox_api iobox_api("239.255.255.250", 12345);
|
|
std::vector<std::string> st = iobox_api.advancedScan(timeout);
|
|
if (st.empty()) return 0;
|
|
deviceInfos = JoinStrings(st);
|
|
if (deviceInfos.empty()) return 0;
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int GetChannelNamesANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int timeout, LStrHandle channelNames) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->getDeviceChannelNames(ioBoxIP);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(channelNames, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int GetValueANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, std::string& lStrValue) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr) return 0;
|
|
try {
|
|
std::string st = "fail";
|
|
bool success = guard.get()->getValue(ioBoxIP, channelName, st);
|
|
if (!success || st.empty() || st == "fail") return 0;
|
|
lStrValue = st;
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int GetChannelNamesANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int timeout, std::string& channelNames) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->getDeviceChannelNames(ioBoxIP);
|
|
if (st.empty()) return 0;
|
|
channelNames = JoinStrings(st);
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int ResetAuthenticationANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* token) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || token == nullptr) return 0;
|
|
try {
|
|
return guard.get()->resetAuthenticationIobox(ioBoxIP, token) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int ResetANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* token) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || token == nullptr) return 0;
|
|
try {
|
|
return guard.get()->resetIobox(ioBoxIP, token) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int GenerateANSIOTokenHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, LStrHandle tokenStr) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
return CopyToLStrHandle(tokenStr, guard.get()->generateToken(ioBoxIP));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int GenerateANSIOTokenHandle_CPP(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, std::string& tokenStr) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::string st = guard.get()->generateToken(ioBoxIP);
|
|
if (st.empty()) return 0;
|
|
tokenStr = st;
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int ConnectANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int ioBoxPort, const char* userName, const char* passWord, std::string& deviceStr) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || userName == nullptr || passWord == nullptr) return 0;
|
|
try {
|
|
std::string st = guard.get()->connectToIobox(ioBoxIP, ioBoxPort, userName, passWord);
|
|
if (st.empty()) return 0;
|
|
deviceStr = st;
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int AdvancedConnectANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int ioBoxPort, const char* ioBoxSN, const char* userName, const char* passWord, std::string& deviceStr) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || ioBoxSN == nullptr || userName == nullptr || passWord == nullptr) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->advancedConnectToIobox(ioBoxIP, ioBoxPort, ioBoxSN, userName, passWord);
|
|
if (st.empty()) return 0;
|
|
deviceStr = JoinStrings(st);
|
|
return 1;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
extern "C" ANSIO_API int CheckANSIOStatusHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
return guard.get()->checkTcpConnectStatus(ioBoxIP) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
extern "C" ANSIO_API int OpenANSAIRS232Port(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int baudrate, int DataBits, int stopBits, int parityBits) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
return guard.get()->openRs232Port(ioBoxIP, baudrate, DataBits, stopBits, parityBits) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int CloseANSAIRS232Port(ANSCENTER::iobox_api** Handle, const char* ioBoxIP) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
return guard.get()->closeRs232Port(ioBoxIP) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int WriteANSAIRS232Port(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* data, int timeout_ms) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || data == nullptr) return 0;
|
|
try {
|
|
return guard.get()->writeRs232Port(ioBoxIP, data, timeout_ms) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int ReadANSAIRS232Port(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* terminatorString, int lenExpect, int timeout_ms, LStrHandle receivedData) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
const char* safeTerminator = (terminatorString != nullptr) ? terminatorString : "";
|
|
return CopyToLStrHandle(receivedData, guard.get()->readRs232Port(ioBoxIP, safeTerminator, lenExpect, timeout_ms));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// OTA
|
|
extern "C" ANSIO_API int OTAANSIOFirmwareDevice(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* filename, const char* type) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || filename == nullptr || type == nullptr) return 0;
|
|
try {
|
|
return guard.get()->otaFirmwareDevice(ioBoxIP, filename, type) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Synchronous version (existing behavior)
|
|
extern "C" ANSIO_API int ToggleIoboxHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, int timeOut, int revertFlag, int resetFlag) {
|
|
try {
|
|
// Input validation
|
|
if (Handle == nullptr || *Handle == nullptr) {
|
|
return -1; // Invalid handle
|
|
}
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return -1;
|
|
|
|
if (ioBoxIP == nullptr || channelName == nullptr) {
|
|
return -2; // Invalid parameters
|
|
}
|
|
|
|
if (timeOut < 0) {
|
|
return -3; // Invalid timeout
|
|
}
|
|
|
|
// Convert C parameters to C++ types
|
|
std::string remote(ioBoxIP);
|
|
std::string channel(channelName);
|
|
bool revert = (revertFlag != 0);
|
|
bool reset = (resetFlag != 0);
|
|
|
|
// Call synchronous version (asyncMode = false)
|
|
bool result = guard.get()->toggleIobox(remote, channel, timeOut, revert, reset, false);
|
|
|
|
return result ? 1 : 0;
|
|
|
|
}
|
|
catch (const std::exception&) {
|
|
return -4; // Exception occurred
|
|
}
|
|
catch (...) {
|
|
return -5; // Unknown exception
|
|
}
|
|
}
|
|
|
|
// Asynchronous version (new function)
|
|
extern "C" ANSIO_API int ToggleIoboxHandleAsync(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, int timeOut, int revertFlag, int resetFlag) {
|
|
try {
|
|
// Input validation
|
|
if (Handle == nullptr || *Handle == nullptr) {
|
|
return -1; // Invalid handle
|
|
}
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return -1;
|
|
|
|
if (ioBoxIP == nullptr || channelName == nullptr) {
|
|
return -2; // Invalid parameters
|
|
}
|
|
|
|
if (timeOut < 0) {
|
|
return -3; // Invalid timeout
|
|
}
|
|
|
|
// Convert C parameters to C++ types
|
|
std::string remote(ioBoxIP);
|
|
std::string channel(channelName);
|
|
bool revert = (revertFlag != 0);
|
|
bool reset = (resetFlag != 0);
|
|
|
|
// Call asynchronous version (asyncMode = true)
|
|
bool result = guard.get()->toggleIobox(remote, channel, timeOut, revert, reset, true);
|
|
|
|
return result ? 1 : 0; // Returns immediately
|
|
|
|
}
|
|
catch (const std::exception&) {
|
|
return -4; // Exception occurred
|
|
}
|
|
catch (...) {
|
|
return -5; // Unknown exception
|
|
}
|
|
}
|
|
|
|
|
|
extern "C" ANSIO_API int GetStaticIpConfigANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, LStrHandle staticIpConfigInfo) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> configs = guard.get()->getStaticIpConfig(ioBoxIP);
|
|
if (configs.empty()) return 0;
|
|
return CopyToLStrHandle(staticIpConfigInfo, JoinStrings(configs));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int SetStaticIpConfigANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int enable, const char* ip, const char* gw, const char* nm) {
|
|
if (Handle == nullptr || *Handle == nullptr || ioBoxIP == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ip == nullptr || gw == nullptr || nm == nullptr) return 0;
|
|
try {
|
|
return guard.get()->setStaticIpConfig(ioBoxIP, enable != 0, ip, gw, nm) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int GetValueDataStringIoboxFromChannelNameANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, LStrHandle dataValue) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr) return 0;
|
|
try {
|
|
return CopyToLStrHandle(dataValue, guard.get()->getValueDataStringIoboxFromChannelName(ioBoxIP, channelName));
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int ToggleDigitalOutputANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, int milliseconds, int invertFlag, int resetFlag) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr) return 0;
|
|
try {
|
|
return guard.get()->toggleDigitalOutput(ioBoxIP, channelName, std::to_string(milliseconds), invertFlag != 0, resetFlag != 0) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
extern "C" ANSIO_API int SetAIBValueDataStringIoboxFromChannelNameANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, const char* value) {
|
|
if (Handle == nullptr || *Handle == nullptr) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(*Handle));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr || value == nullptr) return 0;
|
|
try {
|
|
return guard.get()->setAIBValueDataStringIoboxFromChannelName(ioBoxIP, channelName, value) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) {
|
|
return 0;
|
|
}
|
|
catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// V2 API — handle passed by value (uint64_t) to avoid LabVIEW buffer reuse bug
|
|
// ============================================================================
|
|
|
|
extern "C" ANSIO_API int ConnectANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, int ioBoxPort, const char* userName, const char* passWord, LStrHandle deviceStr) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || userName == nullptr || passWord == nullptr) return 0;
|
|
try {
|
|
return CopyToLStrHandle(deviceStr, guard.get()->connectToIobox(ioBoxIP, ioBoxPort, userName, passWord));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int AdvancedConnectANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, int ioBoxPort, const char* ioBoxSN, const char* userName, const char* passWord, LStrHandle deviceStr) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || ioBoxSN == nullptr || userName == nullptr || passWord == nullptr) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->advancedConnectToIobox(ioBoxIP, ioBoxPort, ioBoxSN, userName, passWord);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(deviceStr, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int DisconnectANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr) return 0;
|
|
try {
|
|
return guard.get()->disconnectToIoboxWithResetOutputs(ioBoxIP) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int CheckANSIOStatusHandle_V2(uint64_t handleVal, const char* ioBoxIP) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr) return 0;
|
|
try {
|
|
return guard.get()->checkTcpConnectStatus(ioBoxIP) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int SetValueANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, const char* channelName, const char* value) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr || value == nullptr) return 0;
|
|
try {
|
|
return guard.get()->setValue(ioBoxIP, channelName, value) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int GetValueANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, const char* channelName, LStrHandle lStrValue) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr) return 0;
|
|
try {
|
|
std::string st = "fail";
|
|
bool success = guard.get()->getValue(ioBoxIP, channelName, st);
|
|
if (!success || st.empty() || st == "fail") return 0;
|
|
return CopyToLStrHandle(lStrValue, st);
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int GetValueDataStringIoboxFromChannelNameANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, const char* channelName, LStrHandle dataValue) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr) return 0;
|
|
try {
|
|
return CopyToLStrHandle(dataValue, guard.get()->getValueDataStringIoboxFromChannelName(ioBoxIP, channelName));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int SetAIBValueDataStringIoboxFromChannelNameANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, const char* channelName, const char* value) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr || value == nullptr) return 0;
|
|
try {
|
|
return guard.get()->setAIBValueDataStringIoboxFromChannelName(ioBoxIP, channelName, value) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int SetAuthenticationANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, const char* userName, const char* passWord) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || userName == nullptr || passWord == nullptr) return 0;
|
|
try {
|
|
return guard.get()->setAuthenticationIobox(ioBoxIP, userName, passWord) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int ResetAuthenticationANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, const char* token) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || token == nullptr) return 0;
|
|
try {
|
|
return guard.get()->resetAuthenticationIobox(ioBoxIP, token) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int GenerateANSIOTokenHandle_V2(uint64_t handleVal, const char* ioBoxIP, LStrHandle tokenStr) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr) return 0;
|
|
try {
|
|
return CopyToLStrHandle(tokenStr, guard.get()->generateToken(ioBoxIP));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int ScanANSIOHandle_V2(uint64_t handleVal, int timeout, LStrHandle ipAddresses) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->scanNetworkDevicesMulticast(timeout);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(ipAddresses, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int ScanANSIOUnicastHandle_V2(uint64_t handleVal, int timeout, LStrHandle ipAddresses) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->scanNetworkDevicesManually(timeout);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(ipAddresses, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int AdvancedScanANSIOHandle_V2(uint64_t handleVal, int timeout, LStrHandle deviceInfos) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->advancedScan(timeout);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(deviceInfos, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int GetChannelNamesANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, int timeout, LStrHandle channelNames) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr) return 0;
|
|
try {
|
|
std::vector<std::string> st = guard.get()->getDeviceChannelNames(ioBoxIP);
|
|
if (st.empty()) return 0;
|
|
return CopyToLStrHandle(channelNames, JoinStrings(st));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int ResetANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, const char* token) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || token == nullptr) return 0;
|
|
try {
|
|
return guard.get()->resetIobox(ioBoxIP, token) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int ToggleIoboxHandle_V2(uint64_t handleVal, const char* ioBoxIP, const char* channelName, int timeOut, int revertFlag, int resetFlag) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return -1;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return -1;
|
|
if (ioBoxIP == nullptr || channelName == nullptr) return -2;
|
|
if (timeOut < 0) return -3;
|
|
try {
|
|
std::string remote(ioBoxIP);
|
|
std::string channel(channelName);
|
|
bool revert = (revertFlag != 0);
|
|
bool reset = (resetFlag != 0);
|
|
bool result = guard.get()->toggleIobox(remote, channel, timeOut, revert, reset, false);
|
|
return result ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return -4; }
|
|
catch (...) { return -5; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int ToggleIoboxHandleAsync_V2(uint64_t handleVal, const char* ioBoxIP, const char* channelName, int timeOut, int revertFlag, int resetFlag) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return -1;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return -1;
|
|
if (ioBoxIP == nullptr || channelName == nullptr) return -2;
|
|
if (timeOut < 0) return -3;
|
|
try {
|
|
std::string remote(ioBoxIP);
|
|
std::string channel(channelName);
|
|
bool revert = (revertFlag != 0);
|
|
bool reset = (resetFlag != 0);
|
|
bool result = guard.get()->toggleIobox(remote, channel, timeOut, revert, reset, true);
|
|
return result ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return -4; }
|
|
catch (...) { return -5; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int ToggleDigitalOutputANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, const char* channelName, int milliseconds, int invertFlag, int resetFlag) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || channelName == nullptr) return 0;
|
|
try {
|
|
return guard.get()->toggleDigitalOutput(ioBoxIP, channelName, std::to_string(milliseconds), invertFlag != 0, resetFlag != 0) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int OpenANSAIRS232Port_V2(uint64_t handleVal, const char* ioBoxIP, int baudrate, int DataBits, int stopBits, int parityBits) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr) return 0;
|
|
try {
|
|
return guard.get()->openRs232Port(ioBoxIP, baudrate, DataBits, stopBits, parityBits) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int CloseANSAIRS232Port_V2(uint64_t handleVal, const char* ioBoxIP) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr) return 0;
|
|
try {
|
|
return guard.get()->closeRs232Port(ioBoxIP) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int WriteANSAIRS232Port_V2(uint64_t handleVal, const char* ioBoxIP, const char* data, int timeout_ms) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || data == nullptr) return 0;
|
|
try {
|
|
return guard.get()->writeRs232Port(ioBoxIP, data, timeout_ms) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int ReadANSAIRS232Port_V2(uint64_t handleVal, const char* ioBoxIP, const char* terminatorString, int lenExpect, int timeout_ms, LStrHandle receivedData) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr) return 0;
|
|
try {
|
|
const char* safeTerminator = (terminatorString != nullptr) ? terminatorString : "";
|
|
return CopyToLStrHandle(receivedData, guard.get()->readRs232Port(ioBoxIP, safeTerminator, lenExpect, timeout_ms));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int GetStaticIpConfigANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, LStrHandle staticIpConfigInfo) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr) return 0;
|
|
try {
|
|
std::vector<std::string> configs = guard.get()->getStaticIpConfig(ioBoxIP);
|
|
if (configs.empty()) return 0;
|
|
return CopyToLStrHandle(staticIpConfigInfo, JoinStrings(configs));
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int SetStaticIpConfigANSIOHandle_V2(uint64_t handleVal, const char* ioBoxIP, int enable, const char* ip, const char* gw, const char* nm) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || ip == nullptr || gw == nullptr || nm == nullptr) return 0;
|
|
try {
|
|
return guard.get()->setStaticIpConfig(ioBoxIP, enable != 0, ip, gw, nm) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
extern "C" ANSIO_API int OTAANSIOFirmwareDevice_V2(uint64_t handleVal, const char* ioBoxIP, const char* filename, const char* type) {
|
|
auto* _v2h = reinterpret_cast<ANSCENTER::iobox_api*>(handleVal); if (!_v2h) return 0;
|
|
IOHandleGuard guard(AcquireIOHandle(_v2h));
|
|
if (!guard) return 0;
|
|
if (ioBoxIP == nullptr || filename == nullptr || type == nullptr) return 0;
|
|
try {
|
|
return guard.get()->otaFirmwareDevice(ioBoxIP, filename, type) ? 1 : 0;
|
|
}
|
|
catch (const std::exception&) { return 0; }
|
|
catch (...) { return 0; }
|
|
}
|
|
|
|
// End of ANSIO/dllmain.cpp
|