Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Vendored third-party header, excluded from clang-tidy lint (installed path matches the CI header filter).
// NOLINTBEGIN
///
// expected - An implementation of std::expected with extensions
// Written in 2017 by Sy Brand (tartanllama@gmail.com, @TartanLlama)
Expand Down Expand Up @@ -2473,3 +2475,4 @@ void swap(expected<T, E> &lhs,
} // namespace tl

#endif
// NOLINTEND
33 changes: 20 additions & 13 deletions src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,23 @@ fetchcontent_makeavailable(open62541pp)
set_directory_properties(PROPERTIES COMPILE_OPTIONS "${_medkit_saved_compile_options}")
unset(_medkit_saved_compile_options)

# Mark open62541pp's interface include directories as SYSTEM so consumers
# (our plugin and tests) do not propagate strict warnings into third-party
# header code. CMake propagates SYSTEM-ness only when the interface property
# is explicitly marked; we do that here on the open62541pp target so downstream
# target_link_libraries picks it up automatically.
if(TARGET open62541pp)
get_target_property(_op62_includes open62541pp INTERFACE_INCLUDE_DIRECTORIES)
if(_op62_includes)
set_target_properties(open62541pp PROPERTIES
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${_op62_includes}")
# Mark the interface include directories of open62541pp AND the bundled
# open62541 target as SYSTEM so consumers (our plugin and tests) do not
# propagate strict warnings into third-party header code. CMake propagates
# SYSTEM-ness only when the interface property is explicitly marked. The
# open62541 target matters for clang-tidy: its headers (e.g.
# client_highlevel.h) contain old-style casts that -Werror=old-style-cast
# turns into hard errors when reached through a plain -I path.
foreach(_op62_target open62541pp open62541)
if(TARGET ${_op62_target})
get_target_property(_op62_includes ${_op62_target} INTERFACE_INCLUDE_DIRECTORIES)
if(_op62_includes)
set_target_properties(${_op62_target} PROPERTIES
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${_op62_includes}")
endif()
unset(_op62_includes)
endif()
unset(_op62_includes)
endif()
endforeach()

# ---- MODULE target: loaded via dlopen at runtime by PluginManager ----
# Symbols from ros2_medkit_gateway are resolved from the host process at runtime.
Expand Down Expand Up @@ -351,10 +355,13 @@ if(BUILD_TESTING)
"${CMAKE_CURRENT_SOURCE_DIR}/test/integration/test_opcua_secured.test.py"
"${CMAKE_BINARY_DIR}/test_alarm_server"
"${CMAKE_CURRENT_SOURCE_DIR}/test/integration/gen_test_certs.sh")
# TIMEOUT must exceed the sum of the script's internal wait deadlines so a
# slow failing run still reaches its own FAIL diagnostics instead of being
# killed by CTest.
set_tests_properties(test_opcua_secured PROPERTIES
LABELS "integration"
SKIP_RETURN_CODE 77
TIMEOUT 300)
TIMEOUT 420)
Comment on lines +358 to +364
endif()

