From f4f8b9a4c42f5aa001b98ca673183a56d7a1750c Mon Sep 17 00:00:00 2001 From: Stefan Broekman Date: Wed, 14 Apr 2021 23:55:45 +0200 Subject: [PATCH] Add winsock startup-cleanup to examples and link ws2_32 --- examples/CMakeLists.txt | 11 ++ examples/DiscoveryManagerExample.cpp | 38 +++-- examples/ExplicitMessagingExample.cpp | 94 +++++++----- examples/FileObjectExample.cpp | 51 +++++-- examples/IdentityObjectExample.cpp | 46 ++++-- examples/ImplicitMessagingExample.cpp | 119 ++++++++------- examples/ParameterObjectExample.cpp | 136 ++++++++++-------- .../Yaskawa_AssemblyObjectExample.cpp | 37 ++++- 8 files changed, 346 insertions(+), 186 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 14c3cc4..6460e9e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -14,8 +14,19 @@ target_link_libraries(implicit_messaging EIPScanner) add_executable(parameter_object_example ParameterObjectExample.cpp) target_link_libraries(parameter_object_example EIPScanner) + add_executable(discovery_example DiscoveryManagerExample.cpp) target_link_libraries(discovery_example EIPScanner) add_executable(yaskawa_assembly_object_example vendors/yaskawa/mp3300iec/Yaskawa_AssemblyObjectExample.cpp) target_link_libraries(yaskawa_assembly_object_example EIPScanner) + +if(WIN32) + target_link_libraries(explicit_messaging ws2_32) + target_link_libraries(file_object_example ws2_32) + target_link_libraries(identity_object_example ws2_32) + target_link_libraries(implicit_messaging ws2_32) + target_link_libraries(parameter_object_example ws2_32) + target_link_libraries(discovery_example ws2_32) + target_link_libraries(yaskawa_assembly_object_example ws2_32) +endif() diff --git a/examples/DiscoveryManagerExample.cpp b/examples/DiscoveryManagerExample.cpp index 9ffaed5..915e00e 100644 --- a/examples/DiscoveryManagerExample.cpp +++ b/examples/DiscoveryManagerExample.cpp @@ -2,6 +2,11 @@ // Created by Aleksey Timin on 12/17/19. // +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) +#include +#define OS_Windows (1) +#endif + #include #include @@ -10,14 +15,29 @@ using eipScanner::utils::Logger; using eipScanner::utils::LogLevel; int main() { - Logger::setLogLevel(LogLevel::DEBUG); + Logger::setLogLevel(LogLevel::DEBUG); + +#if OS_Windows + WSADATA wsaData; + int winsockStart = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (winsockStart != 0) { + Logger(LogLevel::ERROR) << "Failed to start WinSock - error code: " << winsockStart; + return EXIT_FAILURE; + } +#endif + + DiscoveryManager discoveryManager("172.28.255.255", 0xAF12, std::chrono::seconds(1)); + auto devices = discoveryManager.discover(); + + for (auto& device : devices) { + Logger(LogLevel::INFO) << "Discovered device: " + << device.identityObject.getProductName() + << " with address " << device.socketAddress.toString(); + } - DiscoveryManager discoveryManager("172.28.255.255", 0xAF12, std::chrono::seconds(1)); - auto devices = discoveryManager.discover(); +#if OS_Windows + WSACleanup(); +#endif - for (auto& device : devices) { - Logger(LogLevel::INFO) << "Discovered device: " - << device.identityObject.getProductName() - << " with address " << device.socketAddress.toString(); - } -} \ No newline at end of file + return EXIT_SUCCESS; +} diff --git a/examples/ExplicitMessagingExample.cpp b/examples/ExplicitMessagingExample.cpp index d3c5a64..6ae711f 100644 --- a/examples/ExplicitMessagingExample.cpp +++ b/examples/ExplicitMessagingExample.cpp @@ -2,6 +2,11 @@ // Created by Aleksey Timin on 11/16/19. // +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) +#include +#define OS_Windows (1) +#endif + #include #include #include @@ -22,50 +27,63 @@ using eipScanner::utils::Logger; using eipScanner::utils::LogLevel; int main() { - Logger::setLogLevel(LogLevel::DEBUG); - auto si = std::make_shared("127.0.0.1", 0xAF12, std::chrono::seconds(10)); - auto messageRouter = std::make_shared(); + Logger::setLogLevel(LogLevel::DEBUG); + +#if OS_Windows + WSADATA wsaData; + int winsockStart = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (winsockStart != 0) { + Logger(LogLevel::ERROR) << "Failed to start WinSock - error code: " << winsockStart; + return EXIT_FAILURE; + } +#endif + + auto si = std::make_shared("127.0.0.1", 0xAF12, std::chrono::seconds(10)); + auto messageRouter = std::make_shared(); - // Read attribute - auto response = messageRouter->sendRequest(si, ServiceCodes::GET_ATTRIBUTE_SINGLE, - EPath(0x01, 1, 1), - {}); + // Read attribute + auto response = messageRouter->sendRequest(si, ServiceCodes::GET_ATTRIBUTE_SINGLE, + EPath(0x01, 1, 1), + {}); - if (response.getGeneralStatusCode() == GeneralStatusCodes::SUCCESS) { - Buffer buffer(response.getData()); - CipUint vendorId; - buffer >> vendorId; + if (response.getGeneralStatusCode() == GeneralStatusCodes::SUCCESS) { + Buffer buffer(response.getData()); + CipUint vendorId; + buffer >> vendorId; - Logger(LogLevel::INFO) << "Vendor ID is " << vendorId; - } else { - Logger(LogLevel::ERROR) << "We got error=0x" << std::hex << response.getGeneralStatusCode(); - } + Logger(LogLevel::INFO) << "Vendor ID is " << vendorId; + } else { + Logger(LogLevel::ERROR) << "We got error=0x" << std::hex << response.getGeneralStatusCode(); + } - //Write attribute - // See OpenEr EDS 160 line - Buffer assembly151; - assembly151 << CipUsint(1) - << CipUsint(2) - << CipUsint(3) - << CipUsint(4) - << CipUsint(5) - << CipUsint(6) - << CipUsint(7) - << CipUsint(8) - << CipUsint(9) - << CipUsint(10); + //Write attribute + // See OpenEr EDS 160 line + Buffer assembly151; + assembly151 << CipUsint(1) + << CipUsint(2) + << CipUsint(3) + << CipUsint(4) + << CipUsint(5) + << CipUsint(6) + << CipUsint(7) + << CipUsint(8) + << CipUsint(9) + << CipUsint(10); - response = messageRouter->sendRequest(si, ServiceCodes::SET_ATTRIBUTE_SINGLE, - EPath(0x04, 151, 3), - assembly151.data()); + response = messageRouter->sendRequest(si, ServiceCodes::SET_ATTRIBUTE_SINGLE, + EPath(0x04, 151, 3), + assembly151.data()); - if (response.getGeneralStatusCode() == GeneralStatusCodes::SUCCESS) { - Logger(LogLevel::INFO) << "Writing is successful"; - } else { - Logger(LogLevel::ERROR) << "We got error=0x" << std::hex << response.getGeneralStatusCode(); - } + if (response.getGeneralStatusCode() == GeneralStatusCodes::SUCCESS) { + Logger(LogLevel::INFO) << "Writing is successful"; + } else { + Logger(LogLevel::ERROR) << "We got error=0x" << std::hex << response.getGeneralStatusCode(); + } +#if OS_Windows + WSACleanup(); +#endif - return 0; -} \ No newline at end of file + return EXIT_SUCCESS; +} diff --git a/examples/FileObjectExample.cpp b/examples/FileObjectExample.cpp index c7b400b..27a40c7 100644 --- a/examples/FileObjectExample.cpp +++ b/examples/FileObjectExample.cpp @@ -2,6 +2,11 @@ // Created by Aleksey Timin on 11/24/19. // +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) +#include +#define OS_Windows (1) +#endif + #include #include "FileObject.h" #include "utils/Logger.h" @@ -14,18 +19,34 @@ using eipScanner::utils::LogLevel; using eipScanner::FileObject; int main() { - Logger::setLogLevel(LogLevel::DEBUG); - auto si = std::make_shared("172.28.1.3", 0xAF12); - - FileObject edsFile(0xC8, si); - edsFile.beginUpload(si, [](GeneralStatusCodes status, const std::vector &fileContent) { - if (status == GeneralStatusCodes::SUCCESS) { - std::ofstream outFile("Device.eds", std::ios::out | std::ios::trunc | std::ios::binary); - outFile.write(reinterpret_cast(fileContent.data()), fileContent.size()); - } - }); - - while (edsFile.handleTransfers(si)) { - continue; - }; -} \ No newline at end of file + Logger::setLogLevel(LogLevel::DEBUG); + +#if OS_Windows + WSADATA wsaData; + int winsockStart = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (winsockStart != 0) { + Logger(LogLevel::ERROR) << "Failed to start WinSock - error code: " << winsockStart; + return EXIT_FAILURE; + } +#endif + + auto si = std::make_shared("172.28.1.3", 0xAF12); + + FileObject edsFile(0xC8, si); + edsFile.beginUpload(si, [](GeneralStatusCodes status, const std::vector &fileContent) { + if (status == GeneralStatusCodes::SUCCESS) { + std::ofstream outFile("Device.eds", std::ios::out | std::ios::trunc | std::ios::binary); + outFile.write(reinterpret_cast(fileContent.data()), fileContent.size()); + } + }); + + while (edsFile.handleTransfers(si)) { + continue; + }; + +#if OS_Windows + WSACleanup(); +#endif + + return EXIT_SUCCESS; +} diff --git a/examples/IdentityObjectExample.cpp b/examples/IdentityObjectExample.cpp index ce2333e..e29c8e9 100644 --- a/examples/IdentityObjectExample.cpp +++ b/examples/IdentityObjectExample.cpp @@ -2,6 +2,11 @@ // Created by Aleksey Timin on 12/19/19. // +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) +#include +#define OS_Windows (1) +#endif + #include "IdentityObject.h" #include "utils/Logger.h" @@ -11,16 +16,31 @@ using eipScanner::utils::Logger; using eipScanner::utils::LogLevel; int main() { - auto si = std::make_shared("172.28.1.3", 0xAF12); - IdentityObject identityObject(1, si); - - Logger(LogLevel::INFO) << identityObject.getVendorId() - << identityObject.getDeviceType() - << identityObject.getProductCode() - << identityObject.getRevision().toString() - << identityObject.getStatus() - << identityObject.getSerialNumber() - << identityObject.getProductName(); - - return 0; -} \ No newline at end of file + Logger::setLogLevel(LogLevel::DEBUG); + +#if OS_Windows + WSADATA wsaData; + int winsockStart = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (winsockStart != 0) { + Logger(LogLevel::ERROR) << "Failed to start WinSock - error code: " << winsockStart; + return EXIT_FAILURE; + } +#endif + + auto si = std::make_shared("172.28.1.3", 0xAF12); + IdentityObject identityObject(1, si); + + Logger(LogLevel::INFO) << identityObject.getVendorId() + << identityObject.getDeviceType() + << identityObject.getProductCode() + << identityObject.getRevision().toString() + << identityObject.getStatus() + << identityObject.getSerialNumber() + << identityObject.getProductName(); + +#if OS_Windows + WSACleanup(); +#endif + + return EXIT_SUCCESS; +} diff --git a/examples/ImplicitMessagingExample.cpp b/examples/ImplicitMessagingExample.cpp index a6144e2..a8b4d90 100644 --- a/examples/ImplicitMessagingExample.cpp +++ b/examples/ImplicitMessagingExample.cpp @@ -2,6 +2,11 @@ // Created by Aleksey Timin on 11/16/19. // +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) +#include +#define OS_Windows (1) +#endif + #include #include #include "SessionInfo.h" @@ -20,54 +25,68 @@ using eipScanner::utils::Logger; using eipScanner::utils::LogLevel; int main() { - Logger::setLogLevel(LogLevel::DEBUG); - auto si = std::make_shared("172.28.1.3", 0xAF12); - - // Implicit messaging - ConnectionManager connectionManager; - - ConnectionParameters parameters; - parameters.connectionPath = {0x20, 0x04,0x24, 151, 0x2C, 150, 0x2C, 100}; // config Assm151, output Assm150, intput Assm100 - parameters.o2tRealTimeFormat = true; - parameters.originatorVendorId = 342; - parameters.originatorSerialNumber = 32423; - parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::P2P; - parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY; - parameters.t2oNetworkConnectionParams |= 32; //size of Assm100 =32 - parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::P2P; - parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY; - parameters.o2tNetworkConnectionParams |= 32; //size of Assm150 = 32 - - parameters.originatorSerialNumber = 0x12345; - parameters.o2tRPI = 1000000; - parameters.t2oRPI = 1000000; - parameters.transportTypeTrigger |= NetworkConnectionParams::CLASS1; - - auto io = connectionManager.forwardOpen(si, parameters); - if (auto ptr = io.lock()) { - ptr->setDataToSend(std::vector(32)); - - ptr->setReceiveDataListener([](auto realTimeHeader, auto sequence, auto data) { - std::ostringstream ss; - ss << "secNum=" << sequence << " data="; - for (auto &byte : data) { - ss << "[" << std::hex << (int) byte << "]"; - } - - Logger(LogLevel::INFO) << "Received: " << ss.str(); - }); - - ptr->setCloseListener([]() { - Logger(LogLevel::INFO) << "Closed"; - }); - } - - int count = 200; - while (connectionManager.hasOpenConnections() && count-- > 0) { - connectionManager.handleConnections(std::chrono::milliseconds(100)); - } - - connectionManager.forwardClose(si, io); - - return 0; + Logger::setLogLevel(LogLevel::DEBUG); + +#if OS_Windows + WSADATA wsaData; + int winsockStart = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (winsockStart != 0) { + Logger(LogLevel::ERROR) << "Failed to start WinSock - error code: " << winsockStart; + return EXIT_FAILURE; + } +#endif + + auto si = std::make_shared("172.28.1.3", 0xAF12); + + // Implicit messaging + ConnectionManager connectionManager; + + ConnectionParameters parameters; + parameters.connectionPath = {0x20, 0x04,0x24, 151, 0x2C, 150, 0x2C, 100}; // config Assm151, output Assm150, intput Assm100 + parameters.o2tRealTimeFormat = true; + parameters.originatorVendorId = 342; + parameters.originatorSerialNumber = 32423; + parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::P2P; + parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY; + parameters.t2oNetworkConnectionParams |= 32; //size of Assm100 =32 + parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::P2P; + parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY; + parameters.o2tNetworkConnectionParams |= 32; //size of Assm150 = 32 + + parameters.originatorSerialNumber = 0x12345; + parameters.o2tRPI = 1000000; + parameters.t2oRPI = 1000000; + parameters.transportTypeTrigger |= NetworkConnectionParams::CLASS1; + + auto io = connectionManager.forwardOpen(si, parameters); + if (auto ptr = io.lock()) { + ptr->setDataToSend(std::vector(32)); + + ptr->setReceiveDataListener([](auto realTimeHeader, auto sequence, auto data) { + std::ostringstream ss; + ss << "secNum=" << sequence << " data="; + for (auto &byte : data) { + ss << "[" << std::hex << (int) byte << "]"; + } + + Logger(LogLevel::INFO) << "Received: " << ss.str(); + }); + + ptr->setCloseListener([]() { + Logger(LogLevel::INFO) << "Closed"; + }); + } + + int count = 200; + while (connectionManager.hasOpenConnections() && count-- > 0) { + connectionManager.handleConnections(std::chrono::milliseconds(100)); + } + + connectionManager.forwardClose(si, io); + +#if OS_Windows + WSACleanup(); +#endif + + return EXIT_SUCCESS; } diff --git a/examples/ParameterObjectExample.cpp b/examples/ParameterObjectExample.cpp index 8b90b17..537b43c 100644 --- a/examples/ParameterObjectExample.cpp +++ b/examples/ParameterObjectExample.cpp @@ -1,9 +1,16 @@ // // Created by Aleksey Timin on 12/4/19. // + +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) +#include +#define OS_Windows (1) +#endif + #include "ParameterObject.h" #include "utils/Logger.h" #include "utils/Buffer.h" + using namespace eipScanner::cip; using eipScanner::SessionInfo; using eipScanner::MessageRouter; @@ -17,62 +24,77 @@ const CipUint CLASS_DESCRIPTOR = 8; const CipUint SUPPORTS_FULL_ATTRIBUTES = 0x2; int main() { - Logger::setLogLevel(LogLevel::DEBUG); - auto si = std::make_shared("172.28.1.3", 0xAF12); - - // Read the number of the parameters - MessageRouter messageRouter; - auto response = messageRouter.sendRequest(si - , ServiceCodes::GET_ATTRIBUTE_SINGLE - , EPath(ParameterObject::CLASS_ID, 0, MAX_INSTANCE)); - - if (response.getGeneralStatusCode() != GeneralStatusCodes::SUCCESS) { - Logger(LogLevel::ERROR) << "Failed to read the count of the parameters"; - logGeneralAndAdditionalStatus(response); - return -1; - } - - Buffer buffer(response.getData()); - CipUint paramsCount; - buffer >> paramsCount; - - Logger(LogLevel::INFO) << "The device has " << paramsCount << "parameters"; - - // Read Parameter Class Descriptor - response = messageRouter.sendRequest(si - , ServiceCodes::GET_ATTRIBUTE_SINGLE - , EPath(ParameterObject::CLASS_ID, 0, CLASS_DESCRIPTOR)); - - if (response.getGeneralStatusCode() != GeneralStatusCodes::SUCCESS) { - Logger(LogLevel::ERROR) << "Failed to read the class descriptor"; - logGeneralAndAdditionalStatus(response); - return -1; - } - - buffer = Buffer(response.getData()); - CipUint descriptor; - buffer >> descriptor; - - Logger(LogLevel::INFO) << "Read the class descriptor=0x" << std::hex << (int)descriptor; - bool allAttributes = descriptor & SUPPORTS_FULL_ATTRIBUTES; - - // Read and save parameters in a vector - std::vector parameters; - parameters.reserve(paramsCount); - for (int i = 0; i < paramsCount; ++i) { - parameters.emplace_back(i+1, allAttributes, si); - } - - if (!parameters.empty()) { - parameters[0].getType(); // Read type - parameters[0].getActualValue(); // 2040 - parameters[0].getEngValue(); // 20.4 - parameters[0].getName(); // Freq - parameters[0].getUnits(); // Hz - // .. etc - - parameters[0].updateValue(si); - parameters[0].getActualValue(); // updated value - } + Logger::setLogLevel(LogLevel::DEBUG); + +#if OS_Windows + WSADATA wsaData; + int winsockStart = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (winsockStart != 0) { + Logger(LogLevel::ERROR) << "Failed to start WinSock - error code: " << winsockStart; + return EXIT_FAILURE; + } +#endif + + auto si = std::make_shared("172.28.1.3", 0xAF12); + + // Read the number of the parameters + MessageRouter messageRouter; + auto response = messageRouter.sendRequest(si + , ServiceCodes::GET_ATTRIBUTE_SINGLE + , EPath(ParameterObject::CLASS_ID, 0, MAX_INSTANCE)); + + if (response.getGeneralStatusCode() != GeneralStatusCodes::SUCCESS) { + Logger(LogLevel::ERROR) << "Failed to read the count of the parameters"; + logGeneralAndAdditionalStatus(response); + return -1; + } + + Buffer buffer(response.getData()); + CipUint paramsCount; + buffer >> paramsCount; + + Logger(LogLevel::INFO) << "The device has " << paramsCount << "parameters"; + + // Read Parameter Class Descriptor + response = messageRouter.sendRequest(si + , ServiceCodes::GET_ATTRIBUTE_SINGLE + , EPath(ParameterObject::CLASS_ID, 0, CLASS_DESCRIPTOR)); + + if (response.getGeneralStatusCode() != GeneralStatusCodes::SUCCESS) { + Logger(LogLevel::ERROR) << "Failed to read the class descriptor"; + logGeneralAndAdditionalStatus(response); + return -1; + } + + buffer = Buffer(response.getData()); + CipUint descriptor; + buffer >> descriptor; + + Logger(LogLevel::INFO) << "Read the class descriptor=0x" << std::hex << (int)descriptor; + bool allAttributes = descriptor & SUPPORTS_FULL_ATTRIBUTES; + + // Read and save parameters in a vector + std::vector parameters; + parameters.reserve(paramsCount); + for (int i = 0; i < paramsCount; ++i) { + parameters.emplace_back(i+1, allAttributes, si); + } + + if (!parameters.empty()) { + parameters[0].getType(); // Read type + parameters[0].getActualValue(); // 2040 + parameters[0].getEngValue(); // 20.4 + parameters[0].getName(); // Freq + parameters[0].getUnits(); // Hz + // .. etc + + parameters[0].updateValue(si); + parameters[0].getActualValue(); // updated value + } + +#if OS_Windows + WSACleanup(); +#endif + return EXIT_SUCCESS; } diff --git a/examples/vendors/yaskawa/mp3300iec/Yaskawa_AssemblyObjectExample.cpp b/examples/vendors/yaskawa/mp3300iec/Yaskawa_AssemblyObjectExample.cpp index 8d1d9ed..8cebde6 100644 --- a/examples/vendors/yaskawa/mp3300iec/Yaskawa_AssemblyObjectExample.cpp +++ b/examples/vendors/yaskawa/mp3300iec/Yaskawa_AssemblyObjectExample.cpp @@ -1,3 +1,8 @@ +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) +#include +#define OS_Windows (1) +#endif + #include "cip/Types.h" #include #include @@ -153,8 +158,17 @@ std::vector readAssemblyObject(std::shared_ptr // Test to read and write assembly objects on the adapter int main() { - Logger::setLogLevel(LogLevel::DEBUG); + +#if OS_Windows + WSADATA wsaData; + int winsockStart = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (winsockStart != 0) { + Logger(LogLevel::ERROR) << "Failed to start WinSock - error code: " << winsockStart; + return EXIT_FAILURE; + } +#endif + std::vector data_read; bool success; @@ -169,15 +183,27 @@ int main() { data_read = readAssemblyObject(si, YASKAWA_INPUT_ASSEMBLY_111); success = writeAssemblyObject(si, YASKAWA_INPUT_ASSEMBLY_111, data_write); - return 0; +#if OS_Windows + WSACleanup(); +#endif + + return EXIT_SUCCESS; } #if 0 // Test to confirm you are connected to a Yaskawa Device int main() { - Logger::setLogLevel(LogLevel::DEBUG); +#if OS_Windows + WSADATA wsaData; + int winsockStart = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (winsockStart != 0) { + Logger(LogLevel::ERROR) << "Failed to start WinSock - error code: " << winsockStart; + return EXIT_FAILURE; + } +#endif + DiscoveryManager discoveryManager(YASKAWA_IP_ADDR, YASKAWA_PORT, std::chrono::seconds(1)); auto devices = discoveryManager.discover(); @@ -190,8 +216,11 @@ int main() { } } +#if OS_Windows + WSACleanup(); +#endif - return 0; + return EXIT_SUCCESS; } #endif