#ifndef _IO_BOX_API_H_ #define _IO_BOX_API_H_ #define ANSIO_API __declspec(dllexport) #include "LabVIEWHeader/extcode.h" #include #include #include #include #include #include #include // For PIP_ADAPTER_INFO #include #include #include #include "ANSLicense.h" #pragma comment(lib,"WS2_32") #pragma comment(lib, "Iphlpapi.lib") // #pragma comment(lib, "Ws2_32.lib") // #define TEST_FIX_IP #define DEVICE_TCP_PORT 502 #define DEVICE_DATA_ADDRESS 100 #define DEVICE_DATA_LENGTH 17 #define MESSAGE_CRYPT_ENABLE 0 // Configuration constants - make these configurable if needed namespace IoboxConfig { constexpr int MAX_RETRIES = 30; // Reduced from 50 for better timeout control constexpr int RETRY_DELAY_MS = 100; // Increased from 50ms for better reliability constexpr int TOTAL_TIMEOUT_MS = 3000; // 3 seconds total timeout } namespace ANSCENTER { typedef struct { std::string model; std::string ip_address; //local ip std::string ip_public_address; //public ip std::string mac_address; std::string serial_number; std::string firmware_version; std::string hardware_version; std::vector channelNameList; } iobox_info_t; typedef struct { int counting_get; bool is_connected; bool is_anthenticated; SOCKET sock_tcp; iobox_info_t iobox_info; } iobox_profile_t; typedef struct { std::string adapter_index; std::string adapter_name; std::string adapter_description; std::string adapter_mac; std::string adapter_ip; std::string adapter_subnet; std::string adapter_gateway; } network_adapter_t; class ANSIO_API iobox_api { private: // Define the map with MAC address as key and IP address as value std::unordered_map macToIpMap; // Define unordered_map to store IP address and device information (std:vector) std::unordered_map> ipToDeviceMap; std::string ip_mcast; //ip multicast int port_mcast; //port multicast std::string _username; // default username std::string _password; // default password int _port; const char* aes_key = "a1b2c3d4e5f6g7h8"; std::recursive_mutex _mutex; std::vector iobox_profiles; iobox_profile_t* findProfileByIp(const std::string& ip); void save_info_iobox(const iobox_info_t& iobox_info); void setSocketTimeout(SOCKET sock, int timeout); void sendUnicastMessage(SOCKET sock, const char* ip, const std::string& message); void sendMulticastMessage(const std::string& message); bool sendTcpMessage(const std::string& ip, const char* buffer, size_t length, bool needCheckAuthen); bool receiveTcpMessage(const std::string& ip, char* buffer, size_t& length, int timeout = 3000); void show_profile_iobox(const iobox_profile_t& profile); bool connectToIoboxWithoutAuthen(const std::string& remote, int port); void remove_last_info_iobox(); uint16_t getIndexIoboxFromIp(const std::string& ip); std::vector scanNetworkDevicesManuallyOnNetworkAdapter(network_adapter_t adapter, int timeout); std::vector getNetworkAdapters(); bool performSetValue(const std::string& ip, const std::string& channelName, const std::string& value); bool performGetValue(const std::string& ip, const std::string& channelName, std::string& outValue); bool disconnectToIobox(const std::string& remote); private: SPDLogger& _logger = SPDLogger::GetInstance("IOBOX", true); struct ToggleInfo { std::chrono::steady_clock::time_point endTime; std::string originalState; bool revertFlag; std::atomic active{ true }; std::atomic cancelled{ false }; std::mutex mtx; std::condition_variable cv; // Constructor for better initialization ToggleInfo(bool revert = false) : revertFlag(revert) {} }; std::unordered_map> activeToggles; std::mutex toggleMapMutex; bool executeToggleOperation(const std::string& remote, const std::string& channelName, std::shared_ptr toggleInfo, const std::string& key); public: iobox_api(const std::string& ip_mcast, int port_mcast); ~iobox_api() noexcept; void show_profile_iobox(const std::string& remote); void show_profile_ioboxs(); [[nodiscard]] std::string generateToken(const std::string& remote); [[nodiscard]] std::vector scanNetworkDevicesMulticast(int timeout); [[nodiscard]] std::vector scanNetworkDevicesManually(int timeout); [[nodiscard]] std::vector CreateDeviceChannel(const std::string& multicastInfo); bool setAuthenticationIobox(const std::string& remote, const std::string& username, const std::string& password); bool resetAuthenticationIobox(const std::string& remote, const std::string& token); bool resetIobox(const std::string& remote, const std::string& token); [[nodiscard]] std::string connectToIobox(const std::string& remote, int port, const std::string& username, const std::string& password); bool disconnectToIoboxWithResetOutputs(const std::string& remote); [[nodiscard]] std::vector getDeviceChannelNames(const std::string& remote); bool getValueDataStringIoboxFromChannelName(const std::string& remote, const std::string& channelName, std::string& outValue); bool setValueDataStringIoboxFromChannelName(const std::string& remote, const std::string& channelName, const std::string& value); bool checkTcpConnectStatus(const std::string& remote); bool setValue(const std::string& remote, const std::string& channelName, const std::string& value);// Repeat until success or timeout (3s) bool getValue(const std::string& remote, const std::string& channelName, std::string& outValue);// Repeat until success or timeout (3s) //for RS232 bool openRs232Port(const std::string& remote, int baudrate, int dataBits, int stopBits, int parityBits); bool closeRs232Port(const std::string& remote); bool writeRs232Port(const std::string& remote, const std::string& data, int timeout_ms); [[nodiscard]] std::string readRs232Port(const std::string& remote, const std::string& terminatorString, int lenExpect, int timeout_ms); //for ota: type is "esp" or "mcu" bool otaFirmwareDevice(const std::string& remote, const std::string& filename, const std::string& type); // advanced functions (it can connect to ip or mac address and return device channel names) [[nodiscard]] std::vector advancedConnectToIobox(const std::string& remote, int port, const std::string& macAddress, const std::string& username, const std::string& password); [[nodiscard]] std::vector advancedScan(int timeout); // Add to public section: bool toggleIobox(const std::string& remote, const std::string& channelName, int timeOut,bool revertFlag, bool resetFlag, bool asyncMode = false); bool cancelToggle(const std::string& remote, const std::string& channelName); [[nodiscard]] std::vector getActiveToggleChannels(); bool getToggleStatus(const std::string& remote, const std::string& channelName,int& remainingTimeMs, std::string& currentPhase); // new functions [[nodiscard]] std::vector getStaticIpConfig(const std::string& remote); bool setStaticIpConfig(const std::string& remote, bool enable, const std::string& ip, const std::string& gw, const std::string& nm); [[nodiscard]] std::string getValueDataStringIoboxFromChannelName(const std::string& remote, const std::string& channelName); bool toggleDigitalOutput(const std::string& remote, const std::string& channelName, const std::string& milliseconds, bool invert, bool reset); bool setAIBValueDataStringIoboxFromChannelName(const std::string& remote, const std::string& channelName, const std::string& value); }; } extern "C" ANSIO_API int CreateANSIOHandle(ANSCENTER::iobox_api** Handle, const char* multicastIPAddress, int multicastPort); extern "C" ANSIO_API int ScanANSIOHandle(ANSCENTER::iobox_api** Handle, int timeout, LStrHandle ipAddresses); extern "C" ANSIO_API int ScanANSIOUnicastHandle(ANSCENTER::iobox_api** Handle, int timeout, LStrHandle ipAddresses); extern "C" ANSIO_API int AdvancedScanANSIOHandle(ANSCENTER::iobox_api** Handle, int timeout, LStrHandle deviceInfos); extern "C" ANSIO_API int AdvancedStaticScanANSIOHandle(int timeout, LStrHandle deviceInfos); extern "C" ANSIO_API int ConnectANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int ioBoxPort, const char* userName, const char* passWord, LStrHandle deviceStr); extern "C" ANSIO_API int AdvancedConnectANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int ioBoxPort, const char* ioSN, const char* userName, const char* passWord, LStrHandle deviceStr); extern "C" ANSIO_API int DisconnectANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP); extern "C" ANSIO_API int GetChannelNamesANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int timeout, LStrHandle channelNames); extern "C" ANSIO_API int SetValueANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, const char* value); extern "C" ANSIO_API int GetValueANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, LStrHandle lStrValue); extern "C" ANSIO_API int SetAuthenticationANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* userName, const char* passWord); extern "C" ANSIO_API int ReleaseANSIOHandle(ANSCENTER::iobox_api** Handle); extern "C" ANSIO_API int ResetAuthenticationANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* token); extern "C" ANSIO_API int ResetANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* token); extern "C" ANSIO_API int GenerateANSIOTokenHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, LStrHandle tokenStr); extern "C" ANSIO_API int CheckANSIOStatusHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP); // RS232 extern "C" ANSIO_API int OpenANSAIRS232Port(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int baudrate, int DataBits, int stopBits, int parityBits ); extern "C" ANSIO_API int CloseANSAIRS232Port(ANSCENTER::iobox_api** Handle, const char* ioBoxIP); extern "C" ANSIO_API int WriteANSAIRS232Port(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* data, int timeout_ms); extern "C" ANSIO_API int ReadANSAIRS232Port(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* terminatorString, int lenExpect, int timeout_ms, LStrHandle receivedData); // OTA extern "C" ANSIO_API int OTAANSIOFirmwareDevice(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* filename, const char* type); // C++ interface extern "C" ANSIO_API int ScanANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, int timeout, std::string& ipAddresses); extern "C" ANSIO_API int ScanANSIOUnicastHandle_CPP(ANSCENTER::iobox_api** Handle, int timeout, std::string& ipAddresses); extern "C" ANSIO_API int AdvancedScanANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, int timeout, std::string& deviceInfos); extern "C" ANSIO_API int AdvancedStaticScanANSIOHandle_CPP(int timeout, std::string& deviceInfos); extern "C" ANSIO_API int GetChannelNamesANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int timeout, std::string& channelNames); extern "C" ANSIO_API int GetValueANSIOHandle_CPP(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, std::string& lStrValue); extern "C" ANSIO_API int GenerateANSIOTokenHandle_CPP(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, std::string& tokenStr); 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); 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); // toggle extern "C" ANSIO_API int ToggleIoboxHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, int timeOut, int revertFlag, int resetFlag); extern "C" ANSIO_API int ToggleIoboxHandleAsync(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, int timeOut, int revertFlag, int resetFlag); // new functions extern "C" ANSIO_API int GetStaticIpConfigANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, LStrHandle staticIpConfigInfo); extern "C" ANSIO_API int SetStaticIpConfigANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, int enable, const char* ip, const char* gw, const char* nm); extern "C" ANSIO_API int GetValueDataStringIoboxFromChannelNameANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, LStrHandle dataValue); extern "C" ANSIO_API int ToggleDigitalOutputANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, int milliseconds, int invertFlag, int resetFlag); extern "C" ANSIO_API int SetAIBValueDataStringIoboxFromChannelNameANSIOHandle(ANSCENTER::iobox_api** Handle, const char* ioBoxIP, const char* channelName, const char* value); #endif