ros2_medkit_relax_vendor_warnings()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class OpcuaClient {

OpcuaClient(const OpcuaClient &) = delete;
OpcuaClient & operator=(const OpcuaClient &) = delete;
OpcuaClient(OpcuaClient &&) = delete;
OpcuaClient & operator=(OpcuaClient &&) = delete;

/// Connect to OPC-UA server
/// @return true if connected successfully
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ class OpcuaPlugin : public ros2_medkit_gateway::GatewayPlugin,
OpcuaPlugin();
~OpcuaPlugin() override;

OpcuaPlugin(const OpcuaPlugin &) = delete;
OpcuaPlugin & operator=(const OpcuaPlugin &) = delete;
OpcuaPlugin(OpcuaPlugin &&) = delete;
OpcuaPlugin & operator=(OpcuaPlugin &&) = delete;

// -- GatewayPlugin interface --
std::string name() const override {
return "opcua";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ class OpcuaPoller {

OpcuaPoller(const OpcuaPoller &) = delete;
OpcuaPoller & operator=(const OpcuaPoller &) = delete;
OpcuaPoller(OpcuaPoller &&) = delete;
OpcuaPoller & operator=(OpcuaPoller &&) = delete;

/// Start the poller thread
void start(const PollerConfig & config);
Expand Down
17 changes: 7 additions & 10 deletions src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ uint32_t OpcuaClient::create_subscription(double publish_interval_ms, DataChange
uint32_t sub_id = sub.subscriptionId();

std::lock_guard<std::mutex> sub_lock(impl_->sub_mutex);
impl_->subscriptions.push_back({std::move(sub), std::move(callback)});
impl_->subscriptions.push_back({sub, std::move(callback)});

return sub_id;
} catch (const opcua::BadStatus &) {
Expand Down Expand Up @@ -1118,16 +1118,13 @@ static void on_event_trampoline_c(UA_Client * /*client*/, UA_UInt32 sub_id, void
return;
}

// Copy the UA_Variant fields into open62541pp wrappers. UA_Variant_copy
// duplicates the underlying buffer, which the opcua::Variant destructor
// will free.
// Copy the UA_Variant fields into open62541pp wrappers. The Variant
// lvalue constructor deep-copies the underlying buffer, which the
// opcua::Variant destructor will free.
std::vector<opcua::Variant> values;
values.reserve(n_fields);
for (size_t i = 0; i < n_fields; ++i) {
UA_Variant copy;
UA_Variant_init(&copy);
UA_Variant_copy(&fields[i], &copy);
values.emplace_back(opcua::Variant{std::move(copy)});
values.emplace_back(opcua::Variant{fields[i]});
}

// Auto-prepended positions (matching make_event_filter):
Expand Down Expand Up @@ -1349,8 +1346,8 @@ OpcuaClient::call_method(const opcua::NodeId & object_id, const opcua::NodeId &
auto arg_results = result.getInputArgumentResults();
std::vector<uint32_t> arg_codes;
arg_codes.reserve(arg_results.size());
for (size_t i = 0; i < arg_results.size(); ++i) {
arg_codes.push_back(arg_results[i].get());
for (const auto & arg_result : arg_results) {
arg_codes.push_back(arg_result.get());
}
if (client_debug_enabled()) {
// RCLCPP_DEBUG_STREAM constructs its std::stringstream unconditionally,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,13 @@ def main():
# Secured A&C: fire an alarm over the server stdin -> CONFIRMED fault.
server.stdin.write('fire Overpressure 750\n')
server.stdin.flush()
# Generous deadline for slow CI runners: the alarm has already fired on
# the server, but report -> fault_manager -> REST propagation can take
# a while under load. A longer deadline only slows the failure path.
faults = wait_json(
f'{base}/faults',
lambda j: any(i.get('fault_code') == ALARM_CODE and i.get('status') == 'CONFIRMED'
for i in j.get('items', [])), deadline=40)
for i in j.get('items', [])), deadline=120)
if not (faults and any(i.get('fault_code') == ALARM_CODE and i.get('status') == 'CONFIRMED'
for i in faults.get('items', []))):
print('FAIL: alarm did not surface as a CONFIRMED fault', file=sys.stderr)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Vendored third-party header, excluded from clang-tidy lint (installed path matches the CI header filter).
// NOLINTBEGIN
// Copyright 2021 Christophe Bedard
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -43,3 +45,4 @@
#endif // DYNMSG_PARSER_DEBUG

#endif // ROS2_MEDKIT_SERIALIZATION__VENDORED__DYNMSG__CONFIG_HPP_
// NOLINTEND
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Vendored third-party header, excluded from clang-tidy lint (installed path matches the CI header filter).
// NOLINTBEGIN
// Copyright 2020 Open Source Robotics Foundation, Inc.
// Copyright 2021 Christophe Bedard
//
Expand Down Expand Up @@ -57,3 +59,4 @@ YAML::Node message_to_yaml(const RosMessage_Cpp & message);
} // namespace dynmsg

#endif // ROS2_MEDKIT_SERIALIZATION__VENDORED__DYNMSG__MESSAGE_READING_HPP_
// NOLINTEND
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Vendored third-party header, excluded from clang-tidy lint (installed path matches the CI header filter).
// NOLINTBEGIN
// Copyright 2020 Open Source Robotics Foundation, Inc.
// Copyright 2021 Christophe Bedard
//
Expand Down Expand Up @@ -86,3 +88,4 @@ void yaml_and_typeinfo_to_rosmsg(
} // namespace dynmsg

#endif // ROS2_MEDKIT_SERIALIZATION__VENDORED__DYNMSG__MSG_PARSER_HPP_
// NOLINTEND
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Vendored third-party header, excluded from clang-tidy lint (installed path matches the CI header filter).
// NOLINTBEGIN
// Copyright 2020 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -27,3 +29,4 @@ std::string u16string_to_string(const std::u16string & input);
} // extern "C"

#endif // ROS2_MEDKIT_SERIALIZATION__VENDORED__DYNMSG__STRING_UTILS_HPP_
// NOLINTEND
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Vendored third-party header, excluded from clang-tidy lint (installed path matches the CI header filter).
// NOLINTBEGIN
// Copyright 2020 Open Source Robotics Foundation, Inc.
// Copyright 2021 Christophe Bedard
//
Expand Down Expand Up @@ -27,3 +29,4 @@ typedef rcutils_ret_t dynmsg_ret_t;
#define DYNMSG_RET_ERROR RCUTILS_RET_ERROR

#endif // ROS2_MEDKIT_SERIALIZATION__VENDORED__DYNMSG__TYPES_H_
// NOLINTEND
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Vendored third-party header, excluded from clang-tidy lint (installed path matches the CI header filter).
// NOLINTBEGIN
// Copyright 2020 Open Source Robotics Foundation, Inc.
// Copyright 2021 Christophe Bedard
//
Expand Down Expand Up @@ -161,3 +163,4 @@ void ros_message_destroy_with_allocator(RosMessage_Cpp * ros_msg, rcutils_alloca
} // namespace dynmsg

#endif // ROS2_MEDKIT_SERIALIZATION__VENDORED__DYNMSG__TYPESUPPORT_HPP_
// NOLINTEND
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Vendored third-party header, excluded from clang-tidy lint (installed path matches the CI header filter).
// NOLINTBEGIN
// Copyright 2021 Christophe Bedard
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -34,3 +36,4 @@ size_t get_vector_size(const uint8_t * vector, size_t element_size);
} // namespace dynmsg

#endif // ROS2_MEDKIT_SERIALIZATION__VENDORED__DYNMSG__VECTOR_UTILS_HPP_
// NOLINTEND
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Vendored third-party header, excluded from clang-tidy lint (installed path matches the CI header filter).
// NOLINTBEGIN
// Copyright 2021 Christophe Bedard
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -40,3 +42,4 @@ std::string yaml_to_string(
} // namespace dynmsg

#endif // ROS2_MEDKIT_SERIALIZATION__VENDORED__DYNMSG__YAML_UTILS_HPP_
// NOLINTEND
Loading