mirror of
https://github.com/FreeOpcUa/freeopcua
synced 2025-10-26 19:56:54 +08:00
Devel (#345)
Several requested changes of pull requests revised, compatibility
* make it compile with gcc < 4.9 again
* compile with newer boost versions (vmatare)
* cmake update for python (vmatare)
* compile flags (maartendemunck)
* strict ordering of sequence numbers (martinhaefner)
* passwort encryption strategy (martinhaefner)
* close sockets (DennisLemmers)
* GUID format (DennisLemmers)
* use ${CMAKE_INSTALL_LIBDIR} for install (morxa)
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,6 +16,7 @@ dist
|
||||
*.egg
|
||||
*.egg-info
|
||||
eggs
|
||||
.DS_Store
|
||||
.installed.cfg
|
||||
lib
|
||||
lib64
|
||||
|
||||
@@ -68,14 +68,14 @@ if(MSVC)
|
||||
add_definitions(/D_SCL_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_WARNINGS /D_WIN32 /D_WINDOWS /FS /D_WIN32_WINNT=0x0600)
|
||||
add_compile_options(/Zi /Od /EHsc /W4)
|
||||
else(MSVC)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG " -Wall -ggdb -o0 ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG " -Wall -ggdb -O0 ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
|
||||
SET(STATIC_LIBRARY_CXX_FLAGS)
|
||||
SET(EXECUTABLE_CXX_FLAGS)
|
||||
SET(DYNAMIC_LIBRARY_CXX_FLAGS)
|
||||
SET(D -D)
|
||||
set(CMAKE_CXX_FLAGS " -std=c++11 -Wall -fPIC ${CMAKE_CXX_FLAGS} ")
|
||||
SET (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS_INIT} $ENV{LDFLAGS})
|
||||
SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_INIT} $ENV{LDFLAGS}")
|
||||
#set(CMAKE_SHARED_LINKER_FLAGS "--no-undefined" )
|
||||
endif()
|
||||
|
||||
@@ -98,10 +98,19 @@ else(WIN32)
|
||||
SET(DYNAMIC_ADDON_PATH "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libtest_dynamic_addon.so")
|
||||
SET(TEST_CORE_CONFIG_PATH "${PROJECT_SOURCE_DIR}/tests/core/configs/")
|
||||
SET(OS_SUFFIX _lin)
|
||||
# gcc less then version 4.9 uses a broken std::regex implementation
|
||||
# use libxml2 to parse URL's instead
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.0)
|
||||
find_package(LibXml2 REQUIRED)
|
||||
message(STATUS "LibXML2 INCLUDE DIR IS: " ${LIBXML2_INCLUDE_DIR})
|
||||
include_directories( ${LIBXML2_INCLUDE_DIR} )
|
||||
|
||||
SET(NO_REGEX_SUFFIX _noregex)
|
||||
endif()
|
||||
|
||||
|
||||
#FIXME: remove that variable and link directly when necessary!!!!
|
||||
SET(ADDITIONAL_LINK_LIBRARIES pthread dl)
|
||||
SET(ADDITIONAL_LINK_LIBRARIES pthread dl ${LIBXML2_LIBRARIES})
|
||||
|
||||
endif(WIN32)
|
||||
|
||||
@@ -122,7 +131,7 @@ if (SSL_SUPPORT_MBEDTLS)
|
||||
message(STATUS " mbedtls library LIB_DIR: " ${SSL_SUPPORT_MBEDTLS_LIB_DIR})
|
||||
link_directories( ${SSL_SUPPORT_MBEDTLS_LIB_DIR} )
|
||||
ENDIF ()
|
||||
SET(SSL_SUPPORT_LINK_LIBRARIES mbedx509 mbedtls mbedcrypto)
|
||||
SET(SSL_SUPPORT_LINK_LIBRARIES mbedcrypto mbedx509 mbedtls)
|
||||
message(STATUS " mbedtls LIBRARIES: " ${SSL_SUPPORT_LINK_LIBRARIES})
|
||||
endif (SSL_SUPPORT_MBEDTLS)
|
||||
|
||||
@@ -248,7 +257,7 @@ SET(opcuacore_SOURCES
|
||||
src/core/common/common_errors.cpp
|
||||
src/core/common/exception.cpp
|
||||
src/core/common/thread.cpp
|
||||
src/core/common/uri_facade${OS_SUFFIX}.cpp
|
||||
src/core/common/uri_facade${OS_SUFFIX}${NO_REGEX_SUFFIX}.cpp
|
||||
src/core/common/value.cpp
|
||||
src/core/event.cpp
|
||||
src/core/model_impl.h
|
||||
@@ -334,7 +343,8 @@ if (BUILD_CLIENT)
|
||||
opcuacore
|
||||
${ADDITIONAL_LINK_LIBRARIES}
|
||||
${Boost_PROGRAMOPTIONS_LIBRARY}
|
||||
)
|
||||
${SSL_SUPPORT_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
target_include_directories(opcuaclient PUBLIC $<INSTALL_INTERFACE:include>)
|
||||
install(TARGETS opcuaclient EXPORT FreeOpcUa
|
||||
@@ -509,6 +519,7 @@ if(BUILD_SERVER)
|
||||
opcuacore
|
||||
opcuaserver
|
||||
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||
${SSL_SUPPORT_LINK_LIBRARIES}
|
||||
)
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
target_compile_options(opcuaserverapp PUBLIC ${EXECUTABLE_CXX_FLAGS})
|
||||
@@ -549,10 +560,11 @@ if(BUILD_SERVER)
|
||||
)
|
||||
|
||||
target_link_libraries(example_server
|
||||
${ADDITIONAL_LINK_LIBRARIES}
|
||||
opcuaprotocol
|
||||
opcuacore
|
||||
opcuaserver
|
||||
${ADDITIONAL_LINK_LIBRARIES}
|
||||
opcuaprotocol
|
||||
opcuacore
|
||||
opcuaserver
|
||||
${SSL_SUPPORT_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
@@ -572,7 +584,7 @@ if (BUILD_PYTHON)
|
||||
add_subdirectory(python)
|
||||
endif (BUILD_PYTHON)
|
||||
|
||||
install(EXPORT FreeOpcUa DESTINATION lib/cmake/FreeOpcUa FILE FreeOpcUaConfig.cmake)
|
||||
install(EXPORT FreeOpcUa DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/FreeOpcUa FILE FreeOpcUaConfig.cmake)
|
||||
|
||||
SET(CPACK_GENERATOR "DEB")
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "FreeOpcUa")
|
||||
|
||||
@@ -1,26 +1,43 @@
|
||||
cmake_minimum_required(VERSION 2.8.8)
|
||||
|
||||
FIND_PACKAGE(PythonLibs)
|
||||
IF(PYTHONLIBS_FOUND)
|
||||
MESSAGE(STATUS "Compiling module for python ${PYTHONLIBS_VERSION_STRING}")
|
||||
string(REPLACE "." ";" PYTHONLIBS_VERSION_LIST ${PYTHONLIBS_VERSION_STRING})
|
||||
LIST(GET PYTHONLIBS_VERSION_LIST 0 PYTHON_VERSION_MAJOR)
|
||||
IF(PYTHON_VERSION_MAJOR EQUAL 2)
|
||||
FIND_PACKAGE(Boost COMPONENTS python)
|
||||
IF(NOT (Boost_PYTHON_FOUND STREQUAL "ON"))
|
||||
MESSAGE(STATUS "Boost python lib not found: Not building python module")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
IF(PKG_CONFIG_VERSION_STRING VERSION_LESS 0.29.0)
|
||||
MESSAGE(STATUS "Old Python Check: PKG_CONFIG_VERSION_STRING: ${PKG_CONFIG_VERSION_STRING}")
|
||||
FIND_PACKAGE(PythonLibs)
|
||||
IF(PYTHONLIBS_FOUND)
|
||||
MESSAGE(STATUS "Compiling module for python ${PYTHONLIBS_VERSION_STRING}")
|
||||
string(REPLACE "." ";" PYTHONLIBS_VERSION_LIST ${PYTHONLIBS_VERSION_STRING})
|
||||
# LIST(GET PYTHONLIBS_VERSION_LIST 0 PYTHON_VERSION_MAJOR)
|
||||
IF(PYTHON_VERSION_MAJOR EQUAL 2)
|
||||
FIND_PACKAGE(Boost COMPONENTS python)
|
||||
IF(NOT (Boost_PYTHON_FOUND STREQUAL "ON"))
|
||||
MESSAGE(STATUS "Boost python lib not found: Not building python module")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
ELSE()
|
||||
FIND_PACKAGE(Boost COMPONENTS python${PYTHON_VERSION_MAJOR})
|
||||
IF(NOT (Boost_PYTHON${PYTHON_VERSION_MAJOR}_FOUND STREQUAL "ON"))
|
||||
MESSAGE(STATUS "Boost python${PYTHON_VERSION_MAJOR} lib not found: Not building python${PYTHON_VERSION_MAJOR} module")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ELSE()
|
||||
FIND_PACKAGE(Boost COMPONENTS python${PYTHON_VERSION_MAJOR})
|
||||
IF(NOT (Boost_PYTHON${PYTHON_VERSION_MAJOR}_FOUND STREQUAL "ON"))
|
||||
MESSAGE(STATUS "Boost python${PYTHON_VERSION_MAJOR} lib not found: Not building python${PYTHON_VERSION_MAJOR} module")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
MESSAGE(STATUS "Python lib not found: Not building python module")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Python lib not found: Not building python module")
|
||||
RETURN()
|
||||
MESSAGE(STATUS "New Python Check: PKG_CONFIG_VERSION_STRING: ${PKG_CONFIG_VERSION_STRING}")
|
||||
FIND_PACKAGE(Python COMPONENTS Interpreter Development)
|
||||
IF(Python_FOUND)
|
||||
MESSAGE(STATUS "Compiling module for python ${Python_VERSION}")
|
||||
FIND_PACKAGE(Boost COMPONENTS python${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
|
||||
IF(NOT Boost_PYTHON_FOUND)
|
||||
MESSAGE(STATUS "Boost python${Python_VERSION_MAJOR}${Python_VERSION_MINOR} lib not found: Not building python module")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Python lib not found: Not building python module")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
INCLUDE_DIRECTORIES( ${BOOST_INCLUDE_DIR} )
|
||||
|
||||
@@ -844,6 +844,8 @@ public:
|
||||
const SymmetricAlgorithmHeader algorithmHeader = CreateAlgorithmHeader();
|
||||
hdr.AddSize(RawSize(algorithmHeader));
|
||||
|
||||
std::unique_lock<std::mutex> send_lock(send_mutex);
|
||||
|
||||
const SequenceHeader sequence = CreateSequenceHeader();
|
||||
hdr.AddSize(RawSize(sequence));
|
||||
|
||||
@@ -911,11 +913,12 @@ private:
|
||||
const SymmetricAlgorithmHeader algorithmHeader = CreateAlgorithmHeader();
|
||||
hdr.AddSize(RawSize(algorithmHeader));
|
||||
|
||||
std::unique_lock<std::mutex> send_lock(send_mutex);
|
||||
|
||||
const SequenceHeader sequence = CreateSequenceHeader();
|
||||
hdr.AddSize(RawSize(sequence));
|
||||
hdr.AddSize(RawSize(request));
|
||||
|
||||
std::unique_lock<std::mutex> send_lock(send_mutex);
|
||||
Stream << hdr << algorithmHeader << sequence << request << flush;
|
||||
}
|
||||
|
||||
@@ -980,6 +983,7 @@ private:
|
||||
if (callbackIt == Callbacks.end())
|
||||
{
|
||||
LOG_WARN(Logger, "binary_client | no callback found for message id: {}, handle: {}", id, header.RequestHandle);
|
||||
messageBuffer.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1132,6 +1136,8 @@ void BinaryClient::Send<OpenSecureChannelRequest>(OpenSecureChannelRequest reque
|
||||
hdr.AddSize(RawSize(algorithmHeader));
|
||||
hdr.AddSize(RawSize(request));
|
||||
|
||||
std::unique_lock<std::mutex> send_lock(send_mutex);
|
||||
|
||||
const SequenceHeader sequence = CreateSequenceHeader();
|
||||
hdr.AddSize(RawSize(sequence));
|
||||
Stream << hdr << algorithmHeader << sequence << request << flush;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <opc/ua/protocol/string_utils.h>
|
||||
|
||||
#ifdef SSL_SUPPORT_MBEDTLS
|
||||
#define MBEDTLS_X509_CRT_PARSE_C
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/x509_crt.h>
|
||||
@@ -102,7 +103,7 @@ void KeepAliveThread::Stop()
|
||||
Thread.join();
|
||||
}
|
||||
|
||||
catch (std::system_error ex)
|
||||
catch (std::system_error & ex)
|
||||
{
|
||||
LOG_ERROR(Logger, "keep_alive_thread | exception thrown at attempt to join: {}", ex.what());
|
||||
|
||||
@@ -281,7 +282,12 @@ void UaClient::Connect(const EndpointDescription & endpoint)
|
||||
{
|
||||
sessionParameters.UserIdentityToken.setPolicyId(token.PolicyId);
|
||||
sessionParameters.UserIdentityToken.setUser(user, password);
|
||||
EncryptPassword(sessionParameters.UserIdentityToken, createSessionResponse);
|
||||
|
||||
if (token.SecurityPolicyUri != "http://opcfoundation.org/UA/SecurityPolicy#None")
|
||||
{
|
||||
EncryptPassword(sessionParameters.UserIdentityToken, createSessionResponse);
|
||||
}
|
||||
|
||||
user_identify_token_found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ void Uri::Initialize(const std::string &uriString)
|
||||
THROW_ERROR1(CannotParseUri, uriString);
|
||||
}
|
||||
|
||||
|
||||
enum {Scheme = 1, User = 3, Password = 5, Host = 6, Port = 8, Path = 9, QueryAndFragment = 10};
|
||||
|
||||
SchemeStr = uri_match[Scheme].str();
|
||||
|
||||
59
src/core/common/uri_facade_lin_noregex.cpp
Normal file
59
src/core/common/uri_facade_lin_noregex.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/// @author Alexander Rykovanov 2013
|
||||
/// @email rykovanov.as@gmail.com
|
||||
/// @brief Uri.
|
||||
/// @license GNU LGPL
|
||||
///
|
||||
/// Distributed under the GNU LGPL License
|
||||
/// (See accompanying file LICENSE or copy at
|
||||
/// http://www.gnu.org/licenses/lgpl.html)
|
||||
///
|
||||
|
||||
#include <opc/common/uri_facade.h>
|
||||
|
||||
#include <opc/common/exception.h>
|
||||
|
||||
#include <libxml/uri.h>
|
||||
|
||||
namespace Common
|
||||
{
|
||||
|
||||
void Uri::Initialize(const std::string& uriString)
|
||||
{
|
||||
xmlURIPtr uri = xmlParseURI(uriString.c_str());
|
||||
if (!uri)
|
||||
{
|
||||
THROW_ERROR1(CannotParseUri, uriString);
|
||||
}
|
||||
|
||||
if (uri->scheme)
|
||||
{
|
||||
SchemeStr = uri->scheme;
|
||||
}
|
||||
|
||||
if (uri->user)
|
||||
{
|
||||
UserStr = uri->user;
|
||||
int ix = UserStr.find(':');
|
||||
|
||||
if (ix > 0)
|
||||
{
|
||||
PasswordStr = UserStr.substr(ix + 1);
|
||||
UserStr = UserStr.substr(0, ix);
|
||||
}
|
||||
}
|
||||
|
||||
if (uri->server)
|
||||
{
|
||||
HostStr = uri->server;
|
||||
}
|
||||
|
||||
PortNum = uri->port;
|
||||
xmlFreeURI(uri);
|
||||
|
||||
if (SchemeStr.empty() || HostStr.empty())
|
||||
{
|
||||
THROW_ERROR1(CannotParseUri, uriString);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
@@ -50,12 +50,7 @@ OpcUa::SocketChannel::~SocketChannel()
|
||||
|
||||
void OpcUa::SocketChannel::Stop()
|
||||
{
|
||||
int error = shutdown(Socket, 2);
|
||||
|
||||
if (error < 0)
|
||||
{
|
||||
std::cerr << "Failed to close socket connection. " << strerror(errno) << std::endl;
|
||||
}
|
||||
close(Socket);
|
||||
}
|
||||
|
||||
std::size_t OpcUa::SocketChannel::Receive(char * data, std::size_t size)
|
||||
|
||||
@@ -184,8 +184,8 @@ std::string OpcUa::ToString(const OpcUa::LocalizedText & t)
|
||||
|
||||
std::string OpcUa::ToString(const OpcUa::Guid & guid)
|
||||
{
|
||||
char buf[36] = {0};
|
||||
sprintf(buf, "%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
|
||||
char buf[37] = {0};
|
||||
sprintf(buf, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -429,27 +429,27 @@ std::ostream & OpcUa::ToStream(std::ostream & os, const OpcUa::Event & value, in
|
||||
{
|
||||
indent(os, subIndentLevel);
|
||||
os << "LocalTime: " << value.LocalTime;
|
||||
|
||||
|
||||
indent(os, subIndentLevel);
|
||||
os << "ReceiveTime: " << value.ReceiveTime;
|
||||
|
||||
|
||||
indent(os, subIndentLevel);
|
||||
os << "EventId: " << value.EventId;
|
||||
|
||||
|
||||
indent(os, subIndentLevel);
|
||||
os << "SourceName: " << value.SourceName;
|
||||
}
|
||||
|
||||
|
||||
indent(os, subIndentLevel);
|
||||
os << "SourceNode: ";
|
||||
ToStream(os, value.SourceNode);
|
||||
|
||||
indent(os, subIndentLevel);
|
||||
os << "Severity: " << value.Severity;
|
||||
|
||||
|
||||
indent(os, subIndentLevel);
|
||||
os << "Message: " << value.Message;
|
||||
|
||||
|
||||
indent(os, indentLevel, true);
|
||||
os << ")";
|
||||
return os;
|
||||
@@ -719,7 +719,7 @@ std::ostream & OpcUa::ToStream(std::ostream & os, const OpcUa::SimpleAttributeOp
|
||||
|
||||
OpcUa::Guid OpcUa::ToGuid(const std::string & str)
|
||||
{
|
||||
if (str.size() != 35)
|
||||
if (str.size() != 36)
|
||||
{
|
||||
return OpcUa::Guid();
|
||||
}
|
||||
@@ -737,7 +737,7 @@ OpcUa::Guid OpcUa::ToGuid(const std::string & str)
|
||||
unsigned data9 = 0;
|
||||
unsigned data10 = 0;
|
||||
unsigned data11 = 0;
|
||||
const int parts = sscanf(str.c_str(), "%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
const int parts = sscanf(str.c_str(), "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
&data1, &data2, &data3, &data4, &data5, &data6, &data7, &data8, &data9, &data10, &data11);
|
||||
|
||||
guid.Data1 = static_cast<uint32_t>(data1);
|
||||
|
||||
@@ -14,7 +14,7 @@ InternalSubscription::InternalSubscription(SubscriptionServiceInternal & service
|
||||
, CurrentSession(SessionAuthenticationToken)
|
||||
, Callback(callback)
|
||||
, io(service.GetIOService())
|
||||
, Timer(io, boost::posix_time::milliseconds(data.RevisedPublishingInterval))
|
||||
, Timer(io, boost::posix_time::microseconds(static_cast<unsigned long>(1000 * data.RevisedPublishingInterval)))
|
||||
, LifeTimeCount(data.RevisedLifetimeCount)
|
||||
, Logger(logger)
|
||||
{
|
||||
@@ -105,7 +105,7 @@ void InternalSubscription::PublishResults(const boost::system::error_code & erro
|
||||
}
|
||||
|
||||
TimerStopped = false;
|
||||
Timer.expires_at(Timer.expires_at() + boost::posix_time::milliseconds(Data.RevisedPublishingInterval));
|
||||
Timer.expires_at(Timer.expires_at() + boost::posix_time::microseconds(static_cast<unsigned long>(1000 * Data.RevisedPublishingInterval)));
|
||||
std::shared_ptr<InternalSubscription> self = shared_from_this();
|
||||
Timer.async_wait([self](const boost::system::error_code & error) { self->PublishResults(error); });
|
||||
}
|
||||
|
||||
@@ -106,7 +106,11 @@ public:
|
||||
*/
|
||||
typedef std::promise<void> Promise;
|
||||
Promise promise;
|
||||
#if BOOST_VERSION < 107000
|
||||
Socket.get_io_service().post(bind(&Promise::set_value, &promise));
|
||||
#else
|
||||
post(Socket.get_executor(), bind(&Promise::set_value, &promise));
|
||||
#endif
|
||||
promise.get_future().wait();
|
||||
}
|
||||
|
||||
@@ -372,7 +376,11 @@ void OpcTcpServer::Shutdown()
|
||||
*/
|
||||
typedef std::promise<void> Promise;
|
||||
Promise promise;
|
||||
#if BOOST_VERSION < 107000
|
||||
acceptor.get_io_service().post(bind(&Promise::set_value, &promise));
|
||||
#else
|
||||
post(acceptor.get_executor(), bind(&Promise::set_value, &promise));
|
||||
#endif
|
||||
promise.get_future().wait();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user